diff --git a/d2ir/compile.go b/d2ir/compile.go index 0ceb42944..ba3744d3f 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -21,13 +21,22 @@ func (c *compiler) errorf(n d2ast.Node, f string, v ...interface{}) { }) } -func Compile(dst *Map, ast *d2ast.Map) error { - var c compiler - c.compileMap(dst, ast) - if !c.err.Empty() { - return c.err +func Compile(ast *d2ast.Map) (*IR, error) { + ir := &IR{ + AST: ast, + Map: &Map{}, } - return nil + + c := &compiler{} + c.compile(ir) + if !c.err.Empty() { + return nil, c.err + } + return ir, nil +} + +func (c *compiler) compile(ir *IR) { + c.compileMap(ir.Map, ir.AST) } func (c *compiler) compileMap(dst *Map, ast *d2ast.Map) { diff --git a/d2ir/compile_test.go b/d2ir/compile_test.go index 11c882a95..043525cc3 100644 --- a/d2ir/compile_test.go +++ b/d2ir/compile_test.go @@ -24,7 +24,7 @@ func TestCompile(t *testing.T) { type testCase struct { name string - run func(testing.TB, *d2ir.Map) + run func(testing.TB) } func runa(t *testing.T, tca []testCase) { @@ -32,50 +32,38 @@ func runa(t *testing.T, tca []testCase) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() - m := &d2ir.Map{} - tc.run(t, m) + tc.run(t) }) } } -func parse(t testing.TB, dst *d2ir.Map, text string) error { +func compile(t testing.TB, text string) (*d2ir.IR, error) { t.Helper() - d2Path := fmt.Sprintf("d2/testdata/d2ir/%v.d2", t.Name()) + d2Path := fmt.Sprintf("%v.d2", t.Name()) ast, err := d2parser.Parse(d2Path, strings.NewReader(text), nil) assert.Success(t, err) - err = d2ir.Compile(dst, ast) + ir, err := d2ir.Compile(ast) if err != nil { - return err + return nil, err } - err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), dst) - return err + err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), ir) + if err != nil { + return nil, err + } + return ir ,nil } func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interface{}, ida ...string) *d2ir.Field { t.Helper() - var m *d2ir.Map - p := &d2ir.Scalar{ - Value: &d2ast.Null{}, - } - switch n := n.(type) { - case *d2ir.Field: - mm, ok := n.Composite.(*d2ir.Map) - if ok { - m = mm - } else { - t.Fatalf("unexpected d2ir.Field.Composite %T", n.Composite) - } - p = n.Primary - case *d2ir.Map: - m = n - p.Value = &d2ast.Null{} - default: - t.Fatalf("unexpected d2ir.Node %T", n) + m := d2ir.ToMap(n) + if m == nil { + t.Fatalf("nil m from %T", n) } + p := d2ir.ToScalar(n) var f *d2ir.Field if len(ida) > 0 { @@ -84,11 +72,7 @@ func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interfa t.Fatalf("expected field %v in map %s", ida, m) } p = f.Primary - if f_m, ok := f.Composite.(*d2ir.Map); ok { - m = f_m - } else { - m = &d2ir.Map{} - } + m = d2ir.ToMap(f) } assert.Equal(t, nfields, m.FieldCountRecursive()) @@ -108,19 +92,9 @@ func assertEdge(t testing.TB, n d2ir.Node, nfields int, primary interface{}, eid eid := d2ir.NewEdgeIDs(k)[0] - var m *d2ir.Map - switch n := n.(type) { - case *d2ir.Field: - mm, ok := n.Composite.(*d2ir.Map) - if ok { - m = mm - } else { - t.Fatalf("unexpected d2ir.Field.Composite %T", n.Composite) - } - case *d2ir.Map: - m = n - default: - t.Fatalf("unexpected d2ir.Node %T", n) + m := d2ir.ToMap(n) + if m == nil { + t.Fatalf("nil m from %T", n) } ea := m.GetEdges(eid) @@ -177,43 +151,43 @@ func testCompileField(t *testing.T) { tca := []testCase{ { name: "root", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x`) + run: func(t testing.TB) { + ir, err := compile(t, `x`) assert.Success(t, err) - assertField(t, m, 1, 0, nil) + assertField(t, ir, 1, 0, nil) - assertField(t, m, 0, 0, nil, "x") + assertField(t, ir, 0, 0, nil, "x") }, }, { name: "label", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x: yes`) + run: func(t testing.TB) { + ir, err := compile(t, `x: yes`) assert.Success(t, err) - assertField(t, m, 1, 0, nil) + assertField(t, ir, 1, 0, nil) - assertField(t, m, 0, 0, "yes", "x") + assertField(t, ir, 0, 0, "yes", "x") }, }, { name: "nested", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x.y: yes`) + run: func(t testing.TB) { + ir, err := compile(t, `x.y: yes`) assert.Success(t, err) - assertField(t, m, 2, 0, nil) + assertField(t, ir, 2, 0, nil) - assertField(t, m, 1, 0, nil, "x") - assertField(t, m, 0, 0, "yes", "x", "y") + assertField(t, ir, 1, 0, nil, "x") + assertField(t, ir, 0, 0, "yes", "x", "y") }, }, { name: "array", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x: [1;2;3;4]`) + run: func(t testing.TB) { + ir, err := compile(t, `x: [1;2;3;4]`) assert.Success(t, err) - assertField(t, m, 1, 0, nil) + assertField(t, ir, 1, 0, nil) - f := assertField(t, m, 0, 0, nil, "x") + f := assertField(t, ir, 0, 0, nil, "x") assert.String(t, `[1; 2; 3; 4]`, f.Composite.String()) }, }, @@ -226,25 +200,25 @@ func testCompileFieldPrimary(t *testing.T) { tca := []testCase{ { name: "root", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x: yes { pqrs }`) + run: func(t testing.TB) { + ir, err := compile(t, `x: yes { pqrs }`) assert.Success(t, err) - assertField(t, m, 2, 0, nil) + assertField(t, ir, 2, 0, nil) - assertField(t, m, 1, 0, "yes", "x") - assertField(t, m, 0, 0, nil, "x", "pqrs") + assertField(t, ir, 1, 0, "yes", "x") + assertField(t, ir, 0, 0, nil, "x", "pqrs") }, }, { name: "nested", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x.y: yes { pqrs }`) + run: func(t testing.TB) { + ir, err := compile(t, `x.y: yes { pqrs }`) assert.Success(t, err) - assertField(t, m, 3, 0, nil) + assertField(t, ir, 3, 0, nil) - assertField(t, m, 2, 0, nil, "x") - assertField(t, m, 1, 0, "yes", "x", "y") - assertField(t, m, 0, 0, nil, "x", "y", "pqrs") + assertField(t, ir, 2, 0, nil, "x") + assertField(t, ir, 1, 0, "yes", "x", "y") + assertField(t, ir, 0, 0, nil, "x", "y", "pqrs") }, }, } @@ -256,43 +230,43 @@ func testCompileEdge(t *testing.T) { tca := []testCase{ { name: "root", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x -> y`) + run: func(t testing.TB) { + ir, err := compile(t, `x -> y`) assert.Success(t, err) - assertField(t, m, 2, 1, nil) - assertEdge(t, m, 0, nil, `(x -> y)[0]`) + assertField(t, ir, 2, 1, nil) + assertEdge(t, ir, 0, nil, `(x -> y)[0]`) - assertField(t, m, 0, 0, nil, "x") - assertField(t, m, 0, 0, nil, "y") + assertField(t, ir, 0, 0, nil, "x") + assertField(t, ir, 0, 0, nil, "y") }, }, { name: "nested", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `x.y -> z.p`) + run: func(t testing.TB) { + ir, err := compile(t, `x.y -> z.p`) assert.Success(t, err) - assertField(t, m, 4, 1, nil) + assertField(t, ir, 4, 1, nil) - assertField(t, m, 1, 0, nil, "x") - assertField(t, m, 0, 0, nil, "x", "y") + assertField(t, ir, 1, 0, nil, "x") + assertField(t, ir, 0, 0, nil, "x", "y") - assertField(t, m, 1, 0, nil, "z") - assertField(t, m, 0, 0, nil, "z", "p") + assertField(t, ir, 1, 0, nil, "z") + assertField(t, ir, 0, 0, nil, "z", "p") - assertEdge(t, m, 0, nil, "(x.y -> z.p)[0]") + assertEdge(t, ir, 0, nil, "(x.y -> z.p)[0]") }, }, { name: "underscore", - run: func(t testing.TB, m *d2ir.Map) { - err := parse(t, m, `p: { _.x -> z }`) + run: func(t testing.TB) { + ir, err := compile(t, `p: { _.x -> z }`) assert.Success(t, err) - assertField(t, m, 3, 1, nil) + assertField(t, ir, 3, 1, nil) - assertField(t, m, 0, 0, nil, "x") - assertField(t, m, 1, 0, nil, "p") + assertField(t, ir, 0, 0, nil, "x") + assertField(t, ir, 1, 0, nil, "p") - assertEdge(t, m, 0, nil, "(x -> p.z)[0]") + assertEdge(t, ir, 0, nil, "(x -> p.z)[0]") }, }, } diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index fc5d5930b..80297328b 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -13,13 +13,14 @@ import ( type Node interface { node() - ast() d2ast.Node + Copy(parent Node) Node Parent() Node - Copy(newp Node) Node + ast() d2ast.Node fmt.Stringer } +var _ Node = &IR{} var _ Node = &Scalar{} var _ Node = &Field{} var _ Node = &Edge{} @@ -44,12 +45,14 @@ type Composite interface { var _ Composite = &Array{} var _ Composite = &Map{} +func (n *IR) node() {} func (n *Scalar) node() {} func (n *Field) node() {} func (n *Edge) node() {} func (n *Array) node() {} func (n *Map) node() {} +func (n *IR) Parent() Node { return n.parent } func (n *Scalar) Parent() Node { return n.parent } func (n *Field) Parent() Node { return n.parent } func (n *Edge) Parent() Node { return n.parent } @@ -59,16 +62,35 @@ func (n *Map) Parent() Node { return n.parent } func (n *Scalar) value() {} func (n *Array) value() {} func (n *Map) value() {} +func (n *IR) value() {} func (n *Array) composite() {} func (n *Map) composite() {} +func (n *IR) composite() {} +func (n *IR) String() string { return d2format.Format(n.ast()) } func (n *Scalar) String() string { return d2format.Format(n.ast()) } func (n *Field) String() string { return d2format.Format(n.ast()) } func (n *Edge) String() string { return d2format.Format(n.ast()) } func (n *Array) String() string { return d2format.Format(n.ast()) } func (n *Map) String() string { return d2format.Format(n.ast()) } +type IR struct { + parent Node + + AST *d2ast.Map `json:"ast"` + Map *Map `json:"base"` +} + +func (ir *IR) Copy(newp Node) Node { + tmp := *ir + ir = &tmp + + ir.parent = newp.(*IR) + ir.Map = ir.Map.Copy(ir).(*Map) + return ir +} + type Scalar struct { parent Node Value d2ast.Scalar `json:"value"` @@ -115,9 +137,9 @@ func (m *Map) Copy(newp Node) Node { } // Root reports whether the Map is the root of the D2 tree. -// The root map has no parent. func (m *Map) Root() bool { - return m.parent == nil + _, ok := m.parent.(*IR) + return ok } type Field struct { @@ -222,16 +244,16 @@ func (eid *EdgeID) resolveUnderscores(m *Map) (*EdgeID, *Map, error) { if eid.SrcPath[0] == "_" { eid.SrcPath = eid.SrcPath[1:] } else { - mf := parentField(m) + mf := ParentField(m) eid.SrcPath = append([]string{mf.Name}, eid.SrcPath...) } if eid.DstPath[0] == "_" { eid.DstPath = eid.DstPath[1:] } else { - mf := parentField(m) + mf := ParentField(m) eid.DstPath = append([]string{mf.Name}, eid.DstPath...) } - m = parentMap(m) + m = ParentMap(m) if m == nil { return nil, nil, errors.New("invalid underscore") } @@ -327,12 +349,29 @@ type RefContext struct { Key *d2ast.Key Edge *d2ast.Edge Scope *d2ast.Map - - // UnresolvedScopeMap is prior to interpreting _ - UnresolvedScopeMap *Map } -func (rc RefContext) EdgeIndex() int { +// UnresolvedScopeMap is scope prior to interpreting _ +// It does this by finding the referenced *Map of rc.Scope +func (rc *RefContext) UnresolvedScopeMap(m *Map) *Map { + for { + fm := ParentField(m) + if fm == nil { + return m + } + for _, ref := range fm.References { + if ref.KeyPath != ref.Context.Key.Key { + continue + } + if ref.Context.Key.Value.Unbox() == rc.Scope { + return m + } + } + m = ParentMap(m) + } +} + +func (rc *RefContext) EdgeIndex() int { for i, e := range rc.Key.Edges { if e == rc.Edge { return i @@ -379,7 +418,7 @@ func (m *Map) EdgeCountRecursive() int { func (m *Map) GetField(ida []string) *Field { for len(ida) > 0 && ida[0] == "_" { - m = parentMap(m) + m = ParentMap(m) if m == nil { return nil } @@ -415,7 +454,7 @@ func (m *Map) getField(ida []string) *Field { func (m *Map) EnsureField(ida []string) (*Field, error) { for len(ida) > 0 && ida[0] == "_" { - m = parentMap(m) + m = ParentMap(m) if m == nil { return nil, errors.New("invalid underscore") } @@ -469,7 +508,7 @@ func (m *Map) ensureField(ida []string) (*Field, error) { return f.Composite.(*Map).ensureField(rest) } -func (m *Map) Delete(ida []string) bool { +func (m *Map) DeleteField(ida []string) bool { if len(ida) == 0 { return false } @@ -486,7 +525,7 @@ func (m *Map) Delete(ida []string) bool { return true } if f_m, ok := f.Composite.(*Map); ok { - return f_m.Delete(rest) + return f_m.DeleteField(rest) } } return false @@ -554,6 +593,10 @@ func (m *Map) EnsureEdge(eid *EdgeID) (*Edge, error) { return e, nil } +func (ir *IR) ast() d2ast.Node { + return ir.Map.ast() +} + func (s *Scalar) ast() d2ast.Node { return s.Value } @@ -619,7 +662,7 @@ func (m *Map) ast() d2ast.Node { return nil } astMap := &d2ast.Map{} - if m.parent == nil { + if m.Root() { astMap.Range = d2ast.MakeRange(",0:0:0-1:0:0") } else { astMap.Range = d2ast.MakeRange(",1:0:0-2:0:0") @@ -661,7 +704,33 @@ func (m *Map) appendEdgeReferences(e *Edge, refctx *RefContext) { m.appendFieldReferences(0, refctx.Edge.Dst, refctx) } -func parentMap(n Node) *Map { +func ToMap(n Node) *Map { + switch n := n.(type) { + case *Map: + return n + case *IR: + return n.Map + case *Field: + return ToMap(n.Composite) + case *Edge: + return n.Map + default: + return nil + } +} + +func ToScalar(n Node) *Scalar { + switch n := n.(type) { + case *Field: + return n.Primary + case *Edge: + return n.Primary + default: + return nil + } +} + +func ParentMap(n Node) *Map { for n.Parent() != nil { n = n.Parent() if n_m, ok := n.(*Map); ok { @@ -671,7 +740,7 @@ func parentMap(n Node) *Map { return nil } -func parentField(n Node) *Field { +func ParentField(n Node) *Field { for n.Parent() != nil { n = n.Parent() if n_f, ok := n.(*Field); ok { diff --git a/testdata/d2ir/TestCompile/edge/edge.exp.json b/testdata/d2ir/TestCompile/edge/edge.exp.json deleted file mode 100644 index 67dbe62d8..000000000 --- a/testdata/d2ir/TestCompile/edge/edge.exp.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "fields": [ - { - "name": "x" - }, - { - "name": "y" - } - ], - "edges": [ - { - "edge_id": { - "src_path": [ - "x" - ], - "src_arrow": false, - "dst_path": [ - "y" - ], - "dst_arrow": true, - "index": 0 - } - } - ] -} diff --git a/testdata/d2ir/TestCompile/edge/nested.exp.json b/testdata/d2ir/TestCompile/edge/nested.exp.json index 8f8b60261..171f32700 100644 --- a/testdata/d2ir/TestCompile/edge/nested.exp.json +++ b/testdata/d2ir/TestCompile/edge/nested.exp.json @@ -1,43 +1,118 @@ { - "fields": [ - { - "name": "x", - "composite": { - "fields": [ - { - "name": "y" - } - ], - "edges": null + "ast": { + "range": "TestCompile/edge/nested.d2,0:0:0-0:10:10", + "nodes": [ + { + "map_key": { + "range": "TestCompile/edge/nested.d2,0:0:0-0:10:10", + "edges": [ + { + "range": "TestCompile/edge/nested.d2,0:0:0-0:10:10", + "src": { + "range": "TestCompile/edge/nested.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/nested.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/edge/nested.d2,0:2:2-0:3:3", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "TestCompile/edge/nested.d2,0:6:6-0:10:10", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/nested.d2,0:7:7-0:8:8", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/edge/nested.d2,0:9:9-0:10:10", + "value": [ + { + "string": "p", + "raw_string": "p" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } } - }, - { - "name": "z", - "composite": { - "fields": [ - { - "name": "p" - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "composite": { + "fields": [ + { + "name": "y" + } + ], + "edges": null + } + }, + { + "name": "z", + "composite": { + "fields": [ + { + "name": "p" + } + ], + "edges": null + } } - } - ], - "edges": [ - { - "edge_id": { - "src_path": [ - "x", - "y" - ], - "src_arrow": false, - "dst_path": [ - "z", - "p" - ], - "dst_arrow": true, - "index": 0 + ], + "edges": [ + { + "edge_id": { + "src_path": [ + "x", + "y" + ], + "src_arrow": false, + "dst_path": [ + "z", + "p" + ], + "dst_arrow": true, + "index": 0 + } } - } - ] + ] + } } diff --git a/testdata/d2ir/TestCompile/edge/root.exp.json b/testdata/d2ir/TestCompile/edge/root.exp.json index 67dbe62d8..110559953 100644 --- a/testdata/d2ir/TestCompile/edge/root.exp.json +++ b/testdata/d2ir/TestCompile/edge/root.exp.json @@ -1,25 +1,78 @@ { - "fields": [ - { - "name": "x" - }, - { - "name": "y" - } - ], - "edges": [ - { - "edge_id": { - "src_path": [ - "x" - ], - "src_arrow": false, - "dst_path": [ - "y" - ], - "dst_arrow": true, - "index": 0 + "ast": { + "range": "TestCompile/edge/root.d2,0:0:0-0:6:6", + "nodes": [ + { + "map_key": { + "range": "TestCompile/edge/root.d2,0:0:0-0:6:6", + "edges": [ + { + "range": "TestCompile/edge/root.d2,0:0:0-0:6:6", + "src": { + "range": "TestCompile/edge/root.d2,0:0:0-0:2:2", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/root.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "TestCompile/edge/root.d2,0:4:4-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/root.d2,0:5:5-0:6:6", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } } - } - ] + ] + }, + "base": { + "fields": [ + { + "name": "x" + }, + { + "name": "y" + } + ], + "edges": [ + { + "edge_id": { + "src_path": [ + "x" + ], + "src_arrow": false, + "dst_path": [ + "y" + ], + "dst_arrow": true, + "index": 0 + } + } + ] + } } diff --git a/testdata/d2ir/TestCompile/edge/underscore.exp.json b/testdata/d2ir/TestCompile/edge/underscore.exp.json index d4a50ab64..a1076d021 100644 --- a/testdata/d2ir/TestCompile/edge/underscore.exp.json +++ b/testdata/d2ir/TestCompile/edge/underscore.exp.json @@ -1,34 +1,127 @@ { - "fields": [ - { - "name": "p", - "composite": { - "fields": [ - { - "name": "z" + "ast": { + "range": "TestCompile/edge/underscore.d2,0:0:0-0:15:15", + "nodes": [ + { + "map_key": { + "range": "TestCompile/edge/underscore.d2,0:0:0-0:15:15", + "key": { + "range": "TestCompile/edge/underscore.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/underscore.d2,0:0:0-0:1:1", + "value": [ + { + "string": "p", + "raw_string": "p" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "TestCompile/edge/underscore.d2,0:3:3-0:14:14", + "nodes": [ + { + "map_key": { + "range": "TestCompile/edge/underscore.d2,0:5:5-0:14:14", + "edges": [ + { + "range": "TestCompile/edge/underscore.d2,0:5:5-0:14:14", + "src": { + "range": "TestCompile/edge/underscore.d2,0:5:5-0:9:9", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/underscore.d2,0:5:5-0:6:6", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/edge/underscore.d2,0:7:7-0:8:8", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "TestCompile/edge/underscore.d2,0:11:11-0:14:14", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/edge/underscore.d2,0:12:12-0:13:13", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } } - ], - "edges": null + } } - }, - { - "name": "x" - } - ], - "edges": [ - { - "edge_id": { - "src_path": [ - "x" - ], - "src_arrow": false, - "dst_path": [ - "p", - "z" - ], - "dst_arrow": true, - "index": 0 + ] + }, + "base": { + "fields": [ + { + "name": "p", + "composite": { + "fields": [ + { + "name": "z" + } + ], + "edges": null + } + }, + { + "name": "x" } - } - ] + ], + "edges": [ + { + "edge_id": { + "src_path": [ + "x" + ], + "src_arrow": false, + "dst_path": [ + "p", + "z" + ], + "dst_arrow": true, + "index": 0 + } + } + ] + } } diff --git a/testdata/d2ir/TestCompile/field/array.exp.json b/testdata/d2ir/TestCompile/field/array.exp.json index 4f45a4827..cd5a6697e 100644 --- a/testdata/d2ir/TestCompile/field/array.exp.json +++ b/testdata/d2ir/TestCompile/field/array.exp.json @@ -1,40 +1,104 @@ { - "fields": [ - { - "name": "x", - "composite": { - "values": [ - { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:4:4-0:5:5", - "raw": "1", - "value": "1" - } + "ast": { + "range": "TestCompile/field/array.d2,0:0:0-0:12:12", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/array.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/field/array.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/array.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] }, - { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:6:6-0:7:7", - "raw": "2", - "value": "2" - } - }, - { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:8:8-0:9:9", - "raw": "3", - "value": "3" - } - }, - { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:10:10-0:11:11", - "raw": "4", - "value": "4" + "primary": {}, + "value": { + "array": { + "range": "TestCompile/field/array.d2,0:3:3-0:11:11", + "nodes": [ + { + "number": { + "range": "TestCompile/field/array.d2,0:4:4-0:5:5", + "raw": "1", + "value": "1" + } + }, + { + "number": { + "range": "TestCompile/field/array.d2,0:6:6-0:7:7", + "raw": "2", + "value": "2" + } + }, + { + "number": { + "range": "TestCompile/field/array.d2,0:8:8-0:9:9", + "raw": "3", + "value": "3" + } + }, + { + "number": { + "range": "TestCompile/field/array.d2,0:10:10-0:11:11", + "raw": "4", + "value": "4" + } + } + ] } } - ] + } } - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "composite": { + "values": [ + { + "value": { + "range": "TestCompile/field/array.d2,0:4:4-0:5:5", + "raw": "1", + "value": "1" + } + }, + { + "value": { + "range": "TestCompile/field/array.d2,0:6:6-0:7:7", + "raw": "2", + "value": "2" + } + }, + { + "value": { + "range": "TestCompile/field/array.d2,0:8:8-0:9:9", + "raw": "3", + "value": "3" + } + }, + { + "value": { + "range": "TestCompile/field/array.d2,0:10:10-0:11:11", + "raw": "4", + "value": "4" + } + } + ] + } + } + ], + "edges": null + } } diff --git a/testdata/d2ir/TestCompile/field/label.exp.json b/testdata/d2ir/TestCompile/field/label.exp.json index 9378defd0..86d9d7079 100644 --- a/testdata/d2ir/TestCompile/field/label.exp.json +++ b/testdata/d2ir/TestCompile/field/label.exp.json @@ -1,19 +1,59 @@ { - "fields": [ - { - "name": "x", - "primary": { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/label.d2,0:3:3-0:6:6", - "value": [ - { - "string": "yes", - "raw_string": "yes" + "ast": { + "range": "TestCompile/field/label.d2,0:0:0-0:6:6", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/label.d2,0:0:0-0:6:6", + "key": { + "range": "TestCompile/field/label.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/label.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/field/label.d2,0:3:3-0:6:6", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] } - ] + } } } - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "primary": { + "value": { + "range": "TestCompile/field/label.d2,0:3:3-0:6:6", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + ], + "edges": null + } } diff --git a/testdata/d2ir/TestCompile/field/nested.exp.json b/testdata/d2ir/TestCompile/field/nested.exp.json index 638232665..3c77060e2 100644 --- a/testdata/d2ir/TestCompile/field/nested.exp.json +++ b/testdata/d2ir/TestCompile/field/nested.exp.json @@ -1,27 +1,78 @@ { - "fields": [ - { - "name": "x", - "composite": { - "fields": [ - { - "name": "y", - "primary": { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/nested.d2,0:5:5-0:8:8", - "value": [ - { - "string": "yes", - "raw_string": "yes" - } - ] + "ast": { + "range": "TestCompile/field/nested.d2,0:0:0-0:8:8", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/nested.d2,0:0:0-0:8:8", + "key": { + "range": "TestCompile/field/nested.d2,0:0:0-0:3:3", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/nested.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/field/nested.d2,0:2:2-0:3:3", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/field/nested.d2,0:5:5-0:8:8", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] } } - ], - "edges": null + } } - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "composite": { + "fields": [ + { + "name": "y", + "primary": { + "value": { + "range": "TestCompile/field/nested.d2,0:5:5-0:8:8", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + ], + "edges": null + } + } + ], + "edges": null + } } diff --git a/testdata/d2ir/TestCompile/field/primary/nested.exp.json b/testdata/d2ir/TestCompile/field/primary/nested.exp.json index 79063ae09..870609c5d 100644 --- a/testdata/d2ir/TestCompile/field/primary/nested.exp.json +++ b/testdata/d2ir/TestCompile/field/primary/nested.exp.json @@ -1,35 +1,115 @@ { - "fields": [ - { - "name": "x", - "composite": { - "fields": [ - { - "name": "y", - "primary": { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/primary/nested.d2,0:5:5-0:8:8", - "value": [ - { - "string": "yes", - "raw_string": "yes" - } - ] - } - }, - "composite": { - "fields": [ - { - "name": "pqrs" + "ast": { + "range": "TestCompile/field/primary/nested.d2,0:0:0-0:17:17", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/primary/nested.d2,0:0:0-0:17:17", + "key": { + "range": "TestCompile/field/primary/nested.d2,0:0:0-0:3:3", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/primary/nested.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] } - ], - "edges": null + }, + { + "unquoted_string": { + "range": "TestCompile/field/primary/nested.d2,0:2:2-0:3:3", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "TestCompile/field/primary/nested.d2,0:5:5-0:8:8", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "value": { + "map": { + "range": "TestCompile/field/primary/nested.d2,0:9:9-0:16:16", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/primary/nested.d2,0:11:11-0:16:16", + "key": { + "range": "TestCompile/field/primary/nested.d2,0:11:11-0:16:16", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/primary/nested.d2,0:11:11-0:15:15", + "value": [ + { + "string": "pqrs", + "raw_string": "pqrs" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] } } - ], - "edges": null + } } - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "composite": { + "fields": [ + { + "name": "y", + "primary": { + "value": { + "range": "TestCompile/field/primary/nested.d2,0:5:5-0:8:8", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "composite": { + "fields": [ + { + "name": "pqrs" + } + ], + "edges": null + } + } + ], + "edges": null + } + } + ], + "edges": null + } } diff --git a/testdata/d2ir/TestCompile/field/primary/root.exp.json b/testdata/d2ir/TestCompile/field/primary/root.exp.json index cd2bb026c..69c46b633 100644 --- a/testdata/d2ir/TestCompile/field/primary/root.exp.json +++ b/testdata/d2ir/TestCompile/field/primary/root.exp.json @@ -1,27 +1,96 @@ { - "fields": [ - { - "name": "x", - "primary": { - "value": { - "range": "d2/testdata/d2ir/TestCompile/field/primary/root.d2,0:3:3-0:6:6", - "value": [ - { - "string": "yes", - "raw_string": "yes" + "ast": { + "range": "TestCompile/field/primary/root.d2,0:0:0-0:15:15", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/primary/root.d2,0:0:0-0:15:15", + "key": { + "range": "TestCompile/field/primary/root.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/primary/root.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "TestCompile/field/primary/root.d2,0:3:3-0:6:6", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "value": { + "map": { + "range": "TestCompile/field/primary/root.d2,0:7:7-0:14:14", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/primary/root.d2,0:9:9-0:14:14", + "key": { + "range": "TestCompile/field/primary/root.d2,0:9:9-0:14:14", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/primary/root.d2,0:9:9-0:13:13", + "value": [ + { + "string": "pqrs", + "raw_string": "pqrs" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] } - ] - } - }, - "composite": { - "fields": [ - { - "name": "pqrs" } - ], - "edges": null + } } - } - ], - "edges": null + ] + }, + "base": { + "fields": [ + { + "name": "x", + "primary": { + "value": { + "range": "TestCompile/field/primary/root.d2,0:3:3-0:6:6", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "composite": { + "fields": [ + { + "name": "pqrs" + } + ], + "edges": null + } + } + ], + "edges": null + } } diff --git a/testdata/d2ir/TestCompile/field/root.exp.json b/testdata/d2ir/TestCompile/field/root.exp.json index 2dcf9ab44..c4ef7e3f4 100644 --- a/testdata/d2ir/TestCompile/field/root.exp.json +++ b/testdata/d2ir/TestCompile/field/root.exp.json @@ -1,8 +1,38 @@ { - "fields": [ - { - "name": "x" - } - ], - "edges": null + "ast": { + "range": "TestCompile/field/root.d2,0:0:0-0:1:1", + "nodes": [ + { + "map_key": { + "range": "TestCompile/field/root.d2,0:0:0-0:1:1", + "key": { + "range": "TestCompile/field/root.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/field/root.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "base": { + "fields": [ + { + "name": "x" + } + ], + "edges": null + } }