diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 8ecca27a3..2e8157330 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -7,3 +7,4 @@ #### Bugfixes ⛑️ - Fixes edge case where layouts with dagre show a connection from the bottom side of shapes being slightly disconnected from the shape. [#820](https://github.com/terrastruct/d2/pull/820) +- Fixes rare compiler bug when using underscores in edges to create objects across containers. [#824](https://github.com/terrastruct/d2/pull/824) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 37e68632c..1ed5b18ca 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -337,6 +337,17 @@ x: { tassert.Equal(t, g.Objects[0].AbsID(), g.Objects[1].References[0].ScopeObj.AbsID()) }, }, + { + name: "underscore_connection", + text: `a: { + _.c.d -> _.c.b +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + tassert.Equal(t, 4, len(g.Objects)) + tassert.Equal(t, 1, len(g.Edges)) + }, + }, { name: "underscore_parent_not_root", diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index 455a38707..9f37917e3 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -379,7 +379,9 @@ func (eid *EdgeID) Match(eid2 *EdgeID) bool { return true } -func (eid *EdgeID) resolveUnderscores(m *Map) (*EdgeID, *Map, error) { +// resolve resolves both underscores and commons in eid. +// It returns the new eid, containing map adjusted for underscores and common ida. +func (eid *EdgeID) resolve(m *Map) (_ *EdgeID, _ *Map, common []string, _ error) { eid = eid.Copy() maxUnderscores := go2.Max(countUnderscores(eid.SrcPath), countUnderscores(eid.DstPath)) for i := 0; i < maxUnderscores; i++ { @@ -397,23 +399,20 @@ func (eid *EdgeID) resolveUnderscores(m *Map) (*EdgeID, *Map, error) { } m = ParentMap(m) if m == nil { - return nil, nil, errors.New("invalid underscore") + return nil, nil, nil, errors.New("invalid underscore") } } - return eid, m, nil -} -func (eid *EdgeID) trimCommon() (common []string, _ *EdgeID) { - eid = eid.Copy() for len(eid.SrcPath) > 1 && len(eid.DstPath) > 1 { if !strings.EqualFold(eid.SrcPath[0], eid.DstPath[0]) { - return common, eid + return eid, m, common, nil } common = append(common, eid.SrcPath[0]) eid.SrcPath = eid.SrcPath[1:] eid.DstPath = eid.DstPath[1:] } - return common, eid + + return eid, m, common, nil } type Edge struct { @@ -732,11 +731,10 @@ func (m *Map) DeleteField(ida ...string) *Field { } func (m *Map) GetEdges(eid *EdgeID) []*Edge { - eid, m, err := eid.resolveUnderscores(m) + eid, m, common, err := eid.resolve(m) if err != nil { return nil } - common, eid := eid.trimCommon() if len(common) > 0 { f := m.GetField(common...) if f == nil { @@ -762,16 +760,12 @@ func (m *Map) CreateEdge(eid *EdgeID, refctx *RefContext) (*Edge, error) { return nil, d2parser.Errorf(refctx.Edge, "cannot create edge inside edge") } - eid, m, err := eid.resolveUnderscores(m) + eid, m, common, err := eid.resolve(m) if err != nil { return nil, d2parser.Errorf(refctx.Edge, err.Error()) } - common, eid := eid.trimCommon() if len(common) > 0 { - tmp := *refctx.Edge.Src - kp := &tmp - kp.Path = kp.Path[:len(common)] - f, err := m.EnsureField(kp, nil) + f, err := m.EnsureField(d2ast.MakeKeyPath(common), nil) if err != nil { return nil, err } diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 1d3103a28..9fe1c5389 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -2066,7 +2066,13 @@ func hasSpace(tag string) bool { } func getMostNestedRefs(obj *d2graph.Object) []d2graph.Reference { - most := obj.References[0] + var most d2graph.Reference + for _, ref := range obj.References { + if len(ref.MapKey.Edges) == 0 { + most = ref + break + } + } for _, ref := range obj.References { if len(ref.MapKey.Edges) != 0 { continue diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 02669c453..4c6a16cae 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -2001,6 +2001,32 @@ c: { assert.JSON(t, len(g.Objects), 3) }, }, + { + name: "underscore-connection", + + text: `a: { + b + + _.c.d -> b +} + +c: { + d +} +`, + key: `a.b`, + newKey: `c.b`, + + exp: `a: { + _.c.d -> _.c.b +} + +c: { + d + b +} +`, + }, { name: "flat_middle_container", diff --git a/testdata/d2compiler/TestCompile/underscore_connection.exp.json b/testdata/d2compiler/TestCompile/underscore_connection.exp.json new file mode 100644 index 000000000..cdcd84009 --- /dev/null +++ b/testdata/d2compiler/TestCompile/underscore_connection.exp.json @@ -0,0 +1,489 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-3:0:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-2:1:23", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:3:3-2:0:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:16:21", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:16:21", + "src": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 2, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/underscore_connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 2, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2oracle/TestMove/underscore-connection.exp.json b/testdata/d2oracle/TestMove/underscore-connection.exp.json new file mode 100644 index 000000000..46568d214 --- /dev/null +++ b/testdata/d2oracle/TestMove/underscore-connection.exp.json @@ -0,0 +1,624 @@ +{ + "graph": { + "name": "", + "ast": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-8:0:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-2:1:23", + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:3:3-2:0:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:16:21", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:16:21", + "src": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:0:25-7:1:39", + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:0:25-4:1:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:0:25-4:1:26", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:3:28-7:0:38", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,5:2:32-5:3:33", + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,5:2:32-5:3:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,5:2:32-5:3:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,6:2:36-6:3:37", + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,6:2:36-6:3:37", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,6:2:36-6:3:37", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "minWidth": 0, + "minHeight": 0, + "label_dimensions": { + "width": 0, + "height": 0 + }, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:0:25-4:1:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,4:0:25-4:1:26", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:8:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:2:7-1:3:8", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:4:9-1:5:10", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:6:11-1:7:12", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 2, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,5:2:32-5:3:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,5:2:32-5:3:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:10:15-1:16:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:11:16-1:12:17", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:13:18-1:14:19", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,1:15:20-1:16:21", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 2, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,6:2:36-6:3:37", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/underscore-connection.d2,6:2:36-6:3:37", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +}