d2ir: Ensure filters pass before setting primary
This commit is contained in:
parent
df25d8b5fb
commit
88b885a753
8 changed files with 2774 additions and 26 deletions
|
|
@ -606,6 +606,15 @@ func (m *Map) IsFileMap() bool {
|
|||
return m.Range.Start.Line == 0 && m.Range.Start.Column == 0
|
||||
}
|
||||
|
||||
func (m *Map) HasFilter() bool {
|
||||
for _, n := range m.Nodes {
|
||||
if n.MapKey != nil && (n.MapKey.Ampersand || n.MapKey.NotAmpersand) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: require @ on import values for readability
|
||||
type Key struct {
|
||||
Range Range `json:"range"`
|
||||
|
|
|
|||
|
|
@ -376,6 +376,36 @@ func (g *globContext) prefixed(dst *Map) *globContext {
|
|||
return &g2
|
||||
}
|
||||
|
||||
func (c *compiler) ampersandFilterMap(dst *Map, ast, scopeAST *d2ast.Map) bool {
|
||||
for _, n := range ast.Nodes {
|
||||
switch {
|
||||
case n.MapKey != nil:
|
||||
ok := c.ampersandFilter(&RefContext{
|
||||
Key: n.MapKey,
|
||||
Scope: ast,
|
||||
ScopeMap: dst,
|
||||
ScopeAST: scopeAST,
|
||||
})
|
||||
if !ok {
|
||||
// Unapply glob if appropriate.
|
||||
gctx := c.getGlobContext(c.mapRefContextStack[len(c.mapRefContextStack)-1])
|
||||
if gctx == nil {
|
||||
return false
|
||||
}
|
||||
var ks string
|
||||
if gctx.refctx.Key.HasTripleGlob() {
|
||||
ks = d2format.Format(d2ast.MakeKeyPath(IDA(dst)))
|
||||
} else {
|
||||
ks = d2format.Format(d2ast.MakeKeyPath(BoardIDA(dst)))
|
||||
}
|
||||
delete(gctx.appliedFields, ks)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) {
|
||||
var globs []*globContext
|
||||
if len(c.globContextStack) > 0 {
|
||||
|
|
@ -400,31 +430,9 @@ func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) {
|
|||
c.globContextStack = c.globContextStack[:len(c.globContextStack)-1]
|
||||
}()
|
||||
|
||||
for _, n := range ast.Nodes {
|
||||
switch {
|
||||
case n.MapKey != nil:
|
||||
ok := c.ampersandFilter(&RefContext{
|
||||
Key: n.MapKey,
|
||||
Scope: ast,
|
||||
ScopeMap: dst,
|
||||
ScopeAST: scopeAST,
|
||||
})
|
||||
if !ok {
|
||||
// Unapply glob if appropriate.
|
||||
gctx := c.getGlobContext(c.mapRefContextStack[len(c.mapRefContextStack)-1])
|
||||
if gctx == nil {
|
||||
return
|
||||
}
|
||||
var ks string
|
||||
if gctx.refctx.Key.HasTripleGlob() {
|
||||
ks = d2format.Format(d2ast.MakeKeyPath(IDA(dst)))
|
||||
} else {
|
||||
ks = d2format.Format(d2ast.MakeKeyPath(BoardIDA(dst)))
|
||||
}
|
||||
delete(gctx.appliedFields, ks)
|
||||
return
|
||||
}
|
||||
}
|
||||
ok := c.ampersandFilterMap(dst, ast, scopeAST)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for _, n := range ast.Nodes {
|
||||
|
|
@ -644,7 +652,22 @@ func (c *compiler) _ampersandFilter(f *Field, refctx *RefContext) bool {
|
|||
}
|
||||
|
||||
func (c *compiler) _compileField(f *Field, refctx *RefContext) {
|
||||
if len(refctx.Key.Edges) == 0 && refctx.Key.Value.Null != nil {
|
||||
// In case of filters, we need to pass filters before continuing
|
||||
if refctx.Key.Value.Map != nil && refctx.Key.Value.Map.HasFilter() {
|
||||
if f.Map() == nil {
|
||||
f.Composite = &Map{
|
||||
parent: f,
|
||||
}
|
||||
}
|
||||
c.mapRefContextStack = append(c.mapRefContextStack, refctx)
|
||||
ok := c.ampersandFilterMap(f.Map(), refctx.Key.Value.Map, refctx.ScopeAST)
|
||||
c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(refctx.Key.Edges) == 0 && (refctx.Key.Primary.Null != nil || refctx.Key.Value.Null != nil) {
|
||||
// For vars, if we delete the field, it may just resolve to an outer scope var of the same name
|
||||
// Instead we keep it around, so that resolveSubstitutions can find it
|
||||
if !IsVar(ParentMap(f)) {
|
||||
|
|
@ -662,6 +685,7 @@ func (c *compiler) _compileField(f *Field, refctx *RefContext) {
|
|||
Value: refctx.Key.Primary.Unbox(),
|
||||
}
|
||||
}
|
||||
|
||||
if refctx.Key.Value.Array != nil {
|
||||
a := &Array{
|
||||
parent: f,
|
||||
|
|
|
|||
|
|
@ -170,6 +170,46 @@ b.label: a
|
|||
assertQuery(t, m, 0, 0, "yellow", "b.style.fill")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary-filter",
|
||||
run: func(t testing.TB) {
|
||||
m, err := compile(t, `
|
||||
parent: {
|
||||
a -> b1
|
||||
a -> b2
|
||||
a -> b3
|
||||
|
||||
b1 -> c1
|
||||
b1 -> c2
|
||||
|
||||
c1: {
|
||||
c1-child.class: hidden
|
||||
}
|
||||
|
||||
c2: {
|
||||
C2-child.class: hidden
|
||||
}
|
||||
c2.class: hidden
|
||||
b2.class: hidden
|
||||
}
|
||||
|
||||
classes: {
|
||||
hidden: {
|
||||
style: {
|
||||
fill: red
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Error
|
||||
**: null {
|
||||
&class: hidden
|
||||
}
|
||||
`)
|
||||
assert.Success(t, err)
|
||||
assertQuery(t, m, 9, 3, nil, "")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
runa(t, tca)
|
||||
|
|
|
|||
128
testdata/d2ir/TestCompile/filters/array.exp.json
generated
vendored
128
testdata/d2ir/TestCompile/filters/array.exp.json
generated
vendored
|
|
@ -114,6 +114,70 @@
|
|||
"due_to_glob": false,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"edge": null,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/array.d2,11:1:134-11:15:148",
|
||||
"ampersand": true,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:9:142-11:15:148",
|
||||
"value": [
|
||||
{
|
||||
"string": "server",
|
||||
"raw_string": "server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"due_to_glob": true,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
|
|
@ -887,6 +951,70 @@
|
|||
"due_to_glob": false,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"edge": null,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/array.d2,11:1:134-11:15:148",
|
||||
"ampersand": true,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
"value": [
|
||||
{
|
||||
"string": "class",
|
||||
"raw_string": "class"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/array.d2,11:9:142-11:15:148",
|
||||
"value": [
|
||||
{
|
||||
"string": "server",
|
||||
"raw_string": "server"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"due_to_glob": true,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/array.d2,11:2:135-11:7:140",
|
||||
|
|
|
|||
64
testdata/d2ir/TestCompile/filters/base.exp.json
generated
vendored
64
testdata/d2ir/TestCompile/filters/base.exp.json
generated
vendored
|
|
@ -326,6 +326,70 @@
|
|||
"due_to_glob": false,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"edge": null,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/base.d2,7:1:62-7:18:79",
|
||||
"ampersand": true,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/base.d2,7:9:70-7:18:79",
|
||||
"value": [
|
||||
{
|
||||
"string": "rectangle",
|
||||
"raw_string": "rectangle"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"due_to_glob": true,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/base.d2,7:2:63-7:7:68",
|
||||
|
|
|
|||
64
testdata/d2ir/TestCompile/filters/lazy-filter.exp.json
generated
vendored
64
testdata/d2ir/TestCompile/filters/lazy-filter.exp.json
generated
vendored
|
|
@ -362,6 +362,70 @@
|
|||
"due_to_glob": false,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
"value": [
|
||||
{
|
||||
"string": "label",
|
||||
"raw_string": "label"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
"value": [
|
||||
{
|
||||
"string": "label",
|
||||
"raw_string": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"edge": null,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:2:8-2:11:17",
|
||||
"ampersand": true,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
"value": [
|
||||
{
|
||||
"string": "label",
|
||||
"raw_string": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:10:16-2:11:17",
|
||||
"value": [
|
||||
{
|
||||
"string": "a",
|
||||
"raw_string": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"due_to_glob": true,
|
||||
"due_to_lazy_glob": true
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/lazy-filter.d2,2:3:9-2:8:14",
|
||||
|
|
|
|||
64
testdata/d2ir/TestCompile/filters/order.exp.json
generated
vendored
64
testdata/d2ir/TestCompile/filters/order.exp.json
generated
vendored
|
|
@ -326,6 +326,70 @@
|
|||
"due_to_glob": false,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"edge": null,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/order.d2,8:1:86-8:18:103",
|
||||
"ampersand": true,
|
||||
"key": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
"value": [
|
||||
{
|
||||
"string": "shape",
|
||||
"raw_string": "shape"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"unquoted_string": {
|
||||
"range": "TestCompile/filters/order.d2,8:9:94-8:18:103",
|
||||
"value": [
|
||||
{
|
||||
"string": "rectangle",
|
||||
"raw_string": "rectangle"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"due_to_glob": true,
|
||||
"due_to_lazy_glob": false
|
||||
},
|
||||
{
|
||||
"string": {
|
||||
"range": "TestCompile/filters/order.d2,8:2:87-8:7:92",
|
||||
|
|
|
|||
2355
testdata/d2ir/TestCompile/filters/primary-filter.exp.json
generated
vendored
Normal file
2355
testdata/d2ir/TestCompile/filters/primary-filter.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue