Skip to content

Commit 961aceb

Browse files
author
Christian Weichel
committed
Fix #10 by hard de-dupping documentSymbols
1 parent 3551584 commit 961aceb

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

Diff for: handler/handler.go

+33-20
Original file line numberDiff line numberDiff line change
@@ -587,16 +587,21 @@ func (handler *InoHandler) transformClangdResult(method string, uri lsp.Document
587587
handler.cpp2inoTextEdit(&(*r)[index], uri)
588588
}
589589
case "textDocument/documentSymbol":
590-
r := result.(*[]*documentSymbolOrSymbolInformation)
590+
r, ok := result.(*[]*documentSymbolOrSymbolInformation)
591+
if !ok || len(*r) == 0 {
592+
return result
593+
}
594+
591595
slice := *r
592-
if len(slice) > 0 && slice[0].DocumentSymbol != nil {
596+
if slice[0].DocumentSymbol != nil {
593597
// Treat the input as []DocumentSymbol
594598
symbols := make([]DocumentSymbol, len(slice))
595599
for index := range slice {
596600
symbols[index] = *slice[index].DocumentSymbol
597601
}
598-
result = handler.cpp2inoDocumentSymbols(symbols, uri)
599-
} else if len(slice) > 0 && slice[0].SymbolInformation != nil {
602+
return handler.cpp2inoDocumentSymbols(symbols, uri)
603+
}
604+
if slice[0].SymbolInformation != nil {
600605
// Treat the input as []SymbolInformation
601606
symbols := make([]lsp.SymbolInformation, len(slice))
602607
for index := range slice {
@@ -605,11 +610,11 @@ func (handler *InoHandler) transformClangdResult(method string, uri lsp.Document
605610
for index := range symbols {
606611
handler.cpp2inoLocation(&symbols[index].Location)
607612
}
608-
result = symbols
613+
return symbols
609614
}
610615
case "textDocument/rename":
611616
r := result.(*lsp.WorkspaceEdit)
612-
result = handler.cpp2inoWorkspaceEdit(r)
617+
return handler.cpp2inoWorkspaceEdit(r)
613618
case "workspace/symbol":
614619
r := result.(*[]lsp.SymbolInformation)
615620
for index := range *r {
@@ -711,29 +716,37 @@ func (handler *InoHandler) cpp2inoDocumentSymbols(origSymbols []DocumentSymbol,
711716
if !ok || len(origSymbols) == 0 {
712717
return origSymbols
713718
}
714-
newSymbols := make([]DocumentSymbol, len(origSymbols))
715-
j := 0
719+
720+
symbolIdx := make(map[string]*DocumentSymbol)
716721
for i := 0; i < len(origSymbols); i++ {
717722
symbol := &origSymbols[i]
718723
symbol.Range.Start.Line = data.sourceLineMap[symbol.Range.Start.Line]
719724
symbol.Range.End.Line = data.sourceLineMap[symbol.Range.End.Line]
720725

721726
duplicate := false
722-
for k := 0; k < j; k++ {
723-
if symbol.Name == newSymbols[k].Name && symbol.Range.Start.Line == newSymbols[k].Range.Start.Line {
724-
duplicate = true
725-
break
727+
other, duplicate := symbolIdx[symbol.Name]
728+
if duplicate {
729+
// we prefer symbols later in the file due to the function header generation. E.g. if one has a function `void foo() {}` somehwre in the code
730+
// the code generation will add a `void foo();` header at the beginning of the cpp file. We care about the function body later in the file, not
731+
// the header early on.
732+
if symbol.Range.Start.Line < other.Range.Start.Line {
733+
continue
726734
}
727735
}
728-
if !duplicate {
729-
symbol.SelectionRange.Start.Line = data.sourceLineMap[symbol.SelectionRange.Start.Line]
730-
symbol.SelectionRange.End.Line = data.sourceLineMap[symbol.SelectionRange.End.Line]
731-
symbol.Children = handler.cpp2inoDocumentSymbols(symbol.Children, uri)
732-
newSymbols[j] = *symbol
733-
j++
734-
}
736+
737+
symbol.SelectionRange.Start.Line = data.sourceLineMap[symbol.SelectionRange.Start.Line]
738+
symbol.SelectionRange.End.Line = data.sourceLineMap[symbol.SelectionRange.End.Line]
739+
symbol.Children = handler.cpp2inoDocumentSymbols(symbol.Children, uri)
740+
symbolIdx[symbol.Name] = symbol
741+
}
742+
743+
newSymbols := make([]DocumentSymbol, len(symbolIdx))
744+
j := 0
745+
for _, s := range symbolIdx {
746+
newSymbols[j] = *s
747+
j++
735748
}
736-
return newSymbols[:j]
749+
return newSymbols
737750
}
738751

739752
// FromClangd handles a message received from clangd.

0 commit comments

Comments
 (0)