forked from Open-MBEE/OpenSysML
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(runtime): execute binding connectors #310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
4202187
feat(runtime): execute binding connectors
devin-ai-integration[bot] e0db6ba
fix(runtime): refine binding endpoint resolution
devin-ai-integration[bot] 7581b18
fix(runtime): avoid stale binding outcomes
devin-ai-integration[bot] bdf087c
fix(runtime): distinguish binding cycles from unset ends
devin-ai-integration[bot] 6e56bc1
chore(runtime): merge origin/main into binding runtime
devin-ai-integration[bot] 4753afa
chore(runtime): merge origin/main after binding fixes
devin-ai-integration[bot] 302c9c6
fix(runtime): resolve nested binding paths
devin-ai-integration[bot] 2def84c
test(runtime): tidy nested binding container assertion
devin-ai-integration[bot] c108edc
fix(runtime): handle named binding declarations
devin-ai-integration[bot] 1add277
fix(runtime): correct binding endpoint values
devin-ai-integration[bot] 844f8e2
fix(runtime): keep exact set equality bucketed
devin-ai-integration[bot] 86c479d
fix(runtime): refresh binding-derived values
devin-ai-integration[bot] 875d203
fix(runtime): format binding collections and reject ambiguous contrib…
devin-ai-integration[bot] f3beb6b
fix(runtime): preserve set order in binding diagnostics
devin-ai-integration[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package lower | ||
|
|
||
| import ( | ||
| "github.com/Open-MBEE/OpenSysML/internal/core/ast" | ||
| "github.com/Open-MBEE/OpenSysML/internal/core/symbols" | ||
| ) | ||
|
|
||
| // Binding is a lowered binding connector with its two endpoint expressions and | ||
| // the scope in which those expressions were declared. | ||
| type Binding struct { | ||
| Ends [2]BindingEnd | ||
| Scope *symbols.Scope | ||
| Decl *ast.Usage | ||
| } | ||
|
|
||
| // BindingEnd is one binding endpoint. Path is the runtime lvalue path; Expr | ||
| // retains the lossless expression for diagnostics and calc evaluation. | ||
| type BindingEnd struct { | ||
| Path string | ||
| Expr ast.Node | ||
| } | ||
|
|
||
| // ToBindings lowers binding connectors directly declared by a type or usage. | ||
| // Namespace-owned bindings are intentionally left to callers to exclude. | ||
| func ToBindings(decl ast.Node, scope *symbols.Scope) []Binding { | ||
| var members []ast.Node | ||
| switch n := decl.(type) { | ||
| case *ast.Usage: | ||
| members = n.Members | ||
| case *ast.Definition: | ||
| members = n.Members | ||
| default: | ||
| return nil | ||
| } | ||
|
|
||
| var out []Binding | ||
| for _, member := range members { | ||
| u, ok := unwrapMembership(member).(*ast.Usage) | ||
| if !ok || u.Kind != ast.UsageBinding { | ||
| continue | ||
| } | ||
| binding, ok := lowerBinding(u, scope) | ||
| if ok { | ||
| out = append(out, binding) | ||
| } | ||
| } | ||
| return out | ||
| } | ||
|
|
||
| func lowerBinding(u *ast.Usage, scope *symbols.Scope) (Binding, bool) { | ||
| if u == nil { | ||
| return Binding{}, false | ||
| } | ||
|
|
||
| var first ast.Node | ||
| for _, rel := range u.Relationships { | ||
| if rel != nil && rel.Kind == ast.RelReferences { | ||
| first = rel.Target | ||
| break | ||
| } | ||
| } | ||
| if first == nil { | ||
| return Binding{}, false | ||
| } | ||
|
devin-ai-integration[bot] marked this conversation as resolved.
|
||
| if u.Value == nil { | ||
| return Binding{}, false | ||
| } | ||
| ends := [2]BindingEnd{ | ||
| {Path: FeaturePath(first), Expr: first}, | ||
| {Path: FeaturePath(u.Value), Expr: u.Value}, | ||
| } | ||
| return Binding{Ends: ends, Scope: scope, Decl: u}, true | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| package lower | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/Open-MBEE/OpenSysML/internal/core/ast" | ||
| "github.com/Open-MBEE/OpenSysML/internal/core/parser" | ||
| "github.com/Open-MBEE/OpenSysML/internal/core/source" | ||
| "github.com/Open-MBEE/OpenSysML/internal/core/symbols" | ||
| ) | ||
|
|
||
| func TestToBindingsNormalizesBindingSpellings(t *testing.T) { | ||
| p := parser.New(source.New("binding.sysml", []byte(`package P { | ||
| part def Owner { | ||
| binding bind x = y; | ||
| bind x = y; | ||
| binding named bind x = y; | ||
| binding namedOf of x = y; | ||
| binding namedOnly = x; | ||
| bind incomplete; | ||
| binding incompleteOf of x; | ||
| binding [1] config.host = serverAddress; | ||
| } | ||
| }`))) | ||
| file := p.ParseFile() | ||
| idx := symbols.NewIndex() | ||
| idx.AddDocument("binding.sysml", file) | ||
| scope := idx.DocumentRoot("binding.sysml") | ||
| var bindings []Binding | ||
| for _, member := range file.Members { | ||
| membership, ok := member.(*ast.Membership) | ||
| if !ok { | ||
| continue | ||
| } | ||
| pkg, ok := membership.Member.(*ast.Package) | ||
| if !ok { | ||
| continue | ||
| } | ||
| for _, nested := range pkg.Members { | ||
| ownerMembership, ok := nested.(*ast.Membership) | ||
| if !ok { | ||
| continue | ||
| } | ||
| owner, ok := ownerMembership.Member.(*ast.Definition) | ||
| if ok { | ||
| bindings = append(bindings, ToBindings(owner, scope)...) | ||
| } | ||
| } | ||
| } | ||
| if len(bindings) != 5 { | ||
| t.Fatalf("lowered %d bindings, want 5", len(bindings)) | ||
| } | ||
| wants := map[[2]string]int{ | ||
| {"x", "y"}: 4, | ||
| {"config.host", "serverAddress"}: 1, | ||
| } | ||
| for _, binding := range bindings { | ||
| paths := [2]string{binding.Ends[0].Path, binding.Ends[1].Path} | ||
| if wants[paths] == 0 { | ||
| t.Errorf("binding paths = %q, want one of [x, y] or [config.host, serverAddress]", paths) | ||
| continue | ||
| } | ||
| wants[paths]-- | ||
| } | ||
| for paths, count := range wants { | ||
| if count != 0 { | ||
| t.Errorf("binding paths %q occurred %d extra times", paths, count) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestToBindingsKeepsMultipleContributors(t *testing.T) { | ||
| p := parser.New(source.New("binding-multiple.sysml", []byte(`package P { | ||
| part def Sys { | ||
| part edges : Edge[*]; | ||
| part leftEdge : Edge; | ||
| part rightEdge : Edge; | ||
| binding [1] bind [0..1] edges = [0..1] leftEdge; | ||
| binding [1] bind [0..1] edges = [0..1] rightEdge; | ||
| } | ||
| }`))) | ||
| file := p.ParseFile() | ||
| idx := symbols.NewIndex() | ||
| idx.AddDocument("binding-multiple.sysml", file) | ||
| scope := idx.DocumentRoot("binding-multiple.sysml") | ||
| var bindings []Binding | ||
| for _, member := range file.Members { | ||
| membership, ok := member.(*ast.Membership) | ||
| if !ok { | ||
| continue | ||
| } | ||
| pkg, ok := membership.Member.(*ast.Package) | ||
| if !ok { | ||
| continue | ||
| } | ||
| for _, nested := range pkg.Members { | ||
| ownerMembership, ok := nested.(*ast.Membership) | ||
| if !ok { | ||
| continue | ||
| } | ||
| owner, ok := ownerMembership.Member.(*ast.Definition) | ||
| if ok { | ||
| bindings = append(bindings, ToBindings(owner, scope)...) | ||
| } | ||
| } | ||
| } | ||
| if len(bindings) != 2 { | ||
| t.Fatalf("lowered %d bindings, want 2", len(bindings)) | ||
| } | ||
| for _, binding := range bindings { | ||
| if got := [2]string{binding.Ends[0].Path, binding.Ends[1].Path}; got != [2]string{"edges", "leftEdge"} && | ||
| got != [2]string{"edges", "rightEdge"} { | ||
| t.Errorf("binding paths = %q, want edges/leftEdge or edges/rightEdge", got) | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
internal/core/parser/testdata/parse/binding_anonymous_simple.golden
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| (RootNamespace | ||
| (Membership visibility="default" | ||
| (Package name="P" library=false standard=false | ||
| (Membership visibility="default" | ||
| (Definition kind="part" abstract=false variation=false name="Sys" | ||
| (Membership visibility="default" | ||
| (Usage kind="binding" name="" ref=false direction="none" composite=false derived=false ordered=false nonunique=false | ||
| (Relationship kind="references" target=b | ||
| (*ast.QualifiedName)) | ||
| (FeatureReference name="a"))) | ||
| (Membership visibility="default" | ||
| (Usage kind="binding" name="" ref=false direction="none" composite=false derived=false ordered=false nonunique=false keyword="bind" | ||
| (Relationship kind="references" target=b | ||
| (*ast.QualifiedName)) | ||
| (FeatureReference name="a")))))))) |
6 changes: 6 additions & 0 deletions
6
internal/core/parser/testdata/parse/binding_anonymous_simple.sysml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package P { | ||
| part def Sys { | ||
| binding bind b = a; | ||
| bind b = a; | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.