From 0fa89bd81c593d0f6365d3c788fc74c9c32b0699 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Mon, 5 Aug 2024 19:18:34 -0700 Subject: [PATCH] d2ir: use current var stack --- ci/release/changelogs/next.md | 2 + d2compiler/compile_test.go | 26 + d2ir/compile.go | 35 +- .../TestCompile/var_in_vars.exp.json | 868 ++++++++++++++++++ .../vars/override/recursive-var.exp.json | 167 +++- 5 files changed, 1078 insertions(+), 20 deletions(-) create mode 100644 testdata/d2compiler/TestCompile/var_in_vars.exp.json diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index da7d1bf416..9e9668cdf4 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,5 +1,7 @@ #### Features ๐Ÿš€ +- Variables definitions can now refer to other variables in the current scope [#2052](https://github.com/terrastruct/d2/pull/2052) + #### Improvements ๐Ÿงน - Sequence diagram edge groups account for edge label heights [#2038](https://github.com/terrastruct/d2/pull/2038) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 0e9646537f..5b5368434a 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2763,6 +2763,29 @@ x*: { tassert.Equal(t, "x2", g.Objects[3].AbsID()) }, }, + { + name: "var_in_vars", + text: `vars: { + Apple: { + shape:circle + label:Granny Smith + } + Cherry: { + shape:circle + label:Rainier Cherry + } + SummerFruit: { + xx: ${Apple} + cc: ${Cherry} + xx -> cc + } +} + +x: ${Apple} +c: ${Cherry} +sf: ${SummerFruit} +`, + }, { name: "class-shape-class", text: `classes: { @@ -4071,11 +4094,14 @@ vars: { hi: { vars: { x: ${x}-b + b: ${x} } yo: ${x} + hey: ${b} } `, "") assert.Equal(t, "a-b", g.Objects[1].Label.Value) + assert.Equal(t, "a-b", g.Objects[2].Label.Value) }, }, { diff --git a/d2ir/compile.go b/d2ir/compile.go index 2dad21fbb8..a0e63b261f 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -144,9 +144,8 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) { } } } else if f.Map() != nil { - // don't resolve substitutions in vars with the current scope of vars if f.Name == "vars" { - c.compileSubstitutions(f.Map(), varsStack[1:]) + c.compileSubstitutions(f.Map(), varsStack) c.validateConfigs(f.Map().GetField("d2-config")) } else { c.compileSubstitutions(f.Map(), varsStack) @@ -227,8 +226,8 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie case *d2ast.UnquotedString: for i, box := range s.Value { if box.Substitution != nil { - for _, vars := range varsStack { - resolvedField = c.resolveSubstitution(vars, box.Substitution) + for i, vars := range varsStack { + resolvedField = c.resolveSubstitution(vars, node, box.Substitution, i == 0) if resolvedField != nil { if resolvedField.Primary() != nil { if _, ok := resolvedField.Primary().Value.(*d2ast.Null); ok { @@ -319,8 +318,8 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie case *d2ast.DoubleQuotedString: for i, box := range s.Value { if box.Substitution != nil { - for _, vars := range varsStack { - resolvedField = c.resolveSubstitution(vars, box.Substitution) + for i, vars := range varsStack { + resolvedField = c.resolveSubstitution(vars, node, box.Substitution, i == 0) if resolvedField != nil { break } @@ -344,16 +343,38 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie return removedField } -func (c *compiler) resolveSubstitution(vars *Map, substitution *d2ast.Substitution) *Field { +func (c *compiler) resolveSubstitution(vars *Map, node Node, substitution *d2ast.Substitution, isCurrentScopeVars bool) *Field { if vars == nil { return nil } + fieldNode, fok := node.(*Field) + parent := ParentField(node) + for i, p := range substitution.Path { f := vars.GetField(p.Unbox().ScalarString()) if f == nil { return nil } + // Consider this case: + // + // ``` + // vars: { + // x: a + // } + // hi: { + // vars: { + // x: ${x}-b + // } + // yo: ${x} + // } + // ``` + // + // When resolving hi.vars.x, the vars stack includes itself. + // So this next if clause says, "ignore if we're using the current scope's vars to try to resolve a substitution that requires a var from further in the stack" + if fok && fieldNode.Name == p.Unbox().ScalarString() && isCurrentScopeVars && parent.Name == "vars" { + return nil + } if i == len(substitution.Path)-1 { return f diff --git a/testdata/d2compiler/TestCompile/var_in_vars.exp.json b/testdata/d2compiler/TestCompile/var_in_vars.exp.json new file mode 100644 index 0000000000..83d058e831 --- /dev/null +++ b/testdata/d2compiler/TestCompile/var_in_vars.exp.json @@ -0,0 +1,868 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,0:0:0-19:0:277", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,0:0:0-14:1:231", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,0:6:6-14:1:231", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,1:4:12-4:5:74", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,1:4:12-1:9:17", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,1:4:12-1:9:17", + "value": [ + { + "string": "Apple", + "raw_string": "Apple" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,1:11:19-4:5:74", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,2:8:29-2:20:41", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,2:8:29-2:13:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,2:8:29-2:13:34", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,2:14:35-2:20:41", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,3:8:50-3:26:68", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,3:8:50-3:13:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,3:8:50-3:13:55", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,3:14:56-3:26:68", + "value": [ + { + "string": "Granny Smith", + "raw_string": "Granny Smith" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,5:4:79-8:5:144", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,5:4:79-5:10:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,5:4:79-5:10:85", + "value": [ + { + "string": "Cherry", + "raw_string": "Cherry" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,5:12:87-8:5:144", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,6:8:97-6:20:109", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,6:8:97-6:13:102", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,6:8:97-6:13:102", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,6:14:103-6:20:109", + "value": [ + { + "string": "circle", + "raw_string": "circle" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,7:8:118-7:28:138", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,7:8:118-7:13:123", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,7:8:118-7:13:123", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,7:14:124-7:28:138", + "value": [ + { + "string": "Rainier Cherry", + "raw_string": "Rainier Cherry" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,9:4:149-13:5:229", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,9:4:149-9:15:160", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,9:4:149-9:15:160", + "value": [ + { + "string": "SummerFruit", + "raw_string": "SummerFruit" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,9:17:162-13:5:229", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:8:172-10:20:184", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:8:172-10:10:174", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:8:172-10:10:174", + "value": [ + { + "string": "xx", + "raw_string": "xx" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:12:176-10:13:177", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:12:176-10:20:184", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:14:178-10:19:183", + "value": [ + { + "string": "Apple", + "raw_string": "Apple" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:8:193-11:21:206", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:8:193-11:10:195", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:8:193-11:10:195", + "value": [ + { + "string": "cc", + "raw_string": "cc" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:12:197-11:13:198", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:12:197-11:21:206", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:14:199-11:20:205", + "value": [ + { + "string": "Cherry", + "raw_string": "Cherry" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:16:223", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:16:223", + "src": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:10:217", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:10:217", + "value": [ + { + "string": "xx", + "raw_string": "xx" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:14:221-12:16:223", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:14:221-12:16:223", + "value": [ + { + "string": "cc", + "raw_string": "cc" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:0:233-16:11:244", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:0:233-16:1:234", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:0:233-16:1:234", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:3:236-16:4:237", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:3:236-16:11:244", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:5:238-16:10:243", + "value": [ + { + "string": "Apple", + "raw_string": "Apple" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:0:245-17:12:257", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:0:245-17:1:246", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:0:245-17:1:246", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:3:248-17:4:249", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:3:248-17:12:257", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:5:250-17:11:256", + "value": [ + { + "string": "Cherry", + "raw_string": "Cherry" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:0:258-18:18:276", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:0:258-18:2:260", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:0:258-18:2:260", + "value": [ + { + "string": "sf", + "raw_string": "sf" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:4:262-18:5:263", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:4:262-18:18:276", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:6:264-18:17:275", + "value": [ + { + "string": "SummerFruit", + "raw_string": "SummerFruit" + } + ] + } + } + ] + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "xx", + "id_val": "xx", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:8:172-10:10:174", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,10:8:172-10:10:174", + "value": [ + { + "string": "xx", + "raw_string": "xx" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:10:217", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:8:215-12:10:217", + "value": [ + { + "string": "xx", + "raw_string": "xx" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "Granny Smith" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "cc", + "id_val": "cc", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:8:193-11:10:195", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,11:8:193-11:10:195", + "value": [ + { + "string": "cc", + "raw_string": "cc" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:14:221-12:16:223", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,12:14:221-12:16:223", + "value": [ + { + "string": "cc", + "raw_string": "cc" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "Rainier Cherry" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:0:233-16:1:234", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,16:0:233-16:1:234", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "Granny Smith" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:0:245-17:1:246", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,17:0:245-17:1:246", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "Rainier Cherry" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "circle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "sf", + "id_val": "sf", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:0:258-18:2:260", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/var_in_vars.d2,18:0:258-18:2:260", + "value": [ + { + "string": "sf", + "raw_string": "sf" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "sf" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/vars/override/recursive-var.exp.json b/testdata/d2compiler/TestCompile2/vars/override/recursive-var.exp.json index 19277bee22..c075d52a34 100644 --- a/testdata/d2compiler/TestCompile2/vars/override/recursive-var.exp.json +++ b/testdata/d2compiler/TestCompile2/vars/override/recursive-var.exp.json @@ -3,7 +3,7 @@ "name": "", "isFolderOnly": false, "ast": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,0:0:0-10:0:65", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,0:0:0-12:0:87", "nodes": [ { "map_key": { @@ -69,7 +69,7 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,4:0:18-9:1:64", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,4:0:18-11:1:86", "key": { "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,4:0:18-4:2:20", "path": [ @@ -89,11 +89,11 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,4:4:22-9:1:64", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,4:4:22-11:1:86", "nodes": [ { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,5:2:26-7:3:51", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,5:2:26-8:3:61", "key": { "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,5:2:26-5:6:30", "path": [ @@ -113,7 +113,7 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,5:8:32-7:3:51", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,5:8:32-8:3:61", "nodes": [ { "map_key": { @@ -146,6 +146,54 @@ } } } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:2:50-7:9:57", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:2:50-7:3:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:2:50-7:3:51", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:5:53-7:6:54", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:5:53-7:9:57", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,7:7:55-7:8:56", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + } + } + ] + } + } + } } ] } @@ -154,13 +202,13 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:2:54-8:10:62", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:2:64-9:10:72", "key": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:2:54-8:4:56", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:2:64-9:4:66", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:2:54-8:4:56", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:2:64-9:4:66", "value": [ { "string": "yo", @@ -174,16 +222,16 @@ "primary": {}, "value": { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:6:58-8:7:59", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:6:68-9:7:69", "value": [ { "substitution": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:6:58-8:10:62", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:6:68-9:10:72", "spread": false, "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:8:60-8:9:61", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:8:70-9:9:71", "value": [ { "string": "x", @@ -199,6 +247,54 @@ } } } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:2:75-10:11:84", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:2:75-10:5:78", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:2:75-10:5:78", + "value": [ + { + "string": "hey", + "raw_string": "hey" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:7:80-10:8:81", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:7:80-10:11:84", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:9:82-10:10:83", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + } + ] + } + } + } } ] } @@ -283,11 +379,11 @@ "references": [ { "key": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:2:54-8:4:56", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:2:64-9:4:66", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,8:2:54-8:4:56", + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,9:2:64-9:4:66", "value": [ { "string": "yo", @@ -321,6 +417,51 @@ "constraint": null }, "zIndex": 0 + }, + { + "id": "hey", + "id_val": "hey", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:2:75-10:5:78", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/override/recursive-var.d2,10:2:75-10:5:78", + "value": [ + { + "string": "hey", + "raw_string": "hey" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a-b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 } ] },