mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-14 05:30:19 +00:00
fix(parser): extract all names from grouped var/const specs
extractGoVarConst used ChildByFieldName("name"), which returns only the first name field, so 'var a, b = 1, 2' and 'const ( C, D = 3, 4 )' surfaced only a/C. Iterate every "name"-field child so each declared identifier becomes its own symbol. Adds TestExtractGoVarConstMultiName.
This commit is contained in:
@@ -152,12 +152,20 @@ func extractGoVarConst(n *sitter.Node, content []byte, filename string) []protoc
|
|||||||
|
|
||||||
WalkTree(n, func(node *sitter.Node) bool {
|
WalkTree(n, func(node *sitter.Node) bool {
|
||||||
if node.Type() == "const_spec" || node.Type() == "var_spec" {
|
if node.Type() == "const_spec" || node.Type() == "var_spec" {
|
||||||
nameNode := node.ChildByFieldName("name")
|
// A spec may declare multiple names (e.g. var a, b = 1, 2);
|
||||||
if nameNode != nil {
|
// ChildByFieldName returns only the first, so iterate all "name" fields.
|
||||||
|
for i := 0; i < int(node.ChildCount()); i++ {
|
||||||
|
if node.FieldNameForChild(i) != "name" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nameNode := node.Child(i)
|
||||||
|
if nameNode == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
symbols = append(symbols, protocol.Symbol{
|
symbols = append(symbols, protocol.Symbol{
|
||||||
Name: GetNodeText(nameNode, content),
|
Name: GetNodeText(nameNode, content),
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Location: NodeLocation(node, filename),
|
Location: NodeLocation(nameNode, filename),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,44 @@ var globalVar = "test"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grouped var/const specs declare multiple names on one spec (var a, b = 1, 2);
|
||||||
|
// every name must surface as its own symbol, not just the first.
|
||||||
|
func TestExtractGoVarConstMultiName(t *testing.T) {
|
||||||
|
r := NewRegistry()
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
content := `package main
|
||||||
|
|
||||||
|
var a, b = 1, 2
|
||||||
|
|
||||||
|
const (
|
||||||
|
C, D = 3, 4
|
||||||
|
)
|
||||||
|
`
|
||||||
|
ctx := context.Background()
|
||||||
|
result, err := r.Parse(ctx, "test.go", []byte(content))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
symbols := ExtractSymbols(result.Tree, []byte(content), protocol.LangGo, "test.go")
|
||||||
|
want := map[string]protocol.SymbolKind{
|
||||||
|
"a": protocol.SymbolVariable,
|
||||||
|
"b": protocol.SymbolVariable,
|
||||||
|
"C": protocol.SymbolConstant,
|
||||||
|
"D": protocol.SymbolConstant,
|
||||||
|
}
|
||||||
|
got := make(map[string]protocol.SymbolKind)
|
||||||
|
for _, sym := range symbols {
|
||||||
|
got[sym.Name] = sym.Kind
|
||||||
|
}
|
||||||
|
for name, kind := range want {
|
||||||
|
if got[name] != kind {
|
||||||
|
t.Errorf("symbol %q: got kind %q, want %q (symbols: %+v)", name, got[name], kind, symbols)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestExtractJSSymbols(t *testing.T) {
|
func TestExtractJSSymbols(t *testing.T) {
|
||||||
r := NewRegistry()
|
r := NewRegistry()
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
|
|||||||
Reference in New Issue
Block a user