From 85bfad19a6cb1455a242e4d08bddbad73ba5a01c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Jul 2023 11:55:58 -0700 Subject: [PATCH] compile composites --- d2compiler/compile.go | 6 + d2compiler/compile_test.go | 85 ++- d2ir/compile.go | 50 +- .../TestCompile2/vars/basic/map.exp.json | 531 ++++++++++++++++++ .../vars/basic/primary-and-composite.exp.json | 323 +++++++++++ .../TestCompile2/vars/errors/bad-var.exp.json | 11 + .../vars/errors/multi-part-map.exp.json | 11 + .../vars/errors/quoted-map.exp.json | 11 + 8 files changed, 997 insertions(+), 31 deletions(-) create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/map.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/bad-var.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/quoted-map.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index c1800e571..29927ca57 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -281,6 +281,12 @@ func (c *compiler) compileField(obj *d2graph.Object, f *d2ir.Field) { if f.Map() != nil { if len(f.Map().Edges) > 0 { c.errorf(f.Map().Edges[0].LastRef().AST(), "vars cannot contain an edge") + } else { + for _, f := range f.Map().Fields { + if f.Primary() == nil && f.Composite == nil { + c.errorf(f.LastRef().AST(), "invalid var with no value") + } + } } } return diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 54c2feba4..75871506d 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3357,6 +3357,41 @@ a: { assert.Equal(t, "im root var", g.Objects[1].Label.Value) }, }, + { + name: "map", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + cool-style: { + fill: red + } + arrows: { + target-arrowhead.label: yay + } +} +hi.style: ${cool-style} +a -> b: ${arrows} +`, "") + assert.Equal(t, "red", g.Objects[0].Style.Fill.Value) + assert.Equal(t, "yay", g.Edges[0].DstArrowhead.Label.Value) + }, + }, + { + name: "primary-and-composite", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + x: all { + a: b + } +} +z: ${x} +`, "") + assert.Equal(t, "z", g.Objects[1].ID) + assert.Equal(t, "all", g.Objects[1].Label.Value) + assert.Equal(t, 1, len(g.Objects[1].Children)) + }, + }, } for _, tc := range tca { @@ -3592,6 +3627,43 @@ hi: ${z} `, `d2/testdata/d2compiler/TestCompile2/vars/errors/missing.d2:5:1: could not resolve variable "z"`) }, }, + { + name: "bad-var", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + x +} +hi: ${x} +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/bad-var.d2:3:3: invalid var with no value`) + }, + }, + { + name: "multi-part-map", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + x: { + a: b + } +} +hi: 1 ${x} +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.d2:7:1: cannot substitute map variable "x" as part of a string`) + }, + }, + { + name: "quoted-map", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + x: { + a: b + } +} +hi: "${x}" +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.d2:7:1: cannot substitute map variable "x" in quotes`) + }, + }, { name: "nested-missing", run: func(t *testing.T) { @@ -3640,19 +3712,6 @@ hi `, "d2/testdata/d2compiler/TestCompile2/vars/errors/edge.d2:3:3: vars cannot contain an edge") }, }, - { - name: "map", - run: func(t *testing.T) { - assertCompile(t, ` -vars: { - colors: { - button: red - } -} -hi: ${colors} -`, `d2/testdata/d2compiler/TestCompile2/vars/errors/map.d2:7:1: cannot reference map variable "colors"`) - }, - }, } for _, tc := range tca { diff --git a/d2ir/compile.go b/d2ir/compile.go index f908d9b38..2c93b6ef4 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -104,11 +104,10 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) { varsStack = append([]*Map{f.Map()}, varsStack...) } if f.Primary() != nil { - c.resolveSubstitutions(varsStack, f.LastRef().AST(), f.Primary()) + c.resolveSubstitutions(varsStack, f) } if f.Map() != nil { - // this map could be the "vars" - // and if it is, then its already been compiled, so the varsStack can be truncated + // don't resolve substitutions in vars with the current scope of vars if f.Name == "vars" { c.compileSubstitutions(f.Map(), varsStack[1:]) } else { @@ -118,7 +117,7 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) { } for _, e := range m.Edges { if e.Primary() != nil { - c.resolveSubstitutions(varsStack, e.LastRef().AST(), e.Primary()) + c.resolveSubstitutions(varsStack, e) } if e.Map() != nil { c.compileSubstitutions(e.Map(), varsStack) @@ -126,11 +125,11 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) { } } -func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scalar *Scalar) { +func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) { var subbed bool var resolvedField *Field - switch s := scalar.Value.(type) { + switch s := node.Primary().Value.(type) { case *d2ast.UnquotedString: for i, box := range s.Value { if box.Substitution != nil { @@ -141,19 +140,34 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scala } } if resolvedField == nil { - c.errorf(node, `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) + c.errorf(node.LastRef().AST(), `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) return } + if resolvedField.Primary() == nil { + if len(s.Value) > 1 { + c.errorf(node.LastRef().AST(), `cannot substitute map variable "%s" as part of a string`, strings.Join(box.Substitution.IDA(), ".")) + return + } + } else { + // If lone and unquoted, replace with value of sub + if len(s.Value) == 1 { + node.Primary().Value = resolvedField.Primary().Value + } else { + s.Value[i].String = go2.Pointer(resolvedField.Primary().String()) + subbed = true + } + } if resolvedField.Composite != nil { - c.errorf(node, `cannot reference map variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) - return - } - // If lone and unquoted, replace with value of sub - if len(s.Value) == 1 { - scalar.Value = resolvedField.Primary().Value - } else { - s.Value[i].String = go2.Pointer(resolvedField.Primary().String()) - subbed = true + switch n := node.(type) { + case *Field: + n.Composite = resolvedField.Composite + case *Edge: + if resolvedField.Composite.Map() == nil { + c.errorf(node.LastRef().AST(), `cannot substitute array variable "%s" to an edge`, strings.Join(box.Substitution.IDA(), ".")) + return + } + n.Map_ = resolvedField.Composite.Map() + } } } } @@ -170,11 +184,11 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scala } } if resolvedField == nil { - c.errorf(node, `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) + c.errorf(node.LastRef().AST(), `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) return } if resolvedField.Composite != nil { - c.errorf(node, `cannot reference map variable "%s"`, strings.Join(box.Substitution.IDA(), ".")) + c.errorf(node.LastRef().AST(), `cannot substitute map variable "%s" in quotes`, strings.Join(box.Substitution.IDA(), ".")) return } s.Value[i].String = go2.Pointer(resolvedField.Primary().String()) diff --git a/testdata/d2compiler/TestCompile2/vars/basic/map.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/map.exp.json new file mode 100644 index 000000000..e04804d69 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/map.exp.json @@ -0,0 +1,531 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,0:0:0-11:0:133", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,1:0:1-8:1:90", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,1:6:7-8:1:90", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,2:2:11-4:3:40", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,2:2:11-2:12:21", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,2:2:11-2:12:21", + "value": [ + { + "string": "cool-style", + "raw_string": "cool-style" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,2:14:23-4:3:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,3:2:27-3:11:36", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,3:2:27-3:6:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,3:2:27-3:6:31", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,3:8:33-3:11:36", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,5:2:43-7:3:88", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,5:2:43-5:8:49", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,5:2:43-5:8:49", + "value": [ + { + "string": "arrows", + "raw_string": "arrows" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,5:10:51-7:3:88", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,6:4:57-6:31:84", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,6:4:57-6:26:79", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,6:4:57-6:20:73", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,6:21:74-6:26:79", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,6:28:81-6:31:84", + "value": [ + { + "string": "yay", + "raw_string": "yay" + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:0:91-9:23:114", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:0:91-9:8:99", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:0:91-9:2:93", + "value": [ + { + "string": "hi", + "raw_string": "hi" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:3:94-9:8:99", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:10:101-9:11:102", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:10:101-9:23:114", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:12:103-9:22:113", + "value": [ + { + "string": "cool-style", + "raw_string": "cool-style" + } + ] + } + } + ] + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:17:132", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:6:121", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:1:116", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:1:116", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:5:120-10:6:121", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:5:120-10:6:121", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:8:123-10:9:124", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:8:123-10:17:132", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:10:125-10:16:131", + "value": [ + { + "string": "arrows", + "raw_string": "arrows" + } + ] + } + } + ] + } + } + ] + } + } + } + } + ] + }, + "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, + "dstArrowhead": { + "label": { + "value": "yay" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "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": "hi", + "id_val": "hi", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:0:91-9:8:99", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:0:91-9:2:93", + "value": [ + { + "string": "hi", + "raw_string": "hi" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,9:3:94-9:8:99", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hi" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:1:116", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:0:115-10:1:116", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:5:120-10:6:121", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/map.d2,10:5:120-10:6:121", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "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/basic/primary-and-composite.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.exp.json new file mode 100644 index 000000000..f7ddb1d5c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.exp.json @@ -0,0 +1,323 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,0:0:0-7:0:40", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,1:0:1-5:1:31", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,1:6:7-5:1:31", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,2:1:10-4:3:29", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,2:1:10-2:2:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,2:1:10-2:2:11", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,2:4:13-2:7:16", + "value": [ + { + "string": "all", + "raw_string": "all" + } + ] + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,2:8:17-4:3:29", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:2:21-3:6:25", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:2:21-3:3:22", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:2:21-3:3:22", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:5:24-3:6:25", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:0:32-6:7:39", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:0:32-6:1:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:0:32-6:1:33", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:3:35-6:4:36", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:3:35-6:7:39", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:5:37-6:6:38", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + } + } + ] + } + } + } + } + ] + }, + "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": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:2:21-3:3:22", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,3:2:21-3:3:22", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "z", + "id_val": "z", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:0:32-6:1:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/primary-and-composite.d2,6:0:32-6:1:33", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "all" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "vars", + "id_val": "vars", + "attributes": { + "label": { + "value": "vars" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "attributes": { + "label": { + "value": "x" + }, + "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/errors/bad-var.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/bad-var.exp.json new file mode 100644 index 000000000..c079e0f3c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/bad-var.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/bad-var.d2,2:2:11-2:3:12", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/bad-var.d2:3:3: invalid var with no value" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.exp.json new file mode 100644 index 000000000..70c263dfa --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.d2,6:0:31-6:2:33", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/multi-part-map.d2:7:1: cannot substitute map variable \"x\" as part of a string" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.exp.json new file mode 100644 index 000000000..f5610c5de --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.d2,6:0:31-6:2:33", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/quoted-map.d2:7:1: cannot substitute map variable \"x\" in quotes" + } + ] + } +}