From 98f79e2ba5e20e8d13acda4d2dc9b58b677c23cc Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Jul 2023 22:20:55 -0700 Subject: [PATCH] arrays --- d2compiler/compile_test.go | 88 ++++- d2ir/compile.go | 63 ++- d2parser/parse.go | 3 +- .../TestCompile2/vars/basic/array.exp.json | 347 +++++++++++++++++ .../vars/basic/multi-part-array.exp.json | 221 +++++++++++ .../vars/basic/spread-array.exp.json | 359 ++++++++++++++++++ .../vars/basic/sub-array.exp.json | 237 ++++++++++++ .../vars/errors/missing-array.exp.json | 11 + .../vars/errors/spread-non-array.exp.json | 11 + .../vars/errors/spread-non-map.exp.json | 2 +- .../vars/errors/spread-non-solo.exp.json | 11 + 11 files changed, 1335 insertions(+), 18 deletions(-) create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/spread-array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/basic/sub-array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/missing-array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.exp.json create mode 100644 testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 36e502a68..ac43dcc6d 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3411,6 +3411,64 @@ z: { assert.Equal(t, 3, len(g.Objects[1].Children)) }, }, + { + name: "array", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + base-constraints: [UNQ; NOT NULL] +} +a: { + shape: sql_table + b: int {constraint: ${base-constraints}} +} +`, "") + assert.Equal(t, "a", g.Objects[0].ID) + assert.Equal(t, 2, len(g.Objects[0].SQLTable.Columns[0].Constraint)) + }, + }, + { + name: "spread-array", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + base-constraints: [UNQ; NOT NULL] +} +a: { + shape: sql_table + b: int {constraint: [PK; ...${base-constraints}]} +} +`, "") + assert.Equal(t, "a", g.Objects[0].ID) + assert.Equal(t, 3, len(g.Objects[0].SQLTable.Columns[0].Constraint)) + }, + }, + { + name: "sub-array", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + x: all +} +z.class: [a; ${x}] +`, "") + assert.Equal(t, "z", g.Objects[0].ID) + assert.Equal(t, "all", g.Objects[0].Attributes.Classes[1]) + }, + }, + { + name: "multi-part-array", + run: func(t *testing.T) { + g := assertCompile(t, ` +vars: { + x: all +} +z.class: [a; ${x}together] +`, "") + assert.Equal(t, "z", g.Objects[0].ID) + assert.Equal(t, "alltogether", g.Objects[0].Attributes.Classes[1]) + }, + }, } for _, tc := range tca { @@ -3742,7 +3800,35 @@ z: { ...${x} c } -`, `d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.d2:6:3: cannot spread non-map into map`) +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.d2:6:3: cannot spread non-composite into composite`) + }, + }, + { + name: "missing-array", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + x: b +} +z: { + class: [...${a}] +} +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/missing-array.d2:6:3: could not resolve variable "a"`) + }, + }, + { + name: "spread-non-array", + run: func(t *testing.T) { + assertCompile(t, ` +vars: { + x: { + a: b + } +} +z: { + class: [...${x}] +} +`, `d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.d2:8:11: cannot spread non-array into array`) }, }, { diff --git a/d2ir/compile.go b/d2ir/compile.go index db1e8ec5c..f4f0e7d4c 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -106,6 +106,13 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) { if f.Primary() != nil { c.resolveSubstitutions(varsStack, f) } + if arr, ok := f.Composite.(*Array); ok { + for _, val := range arr.Values { + if scalar, ok := val.(*Scalar); ok { + c.resolveSubstitutions(varsStack, scalar) + } + } + } if f.Map() != nil { // don't resolve substitutions in vars with the current scope of vars if f.Name == "vars" { @@ -145,20 +152,34 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) { } if box.Substitution.Spread { if resolvedField.Composite == nil { - c.errorf(box.Substitution, "cannot spread non-map into map") + c.errorf(box.Substitution, "cannot spread non-composite into composite") continue } - // TODO arrays - if resolvedField.Map() != nil { - OverlayMap(ParentMap(node), resolvedField.Map()) - } - // Remove the placeholder field - f := node.(*Field) - m := f.parent.(*Map) - for i, f2 := range m.Fields { - if f == f2 { - m.Fields = append(m.Fields[:i], m.Fields[i+1:]...) - break + switch n := node.(type) { + case *Scalar: // Array value + resolvedArr, ok := resolvedField.Composite.(*Array) + if !ok { + c.errorf(box.Substitution, "cannot spread non-array into array") + continue + } + arr := n.parent.(*Array) + for i, s := range arr.Values { + if s == n { + arr.Values = append(append(arr.Values[:i], resolvedArr.Values...), arr.Values[i+1:]...) + break + } + } + case *Field: + if resolvedField.Map() != nil { + OverlayMap(ParentMap(n), resolvedField.Map()) + } + // Remove the placeholder field + m := n.parent.(*Map) + for i, f2 := range m.Fields { + if n == f2 { + m.Fields = append(m.Fields[:i], m.Fields[i+1:]...) + break + } } } } @@ -167,6 +188,12 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) { c.errorf(node.LastRef().AST(), `cannot substitute map variable "%s" as part of a string`, strings.Join(box.Substitution.IDA(), ".")) return } + switch n := node.(type) { + case *Field: + n.Primary_ = nil + case *Edge: + n.Primary_ = nil + } } else { if len(s.Value) == 1 { // If lone and unquoted, replace with value of sub @@ -276,7 +303,9 @@ func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) { }) case n.Substitution != nil: if !n.Substitution.Spread { - c.errorf(n.Import, "invalid non-spread substitution in map") + // TODO parser parses ${x} as a field with name "$" and map of child x + // So this is never reached. But that parser behavior could change + c.errorf(n.Substitution, "invalid non-spread substitution in map") continue } // placeholder field to be resolved at the end @@ -653,8 +682,12 @@ func (c *compiler) compileArray(dst *Array, a *d2ast.Array, scopeAST *d2ast.Map) irv = n } case *d2ast.Substitution: - // TODO - // panic("TODO") + irv = &Scalar{ + parent: dst, + Value: &d2ast.UnquotedString{ + Value: []d2ast.InterpolationBox{{Substitution: an.Substitution}}, + }, + } } dst.Values = append(dst.Values, irv) diff --git a/d2parser/parse.go b/d2parser/parse.go index fa64531a3..bb460da82 100644 --- a/d2parser/parse.go +++ b/d2parser/parse.go @@ -1560,7 +1560,8 @@ func (p *parser) parseArrayNode(r rune) d2ast.ArrayNodeBox { p.replay(r) vbox := p.parseValue() - if vbox.UnquotedString != nil && vbox.UnquotedString.ScalarString() == "" { + if vbox.UnquotedString != nil && vbox.UnquotedString.ScalarString() == "" && + !(len(vbox.UnquotedString.Value) > 0 && vbox.UnquotedString.Value[0].Substitution != nil) { p.errorf(p.pos, p.pos.Advance(r, p.utf16), "unquoted strings cannot start on %q", r) } box.Null = vbox.Null diff --git a/testdata/d2compiler/TestCompile2/vars/basic/array.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/array.exp.json new file mode 100644 index 000000000..73c5d4b33 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/array.exp.json @@ -0,0 +1,347 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,0:0:0-8:0:114", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,1:0:1-3:1:45", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,1:6:7-3:1:45", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:1:10-2:34:43", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:1:10-2:17:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:1:10-2:17:26", + "value": [ + { + "string": "base-constraints", + "raw_string": "base-constraints" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:19:28-2:33:42", + "nodes": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:20:29-2:23:32", + "value": [ + { + "string": "UNQ", + "raw_string": "UNQ" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,2:25:34-2:33:42", + "value": [ + { + "string": "NOT NULL", + "raw_string": "NOT NULL" + } + ] + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,4:0:46-7:1:113", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,4:0:46-4:1:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,4:0:46-4:1:47", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,4:3:49-7:1:113", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,5:2:53-5:18:69", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,5:2:53-5:7:58", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,5:2:53-5:7:58", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,5:9:60-5:18:69", + "value": [ + { + "string": "sql_table", + "raw_string": "sql_table" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:1:71-6:41:111", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:1:71-6:2:72", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:1:71-6:2:72", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:4:74-6:7:77", + "value": [ + { + "string": "int", + "raw_string": "int" + } + ] + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:8:78-6:41:111", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:9:79-6:40:110", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:9:79-6:19:89", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:9:79-6:19:89", + "value": [ + { + "string": "constraint", + "raw_string": "constraint" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:21:91-6:22:92", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:21:91-6:40:110", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,6:23:93-6:39:109", + "value": [ + { + "string": "base-constraints", + "raw_string": "base-constraints" + } + ] + } + } + ] + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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/array.d2,4:0:46-4:1:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/array.d2,4:0:46-4:1:47", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "sql_table": { + "columns": [ + { + "name": { + "label": "b", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "constraint": [ + "UNQ", + "NOT NULL" + ], + "reference": "" + } + ] + }, + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "sql_table" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.exp.json new file mode 100644 index 000000000..f6b14f864 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.exp.json @@ -0,0 +1,221 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,0:0:0-5:0:46", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,1:0:1-3:1:18", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,1:6:7-3:1:18", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,2:1:10-2:7:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,2:1:10-2:2:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,2:1:10-2:2:11", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,2:4:13-2:7:16", + "value": [ + { + "string": "all", + "raw_string": "all" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:0:19-4:26:45", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:0:19-4:7:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:0:19-4:1:20", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:2:21-4:7:26", + "value": [ + { + "string": "class", + "raw_string": "class" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:9:28-4:25:44", + "nodes": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:10:29-4:11:30", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:13:32-4:25:44", + "value": [ + { + "string": "alltogether" + } + ] + } + } + ] + } + } + } + } + ] + }, + "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": "z", + "id_val": "z", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:0:19-4:7:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:0:19-4:1:20", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/multi-part-array.d2,4:2:21-4:7:26", + "value": [ + { + "string": "class", + "raw_string": "class" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "z" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null, + "classes": [ + "a", + "alltogether" + ] + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/vars/basic/spread-array.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/spread-array.exp.json new file mode 100644 index 000000000..f83c5490d --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/spread-array.exp.json @@ -0,0 +1,359 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,0:0:0-8:0:123", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,1:0:1-3:1:45", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,1:6:7-3:1:45", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:1:10-2:34:43", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:1:10-2:17:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:1:10-2:17:26", + "value": [ + { + "string": "base-constraints", + "raw_string": "base-constraints" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:19:28-2:33:42", + "nodes": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:20:29-2:23:32", + "value": [ + { + "string": "UNQ", + "raw_string": "UNQ" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,2:25:34-2:33:42", + "value": [ + { + "string": "NOT NULL", + "raw_string": "NOT NULL" + } + ] + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,4:0:46-7:1:122", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,4:0:46-4:1:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,4:0:46-4:1:47", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,4:3:49-7:1:122", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,5:2:53-5:18:69", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,5:2:53-5:7:58", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,5:2:53-5:7:58", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,5:9:60-5:18:69", + "value": [ + { + "string": "sql_table", + "raw_string": "sql_table" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:1:71-6:50:120", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:1:71-6:2:72", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:1:71-6:2:72", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:4:74-6:7:77", + "value": [ + { + "string": "int", + "raw_string": "int" + } + ] + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:8:78-6:50:120", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:9:79-6:49:119", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:9:79-6:19:89", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:9:79-6:19:89", + "value": [ + { + "string": "constraint", + "raw_string": "constraint" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:21:91-6:48:118", + "nodes": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:22:92-6:24:94", + "value": [ + { + "string": "PK", + "raw_string": "PK" + } + ] + } + }, + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:26:96-6:48:118", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,6:31:101-6:47:117", + "value": [ + { + "string": "base-constraints", + "raw_string": "base-constraints" + } + ] + } + } + ] + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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/spread-array.d2,4:0:46-4:1:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/spread-array.d2,4:0:46-4:1:47", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "sql_table": { + "columns": [ + { + "name": { + "label": "b", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0 + }, + "constraint": [ + "PK", + "UNQ", + "NOT NULL" + ], + "reference": "" + } + ] + }, + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "sql_table" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/vars/basic/sub-array.exp.json b/testdata/d2compiler/TestCompile2/vars/basic/sub-array.exp.json new file mode 100644 index 000000000..0c182f344 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/basic/sub-array.exp.json @@ -0,0 +1,237 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,0:0:0-5:0:38", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,1:0:1-3:1:18", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,1:0:1-1:4:5", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,1:6:7-3:1:18", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,2:1:10-2:7:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,2:1:10-2:2:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,2:1:10-2:2:11", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,2:4:13-2:7:16", + "value": [ + { + "string": "all", + "raw_string": "all" + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:0:19-4:18:37", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:0:19-4:7:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:0:19-4:1:20", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:2:21-4:7:26", + "value": [ + { + "string": "class", + "raw_string": "class" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "array": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:9:28-4:18:37", + "nodes": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:10:29-4:11:30", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:13:32-4:14:33", + "value": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:13:32-4:17:36", + "spread": false, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:15:34-4:16:35", + "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": "z", + "id_val": "z", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:0:19-4:7:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:0:19-4:1:20", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/vars/basic/sub-array.d2,4:2:21-4:7:26", + "value": [ + { + "string": "class", + "raw_string": "class" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "z" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null, + "classes": [ + "a", + "all" + ] + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/vars/errors/missing-array.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/missing-array.exp.json new file mode 100644 index 000000000..a0790a2f0 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/missing-array.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/missing-array.d2,5:2:24-5:7:29", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/missing-array.d2:6:3: could not resolve variable \"a\"" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.exp.json new file mode 100644 index 000000000..2ffbdf15c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.d2,7:10:45-7:17:52", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-array.d2:8:11: cannot spread non-array into array" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.exp.json index 02e2b3eb6..b713c683f 100644 --- a/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.exp.json +++ b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.exp.json @@ -4,7 +4,7 @@ "errs": [ { "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.d2,5:2:26-5:9:33", - "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.d2:6:3: cannot spread non-map into map" + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-map.d2:6:3: cannot spread non-composite into composite" } ] } diff --git a/testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.exp.json b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.exp.json new file mode 100644 index 000000000..296f35954 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.exp.json @@ -0,0 +1,11 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.d2,7:1:36-7:2:37", + "errmsg": "d2/testdata/d2compiler/TestCompile2/vars/errors/spread-non-solo.d2:8:2: cannot substitute map variable \"x\" as part of a string" + } + ] + } +}