Skip to content

Commit

Permalink
d2ir: use current var stack
Browse files Browse the repository at this point in the history
  • Loading branch information
alixander committed Aug 6, 2024
1 parent 9201649 commit e1239ed
Show file tree
Hide file tree
Showing 5 changed files with 1,078 additions and 20 deletions.
2 changes: 2 additions & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#### Features 🚀

- Variables definitions can now refer to other variables in the current scope [#TODO](https://github.com/terrastruct/d2/pull/TODO)

#### Improvements 🧹

- Sequence diagram edge groups account for edge label heights [#2038](https://github.com/terrastruct/d2/pull/2038)
Expand Down
26 changes: 26 additions & 0 deletions d2compiler/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2763,6 +2763,29 @@ x*: {
tassert.Equal(t, "x2", g.Objects[3].AbsID())
},
},
{
name: "var_in_vars",
text: `vars: {
Apple: {
shape:circle
label:Granny Smith
}
Cherry: {
shape:circle
label:Rainier Cherry
}
SummerFruit: {
xx: ${Apple}
cc: ${Cherry}
xx -> cc
}
}
x: ${Apple}
c: ${Cherry}
sf: ${SummerFruit}
`,
},
{
name: "class-shape-class",
text: `classes: {
Expand Down Expand Up @@ -4071,11 +4094,14 @@ vars: {
hi: {
vars: {
x: ${x}-b
b: ${x}
}
yo: ${x}
hey: ${b}
}
`, "")
assert.Equal(t, "a-b", g.Objects[1].Label.Value)
assert.Equal(t, "a-b", g.Objects[2].Label.Value)
},
},
{
Expand Down
35 changes: 28 additions & 7 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,8 @@ func (c *compiler) compileSubstitutions(m *Map, varsStack []*Map) {
}
}
} else if f.Map() != nil {
// don't resolve substitutions in vars with the current scope of vars
if f.Name == "vars" {
c.compileSubstitutions(f.Map(), varsStack[1:])
c.compileSubstitutions(f.Map(), varsStack)
c.validateConfigs(f.Map().GetField("d2-config"))
} else {
c.compileSubstitutions(f.Map(), varsStack)
Expand Down Expand Up @@ -227,8 +226,8 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie
case *d2ast.UnquotedString:
for i, box := range s.Value {
if box.Substitution != nil {
for _, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, box.Substitution)
for i, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, node, box.Substitution, i == 0)
if resolvedField != nil {
if resolvedField.Primary() != nil {
if _, ok := resolvedField.Primary().Value.(*d2ast.Null); ok {
Expand Down Expand Up @@ -319,8 +318,8 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie
case *d2ast.DoubleQuotedString:
for i, box := range s.Value {
if box.Substitution != nil {
for _, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, box.Substitution)
for i, vars := range varsStack {
resolvedField = c.resolveSubstitution(vars, node, box.Substitution, i == 0)
if resolvedField != nil {
break
}
Expand All @@ -344,16 +343,38 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie
return removedField
}

func (c *compiler) resolveSubstitution(vars *Map, substitution *d2ast.Substitution) *Field {
func (c *compiler) resolveSubstitution(vars *Map, node Node, substitution *d2ast.Substitution, isCurrentScopeVars bool) *Field {
if vars == nil {
return nil
}

fieldNode, fok := node.(*Field)
parent := ParentField(node)

for i, p := range substitution.Path {
f := vars.GetField(p.Unbox().ScalarString())
if f == nil {
return nil
}
// Consider this case:
//
// ```
// vars: {
// x: a
// }
// hi: {
// vars: {
// x: ${x}-b
// }
// yo: ${x}
// }
// ```
//
// When resolving hi.vars.x, the vars stack includes itself.
// So this next if clause says, "ignore if we're using the current scope's vars to try to resolve a substitution that requires a var from further in the stack"
if fok && fieldNode.Name == p.Unbox().ScalarString() && isCurrentScopeVars && parent.Name == "vars" {
return nil
}

if i == len(substitution.Path)-1 {
return f
Expand Down
Loading

0 comments on commit e1239ed

Please sign in to comment.