d2ir: Handle imported scenarios/steps/links

This commit is contained in:
Anmol Sethi 2023-06-06 16:49:12 -07:00
parent a5d3cc1429
commit 7f0450121a
No known key found for this signature in database
GPG key ID: 8CEF1878FF10ADEB
3 changed files with 296 additions and 3 deletions

View file

@ -124,6 +124,15 @@ func (c *compiler) compileMap(dst *Map, ast *d2ast.Map) {
continue
}
OverlayMap(dst, impn.Map())
if impnf, ok := impn.(*Field); ok {
if impnf.Primary_ != nil {
dstf := ParentField(dst)
if dstf != nil {
dstf.Primary_ = impnf.Primary_
}
}
}
case n.Substitution != nil:
panic("TODO")
}
@ -192,13 +201,47 @@ func (c *compiler) compileField(dst *Map, kp *d2ast.KeyPath, refctx *RefContext)
switch n := n.(type) {
case *Field:
if n.Primary_ != nil {
f.Primary_ = n.Primary_.Copy(f).(*Scalar)
refctx2 := refctx.Copy()
key2 := *refctx.Key
refctx.Key = &key2
refctx2.Key.Value = d2ast.MakeValueBox(n.Primary_.Value)
// If the link is a board, we need to transform it into an absolute path.
if f.Name == "link" {
c.compileLink(refctx2)
}
f.Primary_ = &Scalar{
parent: f,
Value: refctx2.Key.Value.ScalarBox().Unbox(),
}
}
if n.Composite != nil {
f.Composite = n.Composite.Copy(f).(Composite)
}
case *Map:
f.Composite = n.Copy(f).(Composite)
f.Composite = &Map{
parent: f,
}
switch NodeBoardKind(f) {
case BoardScenario:
c.overlay(ParentBoard(f).Map(), f)
case BoardStep:
stepsMap := ParentMap(f)
for i := range stepsMap.Fields {
if stepsMap.Fields[i] == f {
if i == 0 {
c.overlay(ParentBoard(f).Map(), f)
} else {
c.overlay(stepsMap.Fields[i-1].Map(), f)
}
break
}
}
}
OverlayMap(f.Map(), n)
switch NodeBoardKind(f) {
case BoardScenario, BoardStep:
c.compileClasses(f.Map())
}
}
} else if refctx.Key.Value.ScalarBox().Unbox() != nil {
// If the link is a board, we need to transform it into an absolute path.
@ -408,7 +451,7 @@ func (c *compiler) compileArray(dst *Array, a *d2ast.Array) {
}
case *Map:
if v.Spread {
c.errorf(v, "cannot spread import map into array")
c.errorf(v, "can only spread import array into array")
continue
}
irv = n

View file

@ -96,6 +96,20 @@ label: meow`,
assertQuery(t, m, 0, 0, nil, "jon")
},
},
{
name: "nested/spread_primary",
run: func(t testing.TB) {
m, err := compileFS(t, "index.d2", map[string]string{
"index.d2": "q: { ...@x.y }",
"x.d2": "y: meow { jon; jan }",
})
assert.Success(t, err)
assertQuery(t, m, 3, 0, nil, "")
assertQuery(t, m, 2, 0, "meow", "q")
assertQuery(t, m, 0, 0, nil, "q.jan")
assertQuery(t, m, 0, 0, nil, "q.jon")
},
},
}
runa(t, tca)
@ -156,6 +170,16 @@ x.d2:1:7: connection missing source`)
assert.ErrorString(t, err, `q.d2:1:1: detected cyclic import chain: x -> y -> q -> x`)
},
},
{
name: "spread_non_map",
run: func(t testing.TB) {
_, err := compileFS(t, "index.d2", map[string]string{
"index.d2": "...@x.y",
"x.d2": "y: meow",
})
assert.ErrorString(t, err, `index.d2:1:1: cannot spread import non map into map`)
},
},
}
runa(t, tca)
})

View file

@ -0,0 +1,226 @@
{
"fields": [
{
"name": "q",
"primary": {
"value": {
"range": "x.d2,0:3:3-0:7:7",
"value": [
{
"string": "meow",
"raw_string": "meow"
}
]
}
},
"composite": {
"fields": [
{
"name": "jon",
"references": [
{
"string": {
"range": "x.d2,0:10:10-0:13:13",
"value": [
{
"string": "jon",
"raw_string": "jon"
}
]
},
"key_path": {
"range": "x.d2,0:10:10-0:13:13",
"path": [
{
"unquoted_string": {
"range": "x.d2,0:10:10-0:13:13",
"value": [
{
"string": "jon",
"raw_string": "jon"
}
]
}
}
]
},
"context": {
"edge": null,
"key": {
"range": "x.d2,0:10:10-0:13:13",
"key": {
"range": "x.d2,0:10:10-0:13:13",
"path": [
{
"unquoted_string": {
"range": "x.d2,0:10:10-0:13:13",
"value": [
{
"string": "jon",
"raw_string": "jon"
}
]
}
}
]
},
"primary": {},
"value": {}
}
}
}
]
},
{
"name": "jan",
"references": [
{
"string": {
"range": "x.d2,0:15:15-0:18:18",
"value": [
{
"string": "jan",
"raw_string": "jan"
}
]
},
"key_path": {
"range": "x.d2,0:15:15-0:18:18",
"path": [
{
"unquoted_string": {
"range": "x.d2,0:15:15-0:18:18",
"value": [
{
"string": "jan",
"raw_string": "jan"
}
]
}
}
]
},
"context": {
"edge": null,
"key": {
"range": "x.d2,0:15:15-0:19:19",
"key": {
"range": "x.d2,0:15:15-0:18:18",
"path": [
{
"unquoted_string": {
"range": "x.d2,0:15:15-0:18:18",
"value": [
{
"string": "jan",
"raw_string": "jan"
}
]
}
}
]
},
"primary": {},
"value": {}
}
}
}
]
}
],
"edges": null
},
"references": [
{
"string": {
"range": "index.d2,0:0:0-0:1:1",
"value": [
{
"string": "q",
"raw_string": "q"
}
]
},
"key_path": {
"range": "index.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "index.d2,0:0:0-0:1:1",
"value": [
{
"string": "q",
"raw_string": "q"
}
]
}
}
]
},
"context": {
"edge": null,
"key": {
"range": "index.d2,0:0:0-0:14:14",
"key": {
"range": "index.d2,0:0:0-0:1:1",
"path": [
{
"unquoted_string": {
"range": "index.d2,0:0:0-0:1:1",
"value": [
{
"string": "q",
"raw_string": "q"
}
]
}
}
]
},
"primary": {},
"value": {
"map": {
"range": "index.d2,0:3:3-0:14:14",
"nodes": [
{
"import": {
"range": "index.d2,0:5:5-0:13:13",
"spread": true,
"pre": "",
"path": [
{
"unquoted_string": {
"range": "index.d2,0:9:9-0:10:10",
"value": [
{
"string": "x",
"raw_string": "x"
}
]
}
},
{
"unquoted_string": {
"range": "index.d2,0:11:11-0:12:12",
"value": [
{
"string": "y",
"raw_string": "y"
}
]
}
}
]
}
}
]
}
}
}
}
}
]
}
],
"edges": null
}