diff --git a/internal/parser/symbols.go b/internal/parser/symbols.go index 9bcb524..6b3538b 100644 --- a/internal/parser/symbols.go +++ b/internal/parser/symbols.go @@ -152,12 +152,20 @@ func extractGoVarConst(n *sitter.Node, content []byte, filename string) []protoc WalkTree(n, func(node *sitter.Node) bool { if node.Type() == "const_spec" || node.Type() == "var_spec" { - nameNode := node.ChildByFieldName("name") - if nameNode != nil { + // A spec may declare multiple names (e.g. var a, b = 1, 2); + // 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{ Name: GetNodeText(nameNode, content), Kind: kind, - Location: NodeLocation(node, filename), + Location: NodeLocation(nameNode, filename), }) } } diff --git a/internal/parser/symbols_test.go b/internal/parser/symbols_test.go index 1bf796b..fed45dc 100644 --- a/internal/parser/symbols_test.go +++ b/internal/parser/symbols_test.go @@ -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) { r := NewRegistry() defer r.Close()