d2ir: add support for nested property filtering on edges
This commit is contained in:
parent
e111c22549
commit
933cc2f857
4 changed files with 2988 additions and 0 deletions
|
|
@ -5499,6 +5499,112 @@ d -> d: "suspend"
|
||||||
assert.Equal(t, 1, len(g.Edges))
|
assert.Equal(t, 1, len(g.Edges))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "edge-glob-ampersand-filter/1",
|
||||||
|
run: func(t *testing.T) {
|
||||||
|
g, _ := assertCompile(t, `
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&src: a
|
||||||
|
style.stroke-dash: 3
|
||||||
|
}
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&dst: c
|
||||||
|
style.stroke: blue
|
||||||
|
}
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&src: b
|
||||||
|
&dst: c
|
||||||
|
style.fill: red
|
||||||
|
}
|
||||||
|
a -> b
|
||||||
|
b -> c
|
||||||
|
a -> c
|
||||||
|
`, ``)
|
||||||
|
tassert.Equal(t, 3, len(g.Edges))
|
||||||
|
|
||||||
|
tassert.Equal(t, "a", g.Edges[0].Src.ID)
|
||||||
|
tassert.Equal(t, "b", g.Edges[0].Dst.ID)
|
||||||
|
tassert.Equal(t, "3", g.Edges[0].Style.StrokeDash.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[0].Style.Stroke)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[0].Style.Fill)
|
||||||
|
|
||||||
|
tassert.Equal(t, "b", g.Edges[1].Src.ID)
|
||||||
|
tassert.Equal(t, "c", g.Edges[1].Dst.ID)
|
||||||
|
tassert.Equal(t, "blue", g.Edges[1].Style.Stroke.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[1].Style.StrokeDash)
|
||||||
|
tassert.Equal(t, "red", g.Edges[1].Style.Fill.Value)
|
||||||
|
|
||||||
|
tassert.Equal(t, "a", g.Edges[2].Src.ID)
|
||||||
|
tassert.Equal(t, "c", g.Edges[2].Dst.ID)
|
||||||
|
tassert.Equal(t, "3", g.Edges[2].Style.StrokeDash.Value)
|
||||||
|
tassert.Equal(t, "blue", g.Edges[2].Style.Stroke.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[2].Style.Fill)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "edge-glob-ampersand-filter/2",
|
||||||
|
run: func(t *testing.T) {
|
||||||
|
g, _ := assertCompile(t, `
|
||||||
|
a: {
|
||||||
|
shape: circle
|
||||||
|
style: {
|
||||||
|
fill: blue
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b: {
|
||||||
|
shape: rectangle
|
||||||
|
style: {
|
||||||
|
fill: red
|
||||||
|
opacity: 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c: {
|
||||||
|
shape: diamond
|
||||||
|
style.fill: green
|
||||||
|
style.opacity: 0.8
|
||||||
|
}
|
||||||
|
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&src.style.fill: blue
|
||||||
|
style.stroke-dash: 3
|
||||||
|
}
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&dst.style.opacity: 0.8
|
||||||
|
style.stroke: cyan
|
||||||
|
}
|
||||||
|
(* -> *)[*]: {
|
||||||
|
&src.shape: rectangle
|
||||||
|
&dst.style.fill: green
|
||||||
|
style.stroke-width: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
a -> b
|
||||||
|
b -> c
|
||||||
|
a -> c
|
||||||
|
`, ``)
|
||||||
|
|
||||||
|
tassert.Equal(t, 3, len(g.Edges))
|
||||||
|
|
||||||
|
tassert.Equal(t, "a", g.Edges[0].Src.ID)
|
||||||
|
tassert.Equal(t, "b", g.Edges[0].Dst.ID)
|
||||||
|
tassert.Equal(t, "3", g.Edges[0].Style.StrokeDash.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[0].Style.Stroke)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[0].Style.StrokeWidth)
|
||||||
|
|
||||||
|
tassert.Equal(t, "b", g.Edges[1].Src.ID)
|
||||||
|
tassert.Equal(t, "c", g.Edges[1].Dst.ID)
|
||||||
|
tassert.Equal(t, "cyan", g.Edges[1].Style.Stroke.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[1].Style.StrokeDash)
|
||||||
|
tassert.Equal(t, "5", g.Edges[1].Style.StrokeWidth.Value)
|
||||||
|
|
||||||
|
tassert.Equal(t, "a", g.Edges[2].Src.ID)
|
||||||
|
tassert.Equal(t, "c", g.Edges[2].Dst.ID)
|
||||||
|
tassert.Equal(t, "3", g.Edges[2].Style.StrokeDash.Value)
|
||||||
|
tassert.Equal(t, "cyan", g.Edges[2].Style.Stroke.Value)
|
||||||
|
tassert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[2].Style.StrokeWidth)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tca {
|
for _, tc := range tca {
|
||||||
|
|
|
||||||
|
|
@ -694,6 +694,63 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keyPath := refctx.Key.Key
|
||||||
|
if keyPath == nil || len(keyPath.Path) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPart := keyPath.Path[0].Unbox().ScalarString()
|
||||||
|
if (firstPart == "src" || firstPart == "dst") && len(keyPath.Path) > 1 {
|
||||||
|
if len(c.mapRefContextStack) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
edge := ParentEdge(refctx.ScopeMap)
|
||||||
|
if edge == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var nodePath []d2ast.String
|
||||||
|
if firstPart == "src" {
|
||||||
|
nodePath = edge.ID.SrcPath
|
||||||
|
} else {
|
||||||
|
nodePath = edge.ID.DstPath
|
||||||
|
}
|
||||||
|
|
||||||
|
rootMap := RootMap(refctx.ScopeMap)
|
||||||
|
node := rootMap.GetField(nodePath...)
|
||||||
|
if node == nil || node.Map() == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
propKeyPath := &d2ast.KeyPath{
|
||||||
|
Path: keyPath.Path[1:],
|
||||||
|
}
|
||||||
|
|
||||||
|
propKey := &d2ast.Key{
|
||||||
|
Key: propKeyPath,
|
||||||
|
Value: refctx.Key.Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
propRefCtx := &RefContext{
|
||||||
|
Key: propKey,
|
||||||
|
ScopeMap: node.Map(),
|
||||||
|
ScopeAST: refctx.ScopeAST,
|
||||||
|
}
|
||||||
|
|
||||||
|
fa, err := node.Map().EnsureField(propKeyPath, propRefCtx, false, c)
|
||||||
|
if err != nil || len(fa) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range fa {
|
||||||
|
if c._ampersandFilter(f, propRefCtx) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, false, c)
|
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, false, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
||||||
|
|
@ -796,6 +853,45 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
f.Primary_ = n.Primary()
|
f.Primary_ = n.Primary()
|
||||||
}
|
}
|
||||||
return c._ampersandFilter(f, refctx)
|
return c._ampersandFilter(f, refctx)
|
||||||
|
case "src":
|
||||||
|
if len(c.mapRefContextStack) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
edge := ParentEdge(refctx.ScopeMap)
|
||||||
|
if edge == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
filterValue := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
||||||
|
|
||||||
|
var srcParts []string
|
||||||
|
for _, part := range edge.ID.SrcPath {
|
||||||
|
srcParts = append(srcParts, part.ScalarString())
|
||||||
|
}
|
||||||
|
srcPath := strings.Join(srcParts, ".")
|
||||||
|
|
||||||
|
return srcPath == filterValue
|
||||||
|
|
||||||
|
case "dst":
|
||||||
|
if len(c.mapRefContextStack) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
edge := ParentEdge(refctx.ScopeMap)
|
||||||
|
if edge == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
filterValue := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
||||||
|
|
||||||
|
var dstParts []string
|
||||||
|
for _, part := range edge.ID.DstPath {
|
||||||
|
dstParts = append(dstParts, part.ScalarString())
|
||||||
|
}
|
||||||
|
dstPath := strings.Join(dstParts, ".")
|
||||||
|
|
||||||
|
return dstPath == filterValue
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1092
testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json
generated
vendored
Normal file
1092
testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1694
testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json
generated
vendored
Normal file
1694
testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue