Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vars #1473

Merged
merged 40 commits into from
Jul 13, 2023
Merged

Vars #1473

Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c9793b9
label works
alixander Jul 11, 2023
05802ed
edge label working
alixander Jul 11, 2023
fd70b5e
layers work
alixander Jul 11, 2023
7269ee1
add overlay tests
alixander Jul 11, 2023
acdbfdd
add replace tests
alixander Jul 11, 2023
0347dff
more tests
alixander Jul 11, 2023
08cc907
more test
alixander Jul 11, 2023
e7e2566
save
alixander Jul 11, 2023
090d10e
handle interpolation
alixander Jul 11, 2023
741a9aa
cleanup
alixander Jul 11, 2023
b193b9b
cleanup
alixander Jul 11, 2023
22bd50a
tests
alixander Jul 11, 2023
78e9e45
only coalesce if subbed
alixander Jul 11, 2023
a6125c4
cleanup
alixander Jul 11, 2023
85cf491
quotes
alixander Jul 11, 2023
4a9327e
non-root err check
alixander Jul 11, 2023
92d87b5
new implementation
alixander Jul 12, 2023
af69e6f
edge cases
alixander Jul 12, 2023
5d4d9c5
import tests
alixander Jul 12, 2023
67a06b6
var-in-var
alixander Jul 12, 2023
7091c58
changelog
alixander Jul 12, 2023
63dbaf0
pr changes
alixander Jul 12, 2023
d06e395
overlayVars refactor
alixander Jul 12, 2023
85bfad1
compile composites
alixander Jul 12, 2023
4b7b636
spread
alixander Jul 12, 2023
98f79e2
arrays
alixander Jul 13, 2023
301bc8d
add precedent test
alixander Jul 13, 2023
ef11d47
null
alixander Jul 13, 2023
06ed41e
remove dead code
alixander Jul 13, 2023
ffdb512
err msg
alixander Jul 13, 2023
780345b
fix double quote primary
alixander Jul 13, 2023
eba41af
use scalarstring
alixander Jul 13, 2023
a54907e
remove overlayVars
alixander Jul 13, 2023
fb0c0d2
nested null
alixander Jul 13, 2023
4847714
fix compiler creating vars
alixander Jul 13, 2023
29af923
fix no-primary-composite
alixander Jul 13, 2023
f12f9ca
move edge check
alixander Jul 13, 2023
e95f619
fix import test
alixander Jul 13, 2023
d275a45
allow edges in vars
alixander Jul 13, 2023
da0d245
rm commented code
alixander Jul 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 87 additions & 1 deletion d2compiler/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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`)
},
},
{
Expand Down
63 changes: 48 additions & 15 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
alixander marked this conversation as resolved.
Show resolved Hide resolved
// don't resolve substitutions in vars with the current scope of vars
if f.Name == "vars" {
Expand Down Expand Up @@ -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")
alixander marked this conversation as resolved.
Show resolved Hide resolved
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)
nhooyr marked this conversation as resolved.
Show resolved Hide resolved
for i, f2 := range m.Fields {
if n == f2 {
m.Fields = append(m.Fields[:i], m.Fields[i+1:]...)
break
}
}
}
}
Expand All @@ -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(), "."))
alixander marked this conversation as resolved.
Show resolved Hide resolved
return
}
switch n := node.(type) {
alixander marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down Expand Up @@ -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
alixander marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion d2parser/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
nhooyr marked this conversation as resolved.
Show resolved Hide resolved
p.errorf(p.pos, p.pos.Advance(r, p.utf16), "unquoted strings cannot start on %q", r)
}
box.Null = vbox.Null
Expand Down
Loading