diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 243ce14f4..5467d044c 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -262,17 +262,19 @@ func (c *compiler) compileField(obj *d2graph.Object, f *d2ir.Field) { obj.Map = fr.Context.Key.Value.Map } } - scopeObjIDA := d2ir.BoardIDA(fr.Context.ScopeMap) - scopeObj := obj.Graph.Root.EnsureChildIDVal(scopeObjIDA) - obj.References = append(obj.References, d2graph.Reference{ + r := d2graph.Reference{ Key: fr.KeyPath, KeyPathIndex: fr.KeyPathIndex(), MapKey: fr.Context.Key, MapKeyEdgeIndex: fr.Context.EdgeIndex(), Scope: fr.Context.Scope, - ScopeObj: scopeObj, - }) + } + if fr.Context.ScopeMap != nil { + scopeObjIDA := d2ir.BoardIDA(fr.Context.ScopeMap) + r.ScopeObj = obj.Graph.Root.EnsureChildIDVal(scopeObjIDA) + } + obj.References = append(obj.References, r) } } @@ -604,15 +606,17 @@ func (c *compiler) compileEdge(obj *d2graph.Object, e *d2ir.Edge) { edge.Label.MapKey = e.LastPrimaryKey() for _, er := range e.References { - scopeObjIDA := d2ir.BoardIDA(er.Context.ScopeMap) - scopeObj := edge.Src.Graph.Root.EnsureChildIDVal(scopeObjIDA) - edge.References = append(edge.References, d2graph.EdgeReference{ + r := d2graph.EdgeReference{ Edge: er.Context.Edge, MapKey: er.Context.Key, MapKeyEdgeIndex: er.Context.EdgeIndex(), Scope: er.Context.Scope, - ScopeObj: scopeObj, - }) + } + if er.Context.ScopeMap != nil { + scopeObjIDA := d2ir.BoardIDA(er.Context.ScopeMap) + r.ScopeObj = edge.Src.Graph.Root.EnsureChildIDVal(scopeObjIDA) + } + edge.References = append(edge.References, r) } } diff --git a/d2ir/import.go b/d2ir/import.go index e269a0cfd..52fce2e7a 100644 --- a/d2ir/import.go +++ b/d2ir/import.go @@ -48,6 +48,7 @@ func (c *compiler) _import(imp *d2ast.Import) (Node, bool) { if !ok { return nil, false } + nilScopeMap(ir) if len(imp.IDA()) > 0 { f := ir.GetField(imp.IDA()...) if f == nil { @@ -126,3 +127,29 @@ func (c *compiler) __import(imp *d2ast.Import) (*Map, bool) { return ir, true } + +func nilScopeMap(n Node) { + switch n := n.(type) { + case *Map: + for _, f := range n.Fields { + nilScopeMap(f) + } + for _, e := range n.Edges { + nilScopeMap(e) + } + case *Edge: + for _, r := range n.References { + r.Context.ScopeMap = nil + } + if n.Map() != nil { + nilScopeMap(n.Map()) + } + case *Field: + for _, r := range n.References { + r.Context.ScopeMap = nil + } + if n.Map() != nil { + nilScopeMap(n.Map()) + } + } +} diff --git a/d2ir/import_test.go b/d2ir/import_test.go index d6eff4809..dceaa64a5 100644 --- a/d2ir/import_test.go +++ b/d2ir/import_test.go @@ -83,6 +83,19 @@ label: meow`, assertQuery(t, m, 0, 0, "wowa", "x") }, }, + { + name: "nested/spread", + run: func(t testing.TB) { + m, err := compileFS(t, "index.d2", map[string]string{ + "index.d2": "...@x.y", + "x.d2": "y: { jon; jan }", + }) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, nil, "jan") + assertQuery(t, m, 0, 0, nil, "jon") + }, + }, } runa(t, tca) diff --git a/e2etests-cli/main_test.go b/e2etests-cli/main_test.go index 1ce1d5ff4..aff8d6f63 100644 --- a/e2etests-cli/main_test.go +++ b/e2etests-cli/main_test.go @@ -378,6 +378,17 @@ steps: { assert.Testdata(t, ".svg", svg) }, }, + { + name: "import_spread_nested", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "hello-world.d2", `...@x.y`) + writeFile(t, dir, "x.d2", `y: { jon; jan }`) + err := runTestMain(t, ctx, dir, env, filepath.Join(dir, "hello-world.d2")) + assert.Success(t, err) + svg := readFile(t, dir, "hello-world.svg") + assert.Testdata(t, ".svg", svg) + }, + }, } ctx := context.Background() diff --git a/e2etests-cli/testdata/TestCLI_E2E/import_spread_nested.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/import_spread_nested.exp.svg new file mode 100644 index 000000000..2c3afa6dc --- /dev/null +++ b/e2etests-cli/testdata/TestCLI_E2E/import_spread_nested.exp.svg @@ -0,0 +1,95 @@ +jonjan + + + diff --git a/testdata/d2ir/TestCompile/imports/nested/spread.exp.json b/testdata/d2ir/TestCompile/imports/nested/spread.exp.json new file mode 100644 index 000000000..6a7baa961 --- /dev/null +++ b/testdata/d2ir/TestCompile/imports/nested/spread.exp.json @@ -0,0 +1,117 @@ +{ + "fields": [ + { + "name": "jon", + "references": [ + { + "string": { + "range": "x.d2,0:5:5-0:8:8", + "value": [ + { + "string": "jon", + "raw_string": "jon" + } + ] + }, + "key_path": { + "range": "x.d2,0:5:5-0:8:8", + "path": [ + { + "unquoted_string": { + "range": "x.d2,0:5:5-0:8:8", + "value": [ + { + "string": "jon", + "raw_string": "jon" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "x.d2,0:5:5-0:8:8", + "key": { + "range": "x.d2,0:5:5-0:8:8", + "path": [ + { + "unquoted_string": { + "range": "x.d2,0:5:5-0:8:8", + "value": [ + { + "string": "jon", + "raw_string": "jon" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + } + ] + }, + { + "name": "jan", + "references": [ + { + "string": { + "range": "x.d2,0:10:10-0:13:13", + "value": [ + { + "string": "jan", + "raw_string": "jan" + } + ] + }, + "key_path": { + "range": "x.d2,0:10:10-0:13:13", + "path": [ + { + "unquoted_string": { + "range": "x.d2,0:10:10-0:13:13", + "value": [ + { + "string": "jan", + "raw_string": "jan" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "x.d2,0:10:10-0:14:14", + "key": { + "range": "x.d2,0:10:10-0:13:13", + "path": [ + { + "unquoted_string": { + "range": "x.d2,0:10:10-0:13:13", + "value": [ + { + "string": "jan", + "raw_string": "jan" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + } + ] + } + ], + "edges": null +}