From 49f60826af46fd7dfb13f84bf808beff0facd6f7 Mon Sep 17 00:00:00 2001 From: Matthew Manela Date: Wed, 24 Apr 2024 12:58:06 -0400 Subject: [PATCH 1/4] Honor regex flags for case-sensitivity --- eval.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eval.go b/eval.go index 7cbd3658f..6cf030f55 100644 --- a/eval.go +++ b/eval.go @@ -641,7 +641,8 @@ func (d *indexData) regexpToMatchTreeRecursive(r *syntax.Regexp, minTextSize int case syntax.OpLiteral: s := string(r.Rune) if len(s) >= minTextSize { - mt, err := d.newSubstringMatchTree(&query.Substring{Pattern: s, FileName: fileName, CaseSensitive: caseSensitive}) + ignoreCase := !caseSensitive || r.Flags&syntax.FoldCase != 0 + mt, err := d.newSubstringMatchTree(&query.Substring{Pattern: s, FileName: fileName, CaseSensitive: !ignoreCase}) return mt, true, !strings.Contains(s, "\n"), err } case syntax.OpCapture: From a104225cec777cf0663dc241c00f53bc85438a65 Mon Sep 17 00:00:00 2001 From: Matthew Manela Date: Wed, 24 Apr 2024 13:00:24 -0400 Subject: [PATCH 2/4] change --- .vscode/launch.json | 14 ++++++++++++++ eval.go | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..dffa3c19e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Process (from list)", + "type": "go", + "request": "attach", + "mode": "local" + }, + ] +} \ No newline at end of file diff --git a/eval.go b/eval.go index 6cf030f55..cc0e61f27 100644 --- a/eval.go +++ b/eval.go @@ -641,8 +641,8 @@ func (d *indexData) regexpToMatchTreeRecursive(r *syntax.Regexp, minTextSize int case syntax.OpLiteral: s := string(r.Rune) if len(s) >= minTextSize { - ignoreCase := !caseSensitive || r.Flags&syntax.FoldCase != 0 - mt, err := d.newSubstringMatchTree(&query.Substring{Pattern: s, FileName: fileName, CaseSensitive: !ignoreCase}) + ignoreCase := syntax.FoldCase == (r.Flags & syntax.FoldCase) + mt, err := d.newSubstringMatchTree(&query.Substring{Pattern: s, FileName: fileName, CaseSensitive: !ignoreCase && caseSensitive}) return mt, true, !strings.Contains(s, "\n"), err } case syntax.OpCapture: From a9b33b7c06763bdddc0ec0f7ebbd5b124855e7a6 Mon Sep 17 00:00:00 2001 From: Matthew Manela Date: Thu, 25 Apr 2024 13:03:07 -0400 Subject: [PATCH 3/4] add test --- eval_test.go | 68 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/eval_test.go b/eval_test.go index aeff6c27e..b29aaf631 100644 --- a/eval_test.go +++ b/eval_test.go @@ -59,57 +59,62 @@ func printRegexp(t *testing.T, r *syntax.Regexp, lvl int) { } } -func substrMT(pattern string) matchTree { +func substrMT(pattern string, caseSensitive bool) matchTree { d := &indexData{} mt, _ := d.newSubstringMatchTree(&query.Substring{ - Pattern: pattern, + Pattern: pattern, + CaseSensitive: caseSensitive, }) return mt } func TestRegexpParse(t *testing.T) { type testcase struct { - in string - query matchTree - isEquivalent bool + in string + query matchTree + isEquivalent bool + caseSensitive bool } cases := []testcase{ - {"(foo|)bar", substrMT("bar"), false}, - {"(foo|)", &bruteForceMatchTree{}, false}, + {"(foo|)bar", substrMT("bar", false), false, false}, + {"(foo|)", &bruteForceMatchTree{}, false, false}, {"(foo|bar)baz.*bla", &andMatchTree{[]matchTree{ &orMatchTree{[]matchTree{ - substrMT("foo"), - substrMT("bar"), + substrMT("foo", false), + substrMT("bar", false), }}, - substrMT("baz"), - substrMT("bla"), - }}, false}, + substrMT("baz", false), + substrMT("bla", false), + }}, false, false}, { "^[a-z](People)+barrabas$", &andMatchTree{[]matchTree{ - substrMT("People"), - substrMT("barrabas"), - }}, false, + substrMT("People", false), + substrMT("barrabas", false), + }}, false, false, }, - {"foo", substrMT("foo"), true}, - {"^foo", substrMT("foo"), false}, - {"(foo) (bar)", &andMatchTree{[]matchTree{substrMT("foo"), substrMT("bar")}}, false}, + {"foo", substrMT("foo", false), true, false}, + {"foo", substrMT("foo", true), true, true}, + {"(?i)foo", substrMT("FOO", false), true, false}, + {"(?i)foo", substrMT("FOO", false), true, true}, + {"^foo", substrMT("foo", false), false, false}, + {"(foo) (bar)", &andMatchTree{[]matchTree{substrMT("foo", false), substrMT("bar", false)}}, false, false}, {"(thread|needle|haystack)", &orMatchTree{[]matchTree{ - substrMT("thread"), - substrMT("needle"), - substrMT("haystack"), - }}, true}, + substrMT("thread", false), + substrMT("needle", false), + substrMT("haystack", false), + }}, true, false}, {"(foo)(?-s:.)*?(bar)", &andLineMatchTree{andMatchTree{[]matchTree{ - substrMT("foo"), - substrMT("bar"), - }}}, false}, + substrMT("foo", false), + substrMT("bar", false), + }}}, false, false}, {"(foo)(?-s:.)*?[[:space:]](?-s:.)*?(bar)", &andMatchTree{[]matchTree{ - substrMT("foo"), - substrMT("bar"), - }}, false}, - {"(foo){2,}", substrMT("foo"), false}, - {"(...)(...)", &bruteForceMatchTree{}, false}, + substrMT("foo", false), + substrMT("bar", false), + }}, false, false}, + {"(foo){2,}", substrMT("foo", false), false, false}, + {"(...)(...)", &bruteForceMatchTree{}, false, false}, } for _, c := range cases { @@ -120,7 +125,8 @@ func TestRegexpParse(t *testing.T) { } d := indexData{} q := query.Regexp{ - Regexp: r, + Regexp: r, + CaseSensitive: c.caseSensitive, } gotQuery, isEq, _, _ := d.regexpToMatchTreeRecursive(q.Regexp, 3, q.FileName, q.CaseSensitive) if !reflect.DeepEqual(c.query, gotQuery) { From cd9cf2bd041bdbda66028c2fc0996871781e2949 Mon Sep 17 00:00:00 2001 From: Matthew Manela Date: Mon, 29 Apr 2024 12:53:45 -0400 Subject: [PATCH 4/4] pr comment --- eval_test.go | 55 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/eval_test.go b/eval_test.go index b29aaf631..32cefdea0 100644 --- a/eval_test.go +++ b/eval_test.go @@ -59,11 +59,20 @@ func printRegexp(t *testing.T, r *syntax.Regexp, lvl int) { } } -func substrMT(pattern string, caseSensitive bool) matchTree { +func caseSensitiveSubstrMT(pattern string) matchTree { d := &indexData{} mt, _ := d.newSubstringMatchTree(&query.Substring{ Pattern: pattern, - CaseSensitive: caseSensitive, + CaseSensitive: true, + }) + return mt +} + +func substrMT(pattern string) matchTree { + d := &indexData{} + mt, _ := d.newSubstringMatchTree(&query.Substring{ + Pattern: pattern, + CaseSensitive: false, }) return mt } @@ -77,43 +86,43 @@ func TestRegexpParse(t *testing.T) { } cases := []testcase{ - {"(foo|)bar", substrMT("bar", false), false, false}, + {"(foo|)bar", substrMT("bar"), false, false}, {"(foo|)", &bruteForceMatchTree{}, false, false}, {"(foo|bar)baz.*bla", &andMatchTree{[]matchTree{ &orMatchTree{[]matchTree{ - substrMT("foo", false), - substrMT("bar", false), + substrMT("foo"), + substrMT("bar"), }}, - substrMT("baz", false), - substrMT("bla", false), + substrMT("baz"), + substrMT("bla"), }}, false, false}, { "^[a-z](People)+barrabas$", &andMatchTree{[]matchTree{ - substrMT("People", false), - substrMT("barrabas", false), + substrMT("People"), + substrMT("barrabas"), }}, false, false, }, - {"foo", substrMT("foo", false), true, false}, - {"foo", substrMT("foo", true), true, true}, - {"(?i)foo", substrMT("FOO", false), true, false}, - {"(?i)foo", substrMT("FOO", false), true, true}, - {"^foo", substrMT("foo", false), false, false}, - {"(foo) (bar)", &andMatchTree{[]matchTree{substrMT("foo", false), substrMT("bar", false)}}, false, false}, + {"foo", substrMT("foo"), true, false}, + {"foo", caseSensitiveSubstrMT("foo"), true, true}, + {"(?i)foo", substrMT("FOO"), true, false}, + {"(?i)foo", substrMT("FOO"), true, true}, + {"^foo", substrMT("foo"), false, false}, + {"(foo) (bar)", &andMatchTree{[]matchTree{substrMT("foo"), substrMT("bar")}}, false, false}, {"(thread|needle|haystack)", &orMatchTree{[]matchTree{ - substrMT("thread", false), - substrMT("needle", false), - substrMT("haystack", false), + substrMT("thread"), + substrMT("needle"), + substrMT("haystack"), }}, true, false}, {"(foo)(?-s:.)*?(bar)", &andLineMatchTree{andMatchTree{[]matchTree{ - substrMT("foo", false), - substrMT("bar", false), + substrMT("foo"), + substrMT("bar"), }}}, false, false}, {"(foo)(?-s:.)*?[[:space:]](?-s:.)*?(bar)", &andMatchTree{[]matchTree{ - substrMT("foo", false), - substrMT("bar", false), + substrMT("foo"), + substrMT("bar"), }}, false, false}, - {"(foo){2,}", substrMT("foo", false), false, false}, + {"(foo){2,}", substrMT("foo"), false, false}, {"(...)(...)", &bruteForceMatchTree{}, false, false}, }