diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 5588fcc60..8bd993f30 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -4598,6 +4598,24 @@ a -> b assert.Equal(t, "red", g.Edges[1].Attributes.Style.Stroke.Value) }, }, + { + name: "exists-filter", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +*: { + &link: * + style.underline: true +} + +x +y.link: https://google.com +z.link: https://yahoo.com +`, ``) + assert.Equal(t, (*d2graph.Scalar)(nil), g.Objects[0].Attributes.Style.Underline) + assert.Equal(t, "true", g.Objects[1].Attributes.Style.Underline.Value) + assert.Equal(t, (*d2graph.Scalar)(nil), g.Objects[2].Attributes.Style.Underline) + }, + }, } for _, tc := range tca { diff --git a/d2ir/compile.go b/d2ir/compile.go index 574acdb12..3b62cc1c7 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -695,8 +695,14 @@ func (c *compiler) _ampersandFilter(f *Field, refctx *RefContext) bool { return false } - if refctx.Key.Value.ScalarBox().Unbox().ScalarString() != f.Primary_.Value.ScalarString() { - return false + us, ok := refctx.Key.Value.ScalarBox().Unbox().(*d2ast.UnquotedString) + + if ok && us.Pattern != nil { + return matchPattern(f.Primary_.Value.ScalarString(), us.Pattern) + } else { + if refctx.Key.Value.ScalarBox().Unbox().ScalarString() != f.Primary_.Value.ScalarString() { + return false + } } return true diff --git a/d2parser/parse.go b/d2parser/parse.go index 0a6a38d95..3eb500484 100644 --- a/d2parser/parse.go +++ b/d2parser/parse.go @@ -1163,16 +1163,18 @@ func (p *parser) parseUnquotedString(inKey bool) (s *d2ast.UnquotedString) { sb.WriteRune(r) rawb.WriteRune(r) r = r2 - case '*': - if sb.Len() == 0 { - s.Pattern = append(s.Pattern, "*") - } else { - s.Pattern = append(s.Pattern, sb.String()[lastPatternIndex:], "*") - } - lastPatternIndex = len(sb.String()) + 1 } } + if r == '*' { + if sb.Len() == 0 { + s.Pattern = append(s.Pattern, "*") + } else { + s.Pattern = append(s.Pattern, sb.String()[lastPatternIndex:], "*") + } + lastPatternIndex = len(sb.String()) + 1 + } + p.commit() if !unicode.IsSpace(r) { diff --git a/testdata/d2compiler/TestCompile2/globs/exists-filter.exp.json b/testdata/d2compiler/TestCompile2/globs/exists-filter.exp.json new file mode 100644 index 000000000..4721aaee6 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/exists-filter.exp.json @@ -0,0 +1,321 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,0:0:0-8:0:72", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,1:0:1-4:1:41", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,1:0:1-1:1:2", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,1:3:4-4:1:41", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,2:2:8-2:10:16", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,2:3:9-2:7:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,2:3:9-2:7:13", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,2:9:15-2:10:16", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,3:1:18-3:22:39", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,3:1:18-3:16:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,3:1:18-3:6:23", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,3:7:24-3:16:33", + "value": [ + { + "string": "underline", + "raw_string": "underline" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "boolean": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,3:18:35-3:22:39", + "value": true + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,6:0:43-6:1:44", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,6:0:43-6:1:44", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,6:0:43-6:1:44", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:0:45-7:26:71", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:0:45-7:6:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:0:45-7:1:46", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:2:47-7:6:51", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:8:53-7:26:71", + "value": [ + { + "string": "https://google.com", + "raw_string": "https://google.com" + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,6:0:43-6:1:44", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,6:0:43-6:1:44", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:0:45-7:6:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:0:45-7:1:46", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/exists-filter.d2,7:2:47-7:6:51", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "underline": { + "value": "true" + } + }, + "link": { + "value": "https://google.com" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/glob-filter.exp.json b/testdata/d2compiler/TestCompile2/globs/glob-filter.exp.json new file mode 100644 index 000000000..b92bbf90c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/glob-filter.exp.json @@ -0,0 +1,426 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,0:0:0-9:0:105", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,1:0:1-4:1:48", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,1:0:1-1:1:2", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,1:3:4-4:1:48", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,2:2:8-2:17:23", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,2:3:9-2:7:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,2:3:9-2:7:13", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,2:9:15-2:17:23", + "value": [ + { + "string": "*google*", + "raw_string": "*google*" + } + ], + "pattern": [ + "*", + "google", + "*" + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,3:1:25-3:22:46", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,3:1:25-3:16:40", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,3:1:25-3:6:30", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,3:7:31-3:16:40", + "value": [ + { + "string": "underline", + "raw_string": "underline" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "boolean": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,3:18:42-3:22:46", + "value": true + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,6:0:50-6:1:51", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,6:0:50-6:1:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,6:0:50-6:1:51", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:0:52-7:26:78", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:0:52-7:6:58", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:0:52-7:1:53", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:2:54-7:6:58", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:8:60-7:26:78", + "value": [ + { + "string": "https://google.com", + "raw_string": "https://google.com" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:0:79-8:25:104", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:0:79-8:6:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:0:79-8:1:80", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:2:81-8:6:85", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:8:87-8:25:104", + "value": [ + { + "string": "https://yahoo.com", + "raw_string": "https://yahoo.com" + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,6:0:50-6:1:51", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,6:0:50-6:1:51", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "y", + "id_val": "y", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:0:52-7:6:58", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:0:52-7:1:53", + "value": [ + { + "string": "y", + "raw_string": "y" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,7:2:54-7:6:58", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "y" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "underline": { + "value": "true" + } + }, + "link": { + "value": "https://google.com" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "z", + "id_val": "z", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:0:79-8:6:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:0:79-8:1:80", + "value": [ + { + "string": "z", + "raw_string": "z" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/glob-filter.d2,8:2:81-8:6:85", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "z" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "link": { + "value": "https://yahoo.com" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +}