Skip to content

Commit

Permalink
fix non-spread import links
Browse files Browse the repository at this point in the history
  • Loading branch information
alixander committed Jul 19, 2024
1 parent e269a0d commit 9e4742a
Show file tree
Hide file tree
Showing 6 changed files with 3,698 additions and 225 deletions.
37 changes: 36 additions & 1 deletion d2compiler/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2952,7 +2952,7 @@ layers: {
},
},
{
name: "import-link-underscore",
name: "import-link-underscore-1",
text: `k
layers: {
Expand All @@ -2976,6 +2976,41 @@ layers: {
k: {
k
}
}`,
},
assertions: func(t *testing.T, g *d2graph.Graph) {
tassert.Equal(t, "root.layers.x", g.Layers[0].Layers[0].Objects[0].Link.Value)
tassert.Equal(t, "root.layers.x.layers.b", g.Layers[0].Layers[0].Layers[0].Objects[0].Link.Value)
tassert.Equal(t, "root.layers.x", g.Layers[0].Layers[0].Layers[0].Objects[1].Link.Value)
tassert.Equal(t, "root.layers.x.layers.b", g.Layers[0].Layers[0].Layers[0].Objects[2].Link.Value)
tassert.Equal(t, "root.layers.x.layers.k", g.Layers[0].Layers[0].Objects[1].Link.Value)
},
},
{
name: "import-link-underscore-2",
text: `k
layers: {
x: @x
}`,
files: map[string]string{
"x.d2": `a
layers: {
b: {
d.link: _
s.link: _.layers.k
layers: {
c: {
c.link: _
z.link: _._
f.link: _._.layers.b
}
}
}
k: {
k
}
}`,
},
assertions: func(t *testing.T, g *d2graph.Graph) {
Expand Down
70 changes: 1 addition & 69 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ func (c *compiler) _compileField(f *Field, refctx *RefContext) {
}
}
OverlayMap(f.Map(), n)
c.updateLinks(f.Map())
c.extendLinks(f.Map(), f)
switch NodeBoardKind(f) {
case BoardScenario, BoardStep:
c.overlayClasses(f.Map())
Expand Down Expand Up @@ -883,74 +883,6 @@ func (c *compiler) extendLinks(m *Map, importF *Field) {
}
}

func (c *compiler) updateLinks(m *Map) {
nodeBoardKind := NodeBoardKind(m)
for _, f := range m.Fields {
if f.Name == "link" {
if nodeBoardKind != "" {
c.errorf(f.LastRef().AST(), "a board itself cannot be linked; only objects within a board can be linked")
continue
}
val := f.Primary().Value.ScalarString()
link, err := d2parser.ParseKey(val)
if err != nil {
continue
}

linkIDA := link.IDA()
if len(linkIDA) == 0 {
continue
}

// When updateLinks is called, all valid board links are already compiled and changed to the qualified path beginning with "root"
if linkIDA[0] != "root" {
continue
}
bida := BoardIDA(f)
aida := IDA(f)

if len(bida) != len(aida) {
prependIDA := aida[:len(aida)-len(bida)]
fullIDA := []string{"root"}
// With nested imports, a value may already have been updated with part of the absolute path
// E.g.,
// The import prepends path a b c
// The existing path is b c d
// So the new path is
// a b c
// b c d
// -------
// a b c d
OUTER:
// Starts at 1 assuming 0 is "root" for both
// +2 assuming layers/scenarios/steps is in between both
for i := 1; i < len(prependIDA); i += 2 {
for j := 0; i+j < len(prependIDA); j++ {
if 1+j >= len(linkIDA) || prependIDA[i+j] != linkIDA[1+j] {
break
}
// Reached the end and all common
if i+j == len(prependIDA)-1 {
break OUTER
}
}
fullIDA = append(fullIDA, prependIDA[i])
fullIDA = append(fullIDA, prependIDA[i+1])
}
// Chop off "root"
fullIDA = append(fullIDA, linkIDA[1:]...)

kp := d2ast.MakeKeyPath(fullIDA)
s := d2format.Format(kp)
f.Primary_.Value = d2ast.MakeValueBox(d2ast.FlatUnquotedString(s)).ScalarBox().Unbox()
}
}
if f.Map() != nil {
c.updateLinks(f.Map())
}
}
}

func (c *compiler) compileLink(f *Field, refctx *RefContext) {
val := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
link, err := d2parser.ParseKey(val)
Expand Down
Loading

0 comments on commit 9e4742a

Please sign in to comment.