d2ir: IR Root wip

This commit is contained in:
Anmol Sethi 2023-01-17 17:39:31 -08:00
parent f69f401d23
commit f7394133b9
No known key found for this signature in database
GPG key ID: 25BC68888A99A8BA
13 changed files with 939 additions and 357 deletions

View file

@ -21,13 +21,22 @@ func (c *compiler) errorf(n d2ast.Node, f string, v ...interface{}) {
}) })
} }
func Compile(dst *Map, ast *d2ast.Map) error { func Compile(ast *d2ast.Map) (*IR, error) {
var c compiler ir := &IR{
c.compileMap(dst, ast) AST: ast,
if !c.err.Empty() { Map: &Map{},
return c.err
} }
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) { func (c *compiler) compileMap(dst *Map, ast *d2ast.Map) {

View file

@ -24,7 +24,7 @@ func TestCompile(t *testing.T) {
type testCase struct { type testCase struct {
name string name string
run func(testing.TB, *d2ir.Map) run func(testing.TB)
} }
func runa(t *testing.T, tca []testCase) { func runa(t *testing.T, tca []testCase) {
@ -32,50 +32,38 @@ func runa(t *testing.T, tca []testCase) {
tc := tc tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
m := &d2ir.Map{} tc.run(t)
tc.run(t, m)
}) })
} }
} }
func parse(t testing.TB, dst *d2ir.Map, text string) error { func compile(t testing.TB, text string) (*d2ir.IR, error) {
t.Helper() 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) ast, err := d2parser.Parse(d2Path, strings.NewReader(text), nil)
assert.Success(t, err) assert.Success(t, err)
err = d2ir.Compile(dst, ast) ir, err := d2ir.Compile(ast)
if err != nil { if err != nil {
return err return nil, err
} }
err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), dst) err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), ir)
return err 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 { func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interface{}, ida ...string) *d2ir.Field {
t.Helper() t.Helper()
var m *d2ir.Map m := d2ir.ToMap(n)
p := &d2ir.Scalar{ if m == nil {
Value: &d2ast.Null{}, t.Fatalf("nil m from %T", n)
}
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)
} }
p := d2ir.ToScalar(n)
var f *d2ir.Field var f *d2ir.Field
if len(ida) > 0 { 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) t.Fatalf("expected field %v in map %s", ida, m)
} }
p = f.Primary p = f.Primary
if f_m, ok := f.Composite.(*d2ir.Map); ok { m = d2ir.ToMap(f)
m = f_m
} else {
m = &d2ir.Map{}
}
} }
assert.Equal(t, nfields, m.FieldCountRecursive()) 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] eid := d2ir.NewEdgeIDs(k)[0]
var m *d2ir.Map m := d2ir.ToMap(n)
switch n := n.(type) { if m == nil {
case *d2ir.Field: t.Fatalf("nil m from %T", n)
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)
} }
ea := m.GetEdges(eid) ea := m.GetEdges(eid)
@ -177,43 +151,43 @@ func testCompileField(t *testing.T) {
tca := []testCase{ tca := []testCase{
{ {
name: "root", name: "root",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x`) ir, err := compile(t, `x`)
assert.Success(t, err) 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", name: "label",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x: yes`) ir, err := compile(t, `x: yes`)
assert.Success(t, err) 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", name: "nested",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x.y: yes`) ir, err := compile(t, `x.y: yes`)
assert.Success(t, err) 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, ir, 1, 0, nil, "x")
assertField(t, m, 0, 0, "yes", "x", "y") assertField(t, ir, 0, 0, "yes", "x", "y")
}, },
}, },
{ {
name: "array", name: "array",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x: [1;2;3;4]`) ir, err := compile(t, `x: [1;2;3;4]`)
assert.Success(t, err) 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()) assert.String(t, `[1; 2; 3; 4]`, f.Composite.String())
}, },
}, },
@ -226,25 +200,25 @@ func testCompileFieldPrimary(t *testing.T) {
tca := []testCase{ tca := []testCase{
{ {
name: "root", name: "root",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x: yes { pqrs }`) ir, err := compile(t, `x: yes { pqrs }`)
assert.Success(t, err) 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, ir, 1, 0, "yes", "x")
assertField(t, m, 0, 0, nil, "x", "pqrs") assertField(t, ir, 0, 0, nil, "x", "pqrs")
}, },
}, },
{ {
name: "nested", name: "nested",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x.y: yes { pqrs }`) ir, err := compile(t, `x.y: yes { pqrs }`)
assert.Success(t, err) 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, ir, 2, 0, nil, "x")
assertField(t, m, 1, 0, "yes", "x", "y") assertField(t, ir, 1, 0, "yes", "x", "y")
assertField(t, m, 0, 0, nil, "x", "y", "pqrs") assertField(t, ir, 0, 0, nil, "x", "y", "pqrs")
}, },
}, },
} }
@ -256,43 +230,43 @@ func testCompileEdge(t *testing.T) {
tca := []testCase{ tca := []testCase{
{ {
name: "root", name: "root",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x -> y`) ir, err := compile(t, `x -> y`)
assert.Success(t, err) assert.Success(t, err)
assertField(t, m, 2, 1, nil) assertField(t, ir, 2, 1, nil)
assertEdge(t, m, 0, nil, `(x -> y)[0]`) assertEdge(t, ir, 0, nil, `(x -> y)[0]`)
assertField(t, m, 0, 0, nil, "x") assertField(t, ir, 0, 0, nil, "x")
assertField(t, m, 0, 0, nil, "y") assertField(t, ir, 0, 0, nil, "y")
}, },
}, },
{ {
name: "nested", name: "nested",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `x.y -> z.p`) ir, err := compile(t, `x.y -> z.p`)
assert.Success(t, err) 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, ir, 1, 0, nil, "x")
assertField(t, m, 0, 0, nil, "x", "y") assertField(t, ir, 0, 0, nil, "x", "y")
assertField(t, m, 1, 0, nil, "z") assertField(t, ir, 1, 0, nil, "z")
assertField(t, m, 0, 0, nil, "z", "p") 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", name: "underscore",
run: func(t testing.TB, m *d2ir.Map) { run: func(t testing.TB) {
err := parse(t, m, `p: { _.x -> z }`) ir, err := compile(t, `p: { _.x -> z }`)
assert.Success(t, err) 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, ir, 0, 0, nil, "x")
assertField(t, m, 1, 0, nil, "p") 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]")
}, },
}, },
} }

View file

@ -13,13 +13,14 @@ import (
type Node interface { type Node interface {
node() node()
ast() d2ast.Node Copy(parent Node) Node
Parent() Node Parent() Node
Copy(newp Node) Node
ast() d2ast.Node
fmt.Stringer fmt.Stringer
} }
var _ Node = &IR{}
var _ Node = &Scalar{} var _ Node = &Scalar{}
var _ Node = &Field{} var _ Node = &Field{}
var _ Node = &Edge{} var _ Node = &Edge{}
@ -44,12 +45,14 @@ type Composite interface {
var _ Composite = &Array{} var _ Composite = &Array{}
var _ Composite = &Map{} var _ Composite = &Map{}
func (n *IR) node() {}
func (n *Scalar) node() {} func (n *Scalar) node() {}
func (n *Field) node() {} func (n *Field) node() {}
func (n *Edge) node() {} func (n *Edge) node() {}
func (n *Array) node() {} func (n *Array) node() {}
func (n *Map) node() {} func (n *Map) node() {}
func (n *IR) Parent() Node { return n.parent }
func (n *Scalar) Parent() Node { return n.parent } func (n *Scalar) Parent() Node { return n.parent }
func (n *Field) Parent() Node { return n.parent } func (n *Field) Parent() Node { return n.parent }
func (n *Edge) 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 *Scalar) value() {}
func (n *Array) value() {} func (n *Array) value() {}
func (n *Map) value() {} func (n *Map) value() {}
func (n *IR) value() {}
func (n *Array) composite() {} func (n *Array) composite() {}
func (n *Map) 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 *Scalar) String() string { return d2format.Format(n.ast()) }
func (n *Field) 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 *Edge) String() string { return d2format.Format(n.ast()) }
func (n *Array) 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()) } 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 { type Scalar struct {
parent Node parent Node
Value d2ast.Scalar `json:"value"` 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. // Root reports whether the Map is the root of the D2 tree.
// The root map has no parent.
func (m *Map) Root() bool { func (m *Map) Root() bool {
return m.parent == nil _, ok := m.parent.(*IR)
return ok
} }
type Field struct { type Field struct {
@ -222,16 +244,16 @@ func (eid *EdgeID) resolveUnderscores(m *Map) (*EdgeID, *Map, error) {
if eid.SrcPath[0] == "_" { if eid.SrcPath[0] == "_" {
eid.SrcPath = eid.SrcPath[1:] eid.SrcPath = eid.SrcPath[1:]
} else { } else {
mf := parentField(m) mf := ParentField(m)
eid.SrcPath = append([]string{mf.Name}, eid.SrcPath...) eid.SrcPath = append([]string{mf.Name}, eid.SrcPath...)
} }
if eid.DstPath[0] == "_" { if eid.DstPath[0] == "_" {
eid.DstPath = eid.DstPath[1:] eid.DstPath = eid.DstPath[1:]
} else { } else {
mf := parentField(m) mf := ParentField(m)
eid.DstPath = append([]string{mf.Name}, eid.DstPath...) eid.DstPath = append([]string{mf.Name}, eid.DstPath...)
} }
m = parentMap(m) m = ParentMap(m)
if m == nil { if m == nil {
return nil, nil, errors.New("invalid underscore") return nil, nil, errors.New("invalid underscore")
} }
@ -327,12 +349,29 @@ type RefContext struct {
Key *d2ast.Key Key *d2ast.Key
Edge *d2ast.Edge Edge *d2ast.Edge
Scope *d2ast.Map 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 { for i, e := range rc.Key.Edges {
if e == rc.Edge { if e == rc.Edge {
return i return i
@ -379,7 +418,7 @@ func (m *Map) EdgeCountRecursive() int {
func (m *Map) GetField(ida []string) *Field { func (m *Map) GetField(ida []string) *Field {
for len(ida) > 0 && ida[0] == "_" { for len(ida) > 0 && ida[0] == "_" {
m = parentMap(m) m = ParentMap(m)
if m == nil { if m == nil {
return nil return nil
} }
@ -415,7 +454,7 @@ func (m *Map) getField(ida []string) *Field {
func (m *Map) EnsureField(ida []string) (*Field, error) { func (m *Map) EnsureField(ida []string) (*Field, error) {
for len(ida) > 0 && ida[0] == "_" { for len(ida) > 0 && ida[0] == "_" {
m = parentMap(m) m = ParentMap(m)
if m == nil { if m == nil {
return nil, errors.New("invalid underscore") return nil, errors.New("invalid underscore")
} }
@ -469,7 +508,7 @@ func (m *Map) ensureField(ida []string) (*Field, error) {
return f.Composite.(*Map).ensureField(rest) return f.Composite.(*Map).ensureField(rest)
} }
func (m *Map) Delete(ida []string) bool { func (m *Map) DeleteField(ida []string) bool {
if len(ida) == 0 { if len(ida) == 0 {
return false return false
} }
@ -486,7 +525,7 @@ func (m *Map) Delete(ida []string) bool {
return true return true
} }
if f_m, ok := f.Composite.(*Map); ok { if f_m, ok := f.Composite.(*Map); ok {
return f_m.Delete(rest) return f_m.DeleteField(rest)
} }
} }
return false return false
@ -554,6 +593,10 @@ func (m *Map) EnsureEdge(eid *EdgeID) (*Edge, error) {
return e, nil return e, nil
} }
func (ir *IR) ast() d2ast.Node {
return ir.Map.ast()
}
func (s *Scalar) ast() d2ast.Node { func (s *Scalar) ast() d2ast.Node {
return s.Value return s.Value
} }
@ -619,7 +662,7 @@ func (m *Map) ast() d2ast.Node {
return nil return nil
} }
astMap := &d2ast.Map{} astMap := &d2ast.Map{}
if m.parent == nil { if m.Root() {
astMap.Range = d2ast.MakeRange(",0:0:0-1:0:0") astMap.Range = d2ast.MakeRange(",0:0:0-1:0:0")
} else { } else {
astMap.Range = d2ast.MakeRange(",1:0:0-2:0:0") 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) 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 { for n.Parent() != nil {
n = n.Parent() n = n.Parent()
if n_m, ok := n.(*Map); ok { if n_m, ok := n.(*Map); ok {
@ -671,7 +740,7 @@ func parentMap(n Node) *Map {
return nil return nil
} }
func parentField(n Node) *Field { func ParentField(n Node) *Field {
for n.Parent() != nil { for n.Parent() != nil {
n = n.Parent() n = n.Parent()
if n_f, ok := n.(*Field); ok { if n_f, ok := n.(*Field); ok {

View file

@ -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
}
}
]
}

View file

@ -1,4 +1,78 @@
{ {
"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": {}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
@ -40,4 +114,5 @@
} }
} }
] ]
}
} }

View file

@ -1,4 +1,56 @@
{ {
"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": [ "fields": [
{ {
"name": "x" "name": "x"
@ -22,4 +74,5 @@
} }
} }
] ]
}
} }

View file

@ -1,4 +1,96 @@
{ {
"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": {}
}
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "p", "name": "p",
@ -31,4 +123,5 @@
} }
} }
] ]
}
} }

View file

@ -1,4 +1,67 @@
{ {
"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"
}
]
}
}
]
},
"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"
}
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
@ -6,28 +69,28 @@
"values": [ "values": [
{ {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:4:4-0:5:5", "range": "TestCompile/field/array.d2,0:4:4-0:5:5",
"raw": "1", "raw": "1",
"value": "1" "value": "1"
} }
}, },
{ {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:6:6-0:7:7", "range": "TestCompile/field/array.d2,0:6:6-0:7:7",
"raw": "2", "raw": "2",
"value": "2" "value": "2"
} }
}, },
{ {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:8:8-0:9:9", "range": "TestCompile/field/array.d2,0:8:8-0:9:9",
"raw": "3", "raw": "3",
"value": "3" "value": "3"
} }
}, },
{ {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/array.d2,0:10:10-0:11:11", "range": "TestCompile/field/array.d2,0:10:10-0:11:11",
"raw": "4", "raw": "4",
"value": "4" "value": "4"
} }
@ -37,4 +100,5 @@
} }
], ],
"edges": null "edges": null
}
} }

View file

@ -1,10 +1,49 @@
{ {
"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"
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
"primary": { "primary": {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/label.d2,0:3:3-0:6:6", "range": "TestCompile/field/label.d2,0:3:3-0:6:6",
"value": [ "value": [
{ {
"string": "yes", "string": "yes",
@ -16,4 +55,5 @@
} }
], ],
"edges": null "edges": null
}
} }

View file

@ -1,4 +1,54 @@
{ {
"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"
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
@ -8,7 +58,7 @@
"name": "y", "name": "y",
"primary": { "primary": {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/nested.d2,0:5:5-0:8:8", "range": "TestCompile/field/nested.d2,0:5:5-0:8:8",
"value": [ "value": [
{ {
"string": "yes", "string": "yes",
@ -24,4 +74,5 @@
} }
], ],
"edges": null "edges": null
}
} }

View file

@ -1,4 +1,83 @@
{ {
"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"
}
]
}
},
{
"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": {}
}
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
@ -8,7 +87,7 @@
"name": "y", "name": "y",
"primary": { "primary": {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/primary/nested.d2,0:5:5-0:8:8", "range": "TestCompile/field/primary/nested.d2,0:5:5-0:8:8",
"value": [ "value": [
{ {
"string": "yes", "string": "yes",
@ -32,4 +111,5 @@
} }
], ],
"edges": null "edges": null
}
} }

View file

@ -1,10 +1,78 @@
{ {
"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": {}
}
}
]
}
}
}
}
]
},
"base": {
"fields": [ "fields": [
{ {
"name": "x", "name": "x",
"primary": { "primary": {
"value": { "value": {
"range": "d2/testdata/d2ir/TestCompile/field/primary/root.d2,0:3:3-0:6:6", "range": "TestCompile/field/primary/root.d2,0:3:3-0:6:6",
"value": [ "value": [
{ {
"string": "yes", "string": "yes",
@ -24,4 +92,5 @@
} }
], ],
"edges": null "edges": null
}
} }

View file

@ -1,8 +1,38 @@
{ {
"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": [ "fields": [
{ {
"name": "x" "name": "x"
} }
], ],
"edges": null "edges": null
}
} }