Skip to content

Commit 2bfe8de

Browse files
committed
fix: resolve Go duplicate references in tree-sitter queries (#5367)
- Replace broad statement captures with function-scoped queries - Eliminates overlapping captures that caused duplicate references - Improves search quality and indexing performance for Go projects - Add test to validate no duplicate line ranges are captured - Maintains backward compatibility with existing functionality Fixes #5367
1 parent a57b0b6 commit 2bfe8de

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

src/services/tree-sitter/__tests__/inspectGo.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,49 @@ describe("Go Tree-sitter Parser", () => {
2020
const result = await testParseSourceCodeDefinitions("file.go", sampleGoContent, testOptions)
2121
expect(result).toBeDefined()
2222
})
23+
24+
// Test 3: Verify no duplicate captures for Go constructs
25+
it("should not create duplicate captures for Go constructs", async () => {
26+
const testOptions = {
27+
language: "go",
28+
wasmFile: "tree-sitter-go.wasm",
29+
queryString: goQuery,
30+
extKey: "go",
31+
}
32+
33+
const result = await testParseSourceCodeDefinitions("file.go", sampleGoContent, testOptions)
34+
35+
// Check that we have results
36+
expect(result).toBeDefined()
37+
expect(typeof result).toBe("string")
38+
expect(result!.length).toBeGreaterThan(0)
39+
40+
// Parse the result to extract line ranges and function names
41+
const lines = result!.split("\n").filter((line) => line.trim() && !line.startsWith("#"))
42+
43+
// Extract line ranges from the format "startLine--endLine | content"
44+
const lineRanges = lines
45+
.map((line) => {
46+
const match = line.match(/^(\d+)--(\d+)/)
47+
return match ? `${match[1]}-${match[2]}` : null
48+
})
49+
.filter(Boolean)
50+
51+
// Check for duplicate line ranges (which was the original problem)
52+
const uniqueLineRanges = [...new Set(lineRanges)]
53+
expect(lineRanges.length).toBe(uniqueLineRanges.length)
54+
55+
// Verify we capture function-based constructs instead of broad statements
56+
// The result should contain function definitions that use Go constructs
57+
expect(result).toContain("TestGoroutineDefinition")
58+
expect(result).toContain("TestDeferDefinition")
59+
expect(result).toContain("TestSelectDefinition")
60+
expect(result).toContain("TestChannelDefinition")
61+
62+
// Should not contain raw go/defer/select statements without function context
63+
// (our fix should prevent capturing these as standalone definitions)
64+
expect(result).not.toMatch(/\|\s*go\s+func\(\)/) // raw go statement
65+
expect(result).not.toMatch(/\|\s*defer\s+func\(\)/) // raw defer statement
66+
expect(result).not.toMatch(/\|\s*select\s*{/) // raw select statement
67+
})
2368
})

src/services/tree-sitter/queries/go.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,28 @@ export default `
4444
(method_declaration
4545
name: (field_identifier) @name.definition.method)
4646
47-
; Channel operations
48-
(channel_type) @name.definition.channel
47+
; Functions containing goroutines (instead of capturing go statements)
48+
(function_declaration
49+
name: (identifier) @name.definition.function
50+
body: (block
51+
(go_statement))) @definition.goroutine_function
4952
50-
; Goroutine declarations
51-
(go_statement) @name.definition.goroutine
53+
; Functions containing defer statements
54+
(function_declaration
55+
name: (identifier) @name.definition.function
56+
body: (block
57+
(defer_statement))) @definition.defer_function
5258
53-
; Defer statements
54-
(defer_statement) @name.definition.defer
59+
; Functions containing select statements
60+
(function_declaration
61+
name: (identifier) @name.definition.function
62+
body: (block
63+
(select_statement))) @definition.select_function
5564
56-
; Select statements
57-
(select_statement) @name.definition.select
65+
; Functions with channel parameters or operations
66+
(function_declaration
67+
name: (identifier) @name.definition.function
68+
parameters: (parameter_list
69+
(parameter_declaration
70+
type: (channel_type)))) @definition.channel_function
5871
`

0 commit comments

Comments
 (0)