implement
This commit is contained in:
parent
f430faa16b
commit
db3e4c21a7
3 changed files with 97 additions and 49 deletions
|
|
@ -5679,7 +5679,13 @@ a.1 -> x
|
||||||
assert.Equal(t, (*d2graph.Scalar)(nil), g.Objects[2].Attributes.Style.Stroke)
|
assert.Equal(t, (*d2graph.Scalar)(nil), g.Objects[2].Attributes.Style.Stroke)
|
||||||
|
|
||||||
assert.Equal(t, "(x -> y)[0]", g.Edges[0].AbsID())
|
assert.Equal(t, "(x -> y)[0]", g.Edges[0].AbsID())
|
||||||
assert.Equal(t, "blue", g.Edges[0].Attributes.Style.Stroke)
|
assert.Equal(t, "blue", g.Edges[0].Attributes.Style.Stroke.Value)
|
||||||
|
|
||||||
|
assert.Equal(t, "a.(1 -> 2)[0]", g.Edges[1].AbsID())
|
||||||
|
assert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[1].Attributes.Style.Stroke)
|
||||||
|
|
||||||
|
assert.Equal(t, "(a.1 -> x)[0]", g.Edges[2].AbsID())
|
||||||
|
assert.Equal(t, (*d2graph.Scalar)(nil), g.Edges[2].Attributes.Style.Stroke)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
122
d2ir/compile.go
122
d2ir/compile.go
|
|
@ -755,6 +755,13 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secondPart := keyPath.Path[1].Unbox().ScalarString()
|
||||||
|
value := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
||||||
|
|
||||||
|
if len(keyPath.Path) == 2 && c._ampersandPropertyFilter(secondPart, value, node, refctx.Key) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
propKeyPath := &d2ast.KeyPath{
|
propKeyPath := &d2ast.KeyPath{
|
||||||
Path: keyPath.Path[1:],
|
Path: keyPath.Path[1:],
|
||||||
}
|
}
|
||||||
|
|
@ -840,53 +847,7 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return c._ampersandFilter(f, refctx)
|
return c._ampersandFilter(f, refctx)
|
||||||
case "leaf":
|
|
||||||
raw := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
|
||||||
boolVal, err := strconv.ParseBool(raw)
|
|
||||||
if err != nil {
|
|
||||||
c.errorf(refctx.Key, `&leaf must be "true" or "false", got %q`, raw)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
f := refctx.ScopeMap.Parent().(*Field)
|
|
||||||
isLeaf := f.Map() == nil || !f.Map().IsContainer()
|
|
||||||
return isLeaf == boolVal
|
|
||||||
case "level":
|
|
||||||
raw := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
|
||||||
levelVal, err := strconv.Atoi(raw)
|
|
||||||
if err != nil {
|
|
||||||
c.errorf(refctx.Key, `&level must be a non-negative integer, got %q`, raw)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if levelVal < 0 {
|
|
||||||
c.errorf(refctx.Key, `&level must be a non-negative integer, got %d`, levelVal)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
f := refctx.ScopeMap.Parent().(*Field)
|
|
||||||
level := 0
|
|
||||||
parent := ParentField(f)
|
|
||||||
for parent != nil && parent.Name.ScalarString() != "root" && NodeBoardKind(parent) == "" {
|
|
||||||
level++
|
|
||||||
parent = ParentField(parent)
|
|
||||||
}
|
|
||||||
return level == levelVal
|
|
||||||
case "connected":
|
|
||||||
raw := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
|
||||||
boolVal, err := strconv.ParseBool(raw)
|
|
||||||
if err != nil {
|
|
||||||
c.errorf(refctx.Key, `&connected must be "true" or "false", got %q`, raw)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
f := refctx.ScopeMap.Parent().(*Field)
|
|
||||||
isConnected := false
|
|
||||||
for _, r := range f.References {
|
|
||||||
if r.InEdge() {
|
|
||||||
isConnected = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isConnected == boolVal
|
|
||||||
case "label":
|
case "label":
|
||||||
f := &Field{}
|
f := &Field{}
|
||||||
n := refctx.ScopeMap.Parent()
|
n := refctx.ScopeMap.Parent()
|
||||||
|
|
@ -978,7 +939,10 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
|
|
||||||
return dstPath == filterValue
|
return dstPath == filterValue
|
||||||
default:
|
default:
|
||||||
return false
|
f := refctx.ScopeMap.Parent().(*Field)
|
||||||
|
propName := refctx.Key.Key.Last().ScalarString()
|
||||||
|
value := refctx.Key.Value.ScalarBox().Unbox().ScalarString()
|
||||||
|
return c._ampersandPropertyFilter(propName, value, f, refctx.Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, f := range fa {
|
for _, f := range fa {
|
||||||
|
|
@ -990,6 +954,70 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handles filters that are not based on fields
|
||||||
|
func (c *compiler) _ampersandPropertyFilter(propName string, value string, node *Field, key *d2ast.Key) bool {
|
||||||
|
switch propName {
|
||||||
|
case "level":
|
||||||
|
levelVal, err := strconv.Atoi(value)
|
||||||
|
if err != nil {
|
||||||
|
c.errorf(key, `&level must be a non-negative integer, got %q`, value)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if levelVal < 0 {
|
||||||
|
c.errorf(key, `&level must be a non-negative integer, got %d`, levelVal)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
level := 0
|
||||||
|
parent := ParentField(node)
|
||||||
|
for parent != nil && parent.Name.ScalarString() != "root" && NodeBoardKind(parent) == "" {
|
||||||
|
level++
|
||||||
|
parent = ParentField(parent)
|
||||||
|
}
|
||||||
|
return level == levelVal
|
||||||
|
case "leaf":
|
||||||
|
boolVal, err := strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
c.errorf(key, `&leaf must be "true" or "false", got %q`, value)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
isLeaf := node.Map() == nil || !node.Map().IsContainer()
|
||||||
|
return isLeaf == boolVal
|
||||||
|
case "connected":
|
||||||
|
boolVal, err := strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
c.errorf(key, `&connected must be "true" or "false", got %q`, value)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
isConnected := false
|
||||||
|
for _, r := range node.References {
|
||||||
|
if r.InEdge() {
|
||||||
|
isConnected = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isConnected == boolVal
|
||||||
|
case "label":
|
||||||
|
f := &Field{}
|
||||||
|
if node.Primary() == nil {
|
||||||
|
f.Primary_ = &Scalar{
|
||||||
|
Value: node.Name,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
f.Primary_ = node.Primary()
|
||||||
|
}
|
||||||
|
propKey := &d2ast.Key{
|
||||||
|
Key: key.Key,
|
||||||
|
Value: key.Value,
|
||||||
|
}
|
||||||
|
propRefCtx := &RefContext{
|
||||||
|
Key: propKey,
|
||||||
|
}
|
||||||
|
return c._ampersandFilter(f, propRefCtx)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (c *compiler) _ampersandFilter(f *Field, refctx *RefContext) bool {
|
func (c *compiler) _ampersandFilter(f *Field, refctx *RefContext) bool {
|
||||||
if refctx.Key.Value.ScalarBox().Unbox() == nil {
|
if refctx.Key.Value.ScalarBox().Unbox() == nil {
|
||||||
c.errorf(refctx.Key, "glob filters cannot be composites")
|
c.errorf(refctx.Key, "glob filters cannot be composites")
|
||||||
|
|
|
||||||
16
testdata/d2compiler/TestCompile2/globs/level-filter.exp.json
generated
vendored
16
testdata/d2compiler/TestCompile2/globs/level-filter.exp.json
generated
vendored
|
|
@ -670,6 +670,9 @@
|
||||||
"src_arrow": false,
|
"src_arrow": false,
|
||||||
"dst_arrow": true,
|
"dst_arrow": true,
|
||||||
"references": [
|
"references": [
|
||||||
|
{
|
||||||
|
"map_key_edge_index": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"map_key_edge_index": 0
|
"map_key_edge_index": 0
|
||||||
}
|
}
|
||||||
|
|
@ -682,7 +685,12 @@
|
||||||
"width": 0,
|
"width": 0,
|
||||||
"height": 0
|
"height": 0
|
||||||
},
|
},
|
||||||
"style": {},
|
"style": {
|
||||||
|
"stroke": {
|
||||||
|
"value": "blue"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": ""
|
"value": ""
|
||||||
|
|
@ -713,6 +721,7 @@
|
||||||
"height": 0
|
"height": 0
|
||||||
},
|
},
|
||||||
"style": {},
|
"style": {},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": ""
|
"value": ""
|
||||||
|
|
@ -743,6 +752,7 @@
|
||||||
"height": 0
|
"height": 0
|
||||||
},
|
},
|
||||||
"style": {},
|
"style": {},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": ""
|
"value": ""
|
||||||
|
|
@ -1077,6 +1087,7 @@
|
||||||
"value": "red"
|
"value": "red"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": "rectangle"
|
"value": "rectangle"
|
||||||
|
|
@ -1126,6 +1137,7 @@
|
||||||
"value": "red"
|
"value": "red"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": "rectangle"
|
"value": "rectangle"
|
||||||
|
|
@ -1206,6 +1218,7 @@
|
||||||
"value": "yellow"
|
"value": "yellow"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": "rectangle"
|
"value": "rectangle"
|
||||||
|
|
@ -1255,6 +1268,7 @@
|
||||||
"value": "yellow"
|
"value": "yellow"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"iconStyle": {},
|
||||||
"near_key": null,
|
"near_key": null,
|
||||||
"shape": {
|
"shape": {
|
||||||
"value": "rectangle"
|
"value": "rectangle"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue