From 359976e5d4e8a3f6724e0a9db3faf2742a593f8d Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Fri, 23 Jun 2023 10:51:55 -0700 Subject: [PATCH] d2ir: Add single level field glob patterns --- d2ast/d2ast.go | 6 + d2ir/compile.go | 19 ++ d2ir/compile_test.go | 1 + d2ir/pattern.go | 31 +++ d2ir/pattern_test.go | 94 +++++++ d2parser/parse.go | 25 +- .../d2ir/TestCompile/globs/escaped.exp.json | 159 ++++++++++++ .../d2ir/TestCompile/globs/prefix.exp.json | 159 ++++++++++++ .../TestCompile/patterns/escaped.exp.json | 236 ++++++++++++++++++ .../patterns/prefix-suffix.exp.json | 159 ++++++++++++ .../patterns/prefix-suffix/2.exp.json | 159 ++++++++++++ .../patterns/prefix-suffix/3.exp.json | 159 ++++++++++++ .../d2ir/TestCompile/patterns/prefix.exp.json | 159 ++++++++++++ .../d2ir/TestCompile/patterns/suffix.exp.json | 159 ++++++++++++ 14 files changed, 1514 insertions(+), 11 deletions(-) create mode 100644 d2ir/pattern.go create mode 100644 d2ir/pattern_test.go create mode 100644 testdata/d2ir/TestCompile/globs/escaped.exp.json create mode 100644 testdata/d2ir/TestCompile/globs/prefix.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/escaped.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/prefix-suffix.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/prefix-suffix/2.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/prefix-suffix/3.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/prefix.exp.json create mode 100644 testdata/d2ir/TestCompile/patterns/suffix.exp.json diff --git a/d2ast/d2ast.go b/d2ast/d2ast.go index 6313dbe0d..629612c22 100644 --- a/d2ast/d2ast.go +++ b/d2ast/d2ast.go @@ -500,6 +500,8 @@ type Number struct { type UnquotedString struct { Range Range `json:"range"` Value []InterpolationBox `json:"value"` + // Pattern holds the parsed glob pattern if in a key and the unquoted string represents a valid pattern. + Pattern []string `json:"pattern,omitempty"` } func (s *UnquotedString) Coalesce() { @@ -1056,6 +1058,10 @@ func (sb *StringBox) Unbox() String { } } +func (sb *StringBox) ScalarString() string { + return sb.Unbox().ScalarString() +} + // InterpolationBox is used to select between strings and substitutions in unquoted and // double quoted strings. There is no corresponding interface to avoid unnecessary // abstraction. diff --git a/d2ir/compile.go b/d2ir/compile.go index 66eb97818..f8e0ff67c 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -404,12 +404,31 @@ func (c *compiler) compileField(dst *Map, kp *d2ast.KeyPath, refctx *RefContext) return } } + + us, ok := kp.Path[0].Unbox().(*d2ast.UnquotedString) + if ok && us.Pattern != nil { + for _, f := range dst.Fields { + if matchPattern(f.Name, us.Pattern) { + if len(kp.Path) == 1 { + c._compileField(f, refctx) + } else { + // TODO: recurse + } + } + } + return + } + f, err := dst.EnsureField(kp, refctx) if err != nil { c.err.Errors = append(c.err.Errors, err.(d2ast.Error)) return } + c._compileField(f, refctx) +} + +func (c *compiler) _compileField(f *Field, refctx *RefContext) { if refctx.Key.Primary.Unbox() != nil { f.Primary_ = &Scalar{ parent: f, diff --git a/d2ir/compile_test.go b/d2ir/compile_test.go index ab7173c8e..f29b45c27 100644 --- a/d2ir/compile_test.go +++ b/d2ir/compile_test.go @@ -26,6 +26,7 @@ func TestCompile(t *testing.T) { t.Run("scenarios", testCompileScenarios) t.Run("steps", testCompileSteps) t.Run("imports", testCompileImports) + t.Run("patterns", testCompilePatterns) } type testCase struct { diff --git a/d2ir/pattern.go b/d2ir/pattern.go new file mode 100644 index 000000000..39fd5c397 --- /dev/null +++ b/d2ir/pattern.go @@ -0,0 +1,31 @@ +package d2ir + +import ( + "strings" +) + +func matchPattern(s string, pattern []string) bool { + if len(pattern) == 0 { + return true + } + + for i := 0; i < len(pattern); i++ { + if pattern[i] == "*" { + // * so match next. + if i != len(pattern)-1 { + j := strings.Index(s, pattern[i+1]) + if j == -1 { + return false + } + s = s[j+len(pattern[i+1]):] + i++ + } + } else { + if !strings.HasPrefix(s, pattern[i]) { + return false + } + s = s[len(pattern[i]):] + } + } + return true +} diff --git a/d2ir/pattern_test.go b/d2ir/pattern_test.go new file mode 100644 index 000000000..b1709080d --- /dev/null +++ b/d2ir/pattern_test.go @@ -0,0 +1,94 @@ +package d2ir_test + +import ( + "testing" + + "oss.terrastruct.com/util-go/assert" +) + +func testCompilePatterns(t *testing.T) { + t.Parallel() + + tca := []testCase{ + { + name: "prefix", + run: func(t testing.TB) { + m, err := compile(t, `animal: meow +action: yes +a*: globbed`) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, "globbed", "animal") + assertQuery(t, m, 0, 0, "globbed", "action") + }, + }, + { + name: "suffix", + run: func(t testing.TB) { + m, err := compile(t, `animal: meow +jingle: loud +*l: globbed`) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, "globbed", "animal") + assertQuery(t, m, 0, 0, "globbed", "jingle") + }, + }, + { + name: "prefix-suffix", + run: func(t testing.TB) { + m, err := compile(t, `tinker: meow +thinker: yes +t*r: globbed`) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, "globbed", "tinker") + assertQuery(t, m, 0, 0, "globbed", "thinker") + }, + }, + { + name: "prefix-suffix/2", + run: func(t testing.TB) { + m, err := compile(t, `tinker: meow +thinker: yes +t*ink*r: globbed`) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, "globbed", "tinker") + assertQuery(t, m, 0, 0, "globbed", "thinker") + }, + }, + { + name: "prefix-suffix/3", + run: func(t testing.TB) { + m, err := compile(t, `tinkertinker: meow +thinkerthinker: yes +t*ink*r*t*inke*: globbed`) + assert.Success(t, err) + assertQuery(t, m, 2, 0, nil, "") + assertQuery(t, m, 0, 0, "globbed", "tinkertinker") + assertQuery(t, m, 0, 0, "globbed", "thinkerthinker") + }, + }, + { + name: "escaped", + run: func(t testing.TB) { + m, err := compile(t, `animal: meow +action: yes +a\*: globbed`) + assert.Success(t, err) + assertQuery(t, m, 3, 0, nil, "") + assertQuery(t, m, 0, 0, "meow", "animal") + assertQuery(t, m, 0, 0, "yes", "action") + assertQuery(t, m, 0, 0, "globbed", `a\*`) + }, + }, + } + + runa(t, tca) + + t.Run("errors", func(t *testing.T) { + tca := []testCase{} + runa(t, tca) + }) +} diff --git a/d2parser/parse.go b/d2parser/parse.go index bb460da82..d7a540897 100644 --- a/d2parser/parse.go +++ b/d2parser/parse.go @@ -1046,6 +1046,15 @@ func (p *parser) parseUnquotedString(inKey bool) (s *d2ast.UnquotedString) { s.Value = append(s.Value, d2ast.InterpolationBox{String: &sv, StringRaw: &rawv}) }() + lastPatternIndex := 0 + defer func() { + if s.Pattern != nil { + if lastPatternIndex < sb.Len() { + s.Pattern = append(s.Pattern, sb.String()[lastPatternIndex:]) + } + } + }() + _s, eof := p.peekn(4) p.rewind() if !eof { @@ -1118,18 +1127,12 @@ func (p *parser) parseUnquotedString(inKey bool) (s *d2ast.UnquotedString) { rawb.WriteRune(r) r = r2 case '*': - // TODO: need a peekNotSpace across escaped newlines - r2, eof := p.peek() - if eof { - return s + if sb.Len() == 0 { + s.Pattern = append(s.Pattern, "*") + } else { + s.Pattern = append(s.Pattern, sb.String()[lastPatternIndex:], "*") } - if r2 == '-' { - p.rewind() - return s - } - sb.WriteRune(r) - rawb.WriteRune(r) - r = r2 + lastPatternIndex = len(sb.String()) + 1 } } diff --git a/testdata/d2ir/TestCompile/globs/escaped.exp.json b/testdata/d2ir/TestCompile/globs/escaped.exp.json new file mode 100644 index 000000000..de7e12d68 --- /dev/null +++ b/testdata/d2ir/TestCompile/globs/escaped.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "animal", + "primary": { + "value": { + "range": "TestCompile/globs/escaped.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + }, + "key_path": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "action", + "primary": { + "value": { + "range": "TestCompile/globs/escaped.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + }, + "key_path": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:11:24", + "key": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/globs/escaped.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/globs/prefix.exp.json b/testdata/d2ir/TestCompile/globs/prefix.exp.json new file mode 100644 index 000000000..7c50c6809 --- /dev/null +++ b/testdata/d2ir/TestCompile/globs/prefix.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "animal", + "primary": { + "value": { + "range": "TestCompile/globs/prefix.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + }, + "key_path": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "action", + "primary": { + "value": { + "range": "TestCompile/globs/prefix.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + }, + "key_path": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:11:24", + "key": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/globs/prefix.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/escaped.exp.json b/testdata/d2ir/TestCompile/patterns/escaped.exp.json new file mode 100644 index 000000000..27262dd30 --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/escaped.exp.json @@ -0,0 +1,236 @@ +{ + "fields": [ + { + "name": "animal", + "primary": { + "value": { + "range": "TestCompile/patterns/escaped.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "action", + "primary": { + "value": { + "range": "TestCompile/patterns/escaped.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:11:24", + "key": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + }, + { + "name": "a*", + "primary": { + "value": { + "range": "TestCompile/patterns/escaped.d2,2:5:30-2:12:37", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:2:27", + "value": [ + { + "string": "a*", + "raw_string": "a\\*" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:2:27", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:2:27", + "value": [ + { + "string": "a*", + "raw_string": "a\\*" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:12:37", + "key": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:2:27", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,2:0:25-2:2:27", + "value": [ + { + "string": "a*", + "raw_string": "a\\*" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/escaped.d2,2:5:30-2:12:37", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/prefix-suffix.exp.json b/testdata/d2ir/TestCompile/patterns/prefix-suffix.exp.json new file mode 100644 index 000000000..a71fb970b --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/prefix-suffix.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "tinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix.d2,2:5:31-2:12:38", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "thinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix.d2,2:5:31-2:12:38", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:7:20", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:12:25", + "key": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:7:20", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix.d2,1:9:22-1:12:25", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/prefix-suffix/2.exp.json b/testdata/d2ir/TestCompile/patterns/prefix-suffix/2.exp.json new file mode 100644 index 000000000..175299dad --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/prefix-suffix/2.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "tinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,2:9:35-2:16:42", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:0:0-0:6:6", + "value": [ + { + "string": "tinker", + "raw_string": "tinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "thinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,2:9:35-2:16:42", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:7:20", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:12:25", + "key": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:7:20", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:0:13-1:7:20", + "value": [ + { + "string": "thinker", + "raw_string": "thinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/2.d2,1:9:22-1:12:25", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/prefix-suffix/3.exp.json b/testdata/d2ir/TestCompile/patterns/prefix-suffix/3.exp.json new file mode 100644 index 000000000..1504168b9 --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/prefix-suffix/3.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "tinkertinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,2:17:56-2:24:63", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:12:12", + "value": [ + { + "string": "tinkertinker", + "raw_string": "tinkertinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:12:12", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:12:12", + "value": [ + { + "string": "tinkertinker", + "raw_string": "tinkertinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:18:18", + "key": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:12:12", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:0:0-0:12:12", + "value": [ + { + "string": "tinkertinker", + "raw_string": "tinkertinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,0:14:14-0:18:18", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "thinkerthinker", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,2:17:56-2:24:63", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:14:33", + "value": [ + { + "string": "thinkerthinker", + "raw_string": "thinkerthinker" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:14:33", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:14:33", + "value": [ + { + "string": "thinkerthinker", + "raw_string": "thinkerthinker" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:19:38", + "key": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:14:33", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:0:19-1:14:33", + "value": [ + { + "string": "thinkerthinker", + "raw_string": "thinkerthinker" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix-suffix/3.d2,1:16:35-1:19:38", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/prefix.exp.json b/testdata/d2ir/TestCompile/patterns/prefix.exp.json new file mode 100644 index 000000000..62dec6cc3 --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/prefix.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "animal", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix.d2,2:4:29-2:11:36", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "action", + "primary": { + "value": { + "range": "TestCompile/patterns/prefix.d2,2:4:29-2:11:36", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:11:24", + "key": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "action", + "raw_string": "action" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/prefix.d2,1:8:21-1:11:24", + "value": [ + { + "string": "yes", + "raw_string": "yes" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +} diff --git a/testdata/d2ir/TestCompile/patterns/suffix.exp.json b/testdata/d2ir/TestCompile/patterns/suffix.exp.json new file mode 100644 index 000000000..40da3b5a1 --- /dev/null +++ b/testdata/d2ir/TestCompile/patterns/suffix.exp.json @@ -0,0 +1,159 @@ +{ + "fields": [ + { + "name": "animal", + "primary": { + "value": { + "range": "TestCompile/patterns/suffix.d2,2:4:30-2:11:37", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:12:12", + "key": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:6:6", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,0:0:0-0:6:6", + "value": [ + { + "string": "animal", + "raw_string": "animal" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,0:8:8-0:12:12", + "value": [ + { + "string": "meow", + "raw_string": "meow" + } + ] + } + } + } + } + } + ] + }, + { + "name": "jingle", + "primary": { + "value": { + "range": "TestCompile/patterns/suffix.d2,2:4:30-2:11:37", + "value": [ + { + "string": "globbed", + "raw_string": "globbed" + } + ] + } + }, + "references": [ + { + "string": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "jingle", + "raw_string": "jingle" + } + ] + }, + "key_path": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "jingle", + "raw_string": "jingle" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:12:25", + "key": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:6:19", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,1:0:13-1:6:19", + "value": [ + { + "string": "jingle", + "raw_string": "jingle" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/patterns/suffix.d2,1:8:21-1:12:25", + "value": [ + { + "string": "loud", + "raw_string": "loud" + } + ] + } + } + } + } + } + ] + } + ], + "edges": null +}