Skip to content

Commit

Permalink
d2ir: spread vars in place
Browse files Browse the repository at this point in the history
  • Loading branch information
alixander committed Aug 17, 2024
1 parent f9d1184 commit 0f53a83
Show file tree
Hide file tree
Showing 5 changed files with 1,384 additions and 2 deletions.
1 change: 1 addition & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
- Globs: An edge case was fixed where globs used in edges were creating nodes when it shouldn't have [#2051](https://github.com/terrastruct/d2/pull/2051)
- Render: Multi-line class labels/headers are rendered correctly [#2057](https://github.com/terrastruct/d2/pull/2057)
- CLI: Watch mode uses correct backlinks (`_` usages) [#2058](https://github.com/terrastruct/d2/pull/2058)
- Vars: Spread variables are inserted in place instead of appending to end of scope [#TODO](https://github.com/terrastruct/d2/pull/TODO)
4 changes: 2 additions & 2 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,11 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie
}
}
case *Field:
m := ParentMap(n)
if resolvedField.Map() != nil {
OverlayMap(ParentMap(n), resolvedField.Map())
ExpandSubstitution(m, resolvedField.Map(), n)
}
// Remove the placeholder field
m := n.parent.(*Map)
for i, f2 := range m.Fields {
if n == f2 {
m.Fields = append(m.Fields[:i], m.Fields[i+1:]...)
Expand Down
30 changes: 30 additions & 0 deletions d2ir/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestCompile(t *testing.T) {
t.Run("imports", testCompileImports)
t.Run("patterns", testCompilePatterns)
t.Run("filters", testCompileFilters)
t.Run("vars", testCompileVars)
}

type testCase struct {
Expand Down Expand Up @@ -698,3 +699,32 @@ layers: {
}
runa(t, tca)
}

func testCompileVars(t *testing.T) {
t.Parallel()
tca := []testCase{
{
name: "spread-in-place",
run: func(t testing.TB) {
m, err := compile(t, `vars: {
person-shape: {
grid-columns: 1
grid-rows: 2
grid-gap: 0
head
body
}
}
dora: {
...${person-shape}
body
}
`)
assert.Success(t, err)
assert.Equal(t, "grid-columns", m.Fields[1].Map().Fields[0].Name)
},
},
}
runa(t, tca)
}
33 changes: 33 additions & 0 deletions d2ir/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,39 @@ func OverlayMap(base, overlay *Map) {
}
}

func ExpandSubstitution(m, resolved *Map, placeholder *Field) {
fi := -1
for i := 0; i < len(m.Fields); i++ {
if m.Fields[i] == placeholder {
fi = i
break
}
}

for _, of := range resolved.Fields {
bf := m.GetField(of.Name)
if bf == nil {
m.Fields = append(append(m.Fields[:fi], of.Copy(m).(*Field)), m.Fields[fi:]...)
fi++
continue
}
OverlayField(bf, of)
}

// NOTE this doesn't expand edges in place, and just appends
// I suppose to do this, there needs to be an edge placeholder too on top of the field placeholder
// Will wait to see if a problem
for _, oe := range resolved.Edges {
bea := m.GetEdges(oe.ID, nil, nil)
if len(bea) == 0 {
m.Edges = append(m.Edges, oe.Copy(m).(*Edge))
continue
}
be := bea[0]
OverlayEdge(be, oe)
}
}

func OverlayField(bf, of *Field) {
if of.Primary_ != nil {
bf.Primary_ = of.Primary_.Copy(bf).(*Scalar)
Expand Down
Loading

0 comments on commit 0f53a83

Please sign in to comment.