Skip to content

Commit

Permalink
edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
alixander committed Jul 12, 2023
1 parent 92d87b5 commit af69e6f
Show file tree
Hide file tree
Showing 5 changed files with 769 additions and 12 deletions.
45 changes: 45 additions & 0 deletions d2compiler/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3290,6 +3290,21 @@ a -> b: ${x}
assert.Equal(t, "im a var", g.Edges[0].Label.Value)
},
},
{
name: "edge-map",
run: func(t *testing.T) {
g := assertCompile(t, `
vars: {
x: im a var
}
a -> b: {
target-arrowhead.label: ${x}
}
`, "")
assert.Equal(t, 1, len(g.Edges))
assert.Equal(t, "im a var", g.Edges[0].DstArrowhead.Label.Value)
},
},
{
name: "quoted-var",
run: func(t *testing.T) {
Expand Down Expand Up @@ -3325,6 +3340,23 @@ y: "hey ${x}"
assert.Equal(t, `hey "hi"`, g.Objects[0].Label.Value)
},
},
{
name: "parent-scope",
run: func(t *testing.T) {
g := assertCompile(t, `
vars: {
x: im root var
}
a: {
vars: {
b: im nested var
}
hi: ${x}
}
`, "")
assert.Equal(t, "im root var", g.Objects[1].Label.Value)
},
},
}

for _, tc := range tca {
Expand Down Expand Up @@ -3538,6 +3570,19 @@ hi: ${x.z}
`, `d2/testdata/d2compiler/TestCompile2/vars/errors/nested-missing.d2:7:1: could not resolve variable "x.z"`)
},
},
{
name: "out-of-scope",
run: func(t *testing.T) {
assertCompile(t, `
a: {
vars: {
x: hey
}
}
hi: ${x}
`, `d2/testdata/d2compiler/TestCompile2/vars/errors/out-of-scope.d2:7:1: could not resolve variable "x"`)
},
},
{
name: "edge",
run: func(t *testing.T) {
Expand Down
46 changes: 34 additions & 12 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,41 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) {
if e.Primary() != nil {
c.resolveSubstitutions(varsStack, e.LastRef().AST(), e.Primary())
}
if e.Map() != nil {
c.compileSubstitutions(e.Map(), varsStack)
}
}
}

func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scalar *Scalar) {
subbed := false
var subbed bool
var resolvedField *Field

switch s := scalar.Value.(type) {
case *d2ast.UnquotedString:
for i, box := range s.Value {
if box.Substitution != nil {
resolvedField := c.resolveSubstitution(varsStack[0], node, box.Substitution)
for _, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, box.Substitution)
if resolvedField != nil {
break
}
}
if resolvedField != nil {
if resolvedField.Composite != nil {
c.errorf(node, `cannot reference map variable "%s"`, strings.Join(box.Substitution.IDA(), "."))
return
}
// If lone and unquoted, replace with value of sub
if len(s.Value) == 1 {
scalar.Value = resolvedField.Primary().Value
} else {
s.Value[i].String = go2.Pointer(resolvedField.Primary().String())
subbed = true
}
} else {
c.errorf(node, `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), "."))
return
}
}
}
Expand All @@ -141,10 +158,22 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scala
case *d2ast.DoubleQuotedString:
for i, box := range s.Value {
if box.Substitution != nil {
resolvedField := c.resolveSubstitution(varsStack[0], node, box.Substitution)
for _, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, box.Substitution)
if resolvedField != nil {
break
}
}
if resolvedField != nil {
if resolvedField.Composite != nil {
c.errorf(node, `cannot reference map variable "%s"`, strings.Join(box.Substitution.IDA(), "."))
return
}
s.Value[i].String = go2.Pointer(resolvedField.Primary().String())
subbed = true
} else {
c.errorf(node, `could not resolve variable "%s"`, strings.Join(box.Substitution.IDA(), "."))
return
}
}
}
Expand All @@ -154,7 +183,7 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node d2ast.Node, scala
}
}

func (c *compiler) resolveSubstitution(vars *Map, node d2ast.Node, substitution *d2ast.Substitution) *Field {
func (c *compiler) resolveSubstitution(vars *Map, substitution *d2ast.Substitution) *Field {
var resolved *Field
for _, p := range substitution.Path {
if vars == nil {
Expand All @@ -170,14 +199,7 @@ func (c *compiler) resolveSubstitution(vars *Map, node d2ast.Node, substitution
resolved = r
}

if resolved == nil {
c.errorf(node, `could not resolve variable "%s"`, strings.Join(substitution.IDA(), "."))
} else if resolved.Composite != nil {
c.errorf(node, `cannot reference map variable "%s"`, strings.Join(substitution.IDA(), "."))
} else {
return resolved
}
return nil
return resolved
}

func (c *compiler) overlayVars(base, overlay *Map) {
Expand Down
Loading

0 comments on commit af69e6f

Please sign in to comment.