d2ir: spread vars in place

This commit is contained in:
Alexander Wang 2024-08-17 08:48:06 +08:00
parent f9d11848d7
commit de6eafa595
No known key found for this signature in database
GPG key ID: BE3937D0D52D8927
5 changed files with 1326 additions and 2 deletions

View file

@ -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 [#2062](https://github.com/terrastruct/d2/pull/2062)

View file

@ -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:]...)

View file

@ -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 {
@ -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)
}

View file

@ -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(m.Fields[:fi], append([]*Field{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)

1260
testdata/d2ir/TestCompile/vars/spread-in-place.exp.json generated vendored Normal file

File diff suppressed because it is too large Load diff