Skip to content

Commit 625ba6d

Browse files
committed
fix: embed stack trace regex into main pattern, update tests
1 parent 246ff43 commit 625ba6d

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

error_template.go

+26-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func (tmp *CompiledErrorTemplate) ExtractVariables(msg string) map[string]string
5050
continue
5151
}
5252

53+
if v, ok := variables[groupNames[idx]]; ok && len(v) != 0 {
54+
continue
55+
}
56+
5357
variables[groupNames[idx]] = matchedContent
5458
}
5559
}
@@ -108,7 +112,11 @@ func (tmp *CompiledErrorTemplate) Match(str string) bool {
108112

109113
type ErrorTemplates map[string]*CompiledErrorTemplate
110114

111-
const defaultStackTraceRegex = `(?P<stacktrace>(?:.|\s)*)`
115+
const defaultStackTraceRegexOpening = `(?P<stacktrace>(?:`
116+
const defaultStackTraceRegexClosing = `)*)`
117+
const defaultStackTraceRegex = defaultStackTraceRegexOpening + `.|\s` + defaultStackTraceRegexClosing
118+
119+
var stackTraceCaptureGroupRegex = regexp.MustCompile(`\(\?P<(?:symbol|path|position)>([a-z0-9A-Z_\\//+.]+)\)`)
112120

113121
func (tmps *ErrorTemplates) Add(language *Language, template ErrorTemplate) (*CompiledErrorTemplate, error) {
114122
key := TemplateKey(language.Name, template.Name)
@@ -143,8 +151,10 @@ func (tmps *ErrorTemplates) Add(language *Language, template ErrorTemplate) (*Co
143151
}
144152

145153
if strings.Contains(patternForCompile, "$stacktrace") {
146-
patternForCompile =
147-
strings.ReplaceAll(patternForCompile, "$stacktrace", defaultStackTraceRegex)
154+
rawStackTracePattern := template.StackTracePattern
155+
if len(rawStackTracePattern) == 0 && len(language.StackTracePattern) != 0 {
156+
rawStackTracePattern = language.StackTracePattern
157+
}
148158

149159
if len(template.StackTracePattern) != 0 {
150160
var err error
@@ -153,6 +163,19 @@ func (tmps *ErrorTemplates) Add(language *Language, template ErrorTemplate) (*Co
153163
return nil, err
154164
}
155165
}
166+
167+
if len(rawStackTracePattern) != 0 {
168+
// strip first the group names before replacing $stacktrace
169+
strippedStackTracePattern := stackTraceCaptureGroupRegex.ReplaceAllString(rawStackTracePattern, "$1")
170+
171+
// replace $stacktrace with the actual stack trace pattern
172+
patternForCompile =
173+
strings.ReplaceAll(patternForCompile, "$stacktrace",
174+
defaultStackTraceRegexOpening+strippedStackTracePattern+defaultStackTraceRegexClosing)
175+
} else {
176+
patternForCompile =
177+
strings.ReplaceAll(patternForCompile, "$stacktrace", defaultStackTraceRegex)
178+
}
156179
}
157180

158181
compiledPattern, err := regexp.Compile("(?m)^" + patternForCompile + "$")

error_template_test.go

+24-10
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestErrorTemplate(t *testing.T) {
3434

3535
testutils.Equals(t, tmp.Name, "ErrorA")
3636
testutils.Equals(t, tmp.Language, lib.TestLanguage)
37-
testutils.Equals(t, tmp.Pattern.String(), `(?m)^This is a sample error(?P<stacktrace>(?:.|\s)*)$`)
37+
testutils.Equals(t, tmp.Pattern.String(), `(?m)^This is a sample error(?P<stacktrace>(?:\sin \S+ at \S+:\d+)*)$`)
3838
testutils.Equals(t, tmp.StackTraceRegex().String(), `(?m)\sin (?P<symbol>\S+) at (?P<path>\S+):(?P<position>\d+)`)
3939
testutils.ExpectNil(t, tmp.StackTracePattern)
4040
})
@@ -54,7 +54,7 @@ func TestErrorTemplate(t *testing.T) {
5454

5555
testutils.Equals(t, tmp.Name, "ErrorB")
5656
testutils.Equals(t, tmp.Language, lib.TestLanguage)
57-
testutils.Equals(t, tmp.Pattern.String(), `(?m)^This is a sample error with stack trace(?P<stacktrace>(?:.|\s)*)$`)
57+
testutils.Equals(t, tmp.Pattern.String(), `(?m)^This is a sample error with stack trace(?P<stacktrace>(?:\S+:\S+:\d+)*)$`)
5858
testutils.Equals(t, tmp.StackTraceRegex().String(), `(?P<symbol>\S+):(?P<path>\S+):(?P<position>\d+)`)
5959
})
6060

@@ -72,7 +72,7 @@ func TestErrorTemplate(t *testing.T) {
7272

7373
testutils.Equals(t, tmp.Name, "ErrorC")
7474
testutils.Equals(t, tmp.Language, lib.TestLanguage)
75-
testutils.Equals(t, tmp.Pattern.String(), `(?m)^Stack trace in middle (?P<stacktrace>(?:.|\s)*)test$`)
75+
testutils.Equals(t, tmp.Pattern.String(), `(?m)^Stack trace in middle (?P<stacktrace>(?:\sin \S+ at \S+:\d+)*)test$`)
7676
testutils.ExpectNil(t, tmp.StackTracePattern)
7777
})
7878
}
@@ -265,7 +265,7 @@ func TestExtractVariables(t *testing.T) {
265265

266266
variables := tmp.ExtractVariables(input)
267267
exp := map[string]string{
268-
"stacktrace": "\nin main at /home/user/main.py:123\nin main at /home/user/main.py:1",
268+
"stacktrace": "",
269269
"input": "123abc",
270270
}
271271

@@ -439,6 +439,8 @@ func TestErrorTemplates(t *testing.T) {
439439
OnGenBugFixFn: emptyBugFixFn,
440440
})
441441

442+
inputStackTrace := " in Abcd at test.file:10"
443+
442444
fmt.Println(tmp.Pattern.String())
443445
fmt.Println(tmp2.Pattern.String())
444446

@@ -454,7 +456,10 @@ func TestErrorTemplates(t *testing.T) {
454456
}
455457

456458
for i, input := range inputs {
457-
matched := errorTemplates.Match(input + "\n" + lib.TestLanguage.StackTracePattern)
459+
matched := errorTemplates.Match(input + "\n" + inputStackTrace)
460+
if matched == nil {
461+
t.Fatalf("expected %s, got nil", expected[i].Name)
462+
}
458463

459464
if !reflect.DeepEqual(matched, expected[i]) {
460465
t.Fatalf("expected %s, got %s", expected[i].Name, matched.Name)
@@ -474,7 +479,10 @@ func TestErrorTemplates(t *testing.T) {
474479
}
475480

476481
for i, input := range inputs {
477-
matched := errorTemplates.Match(input + "\n" + lib.TestLanguage.StackTracePattern)
482+
matched := errorTemplates.Match(input + "\n" + inputStackTrace)
483+
if matched == nil {
484+
t.Fatalf("expected %s, got nil", expected[i].Name)
485+
}
478486

479487
if !reflect.DeepEqual(matched, expected[i]) {
480488
t.Fatalf("expected %s, got %s", expected[i].Name, matched.Name)
@@ -486,8 +494,8 @@ func TestErrorTemplates(t *testing.T) {
486494
inputs := []string{
487495
"This is a sample errorz\n",
488496
"AAnother exmaple error\n",
489-
"Another eaaxmaple error\n" + lib.TestLanguage.StackTracePattern,
490-
"This is a sample erroar\n" + lib.TestLanguage.StackTracePattern,
497+
"Another eaaxmaple error\n" + inputStackTrace,
498+
"This is a sample erroar\n" + inputStackTrace,
491499
}
492500

493501
for _, input := range inputs {
@@ -505,8 +513,11 @@ func TestErrorTemplates(t *testing.T) {
505513
"Another exmaple error",
506514
}
507515

508-
input := strings.Join(inputs, "\nin main at /home/user/main.py:1\n\n")
516+
input := strings.Join(inputs, "\n in main at /home/user/main.py:1\n\n")
509517
matched := errorTemplates.Match(input)
518+
if matched == nil {
519+
t.Fatalf("expected %s, got nil", tmp.Name)
520+
}
510521

511522
if !reflect.DeepEqual(matched, tmp) {
512523
t.Fatalf("expected %s, got %s", tmp.Name, matched.Name)
@@ -520,8 +531,11 @@ func TestErrorTemplates(t *testing.T) {
520531
"This is a sample error",
521532
}
522533

523-
input := strings.Join(inputs, "\nin main at /home/user/main.py:1\n\n")
534+
input := strings.Join(inputs, "\n in main at /home/user/main.py:1\n\n")
524535
matched := errorTemplates.Match(input)
536+
if matched == nil {
537+
t.Fatalf("expected %s, got nil", tmp2.Name)
538+
}
525539

526540
if !reflect.DeepEqual(matched, tmp2) {
527541
t.Fatalf("expected %s, got %s", tmp2.Name, matched.Name)

source.go

+5
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,11 @@ func ParseDocument(path string, r io.Reader, parser *sitter.Parser, selectLang *
543543
}
544544

545545
defer parser.Reset()
546+
547+
if selectLang.SitterLanguage == nil {
548+
return nil, fmt.Errorf("Language %s does not have a parser", selectLang.Name)
549+
}
550+
546551
parser.SetLanguage(selectLang.SitterLanguage)
547552

548553
var existingTree *sitter.Tree

0 commit comments

Comments
 (0)