d2ir: Ensure filters pass before setting primary

This commit is contained in:
Anmol Sethi 2023-08-30 00:31:36 -07:00
parent df25d8b5fb
commit 88b885a753
No known key found for this signature in database
GPG key ID: 8CEF1878FF10ADEB
8 changed files with 2774 additions and 26 deletions

View file

@ -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"`

View file

@ -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,

View file

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

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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

File diff suppressed because it is too large Load diff