@@ -535,16 +535,15 @@ func (sc *LSPServiceClientBase) populateDocumentSymbolCache(ctx context.Context,
535535 sc .Log .Error (err , "documentSymbol request failed" , "uri" , uri )
536536 continue
537537 }
538- for _ , symbol := range findDocumentSymbolsAtLocation (uri , documentSymbols , definition ) {
538+ if symbol , ok := findDocumentSymbolAtLocation (uri , documentSymbols , definition ); ok {
539539 wsSymbolsForDefinitions [workspaceSymbolKey (symbol )] = symbol
540540 }
541541 }
542542 definitionSymbols := []protocol.WorkspaceSymbol {}
543543 for _ , symbol := range wsSymbolsForDefinitions {
544544 definitionSymbols = append (definitionSymbols , symbol )
545545 }
546- // attach all definitions found with the original match, so that
547- // we can determine it as a referenced symbol
546+ // attach all definitions found with the original match
548547 pair := WorkspaceSymbolDefinitionsPair {
549548 WorkspaceSymbol : protocol.WorkspaceSymbol {
550549 Location : protocol.OrPLocation_workspace_symbol {
@@ -564,6 +563,7 @@ func (sc *LSPServiceClientBase) populateDocumentSymbolCache(ctx context.Context,
564563 }
565564 workspaceSymbols [workspaceSymbolKey (pair .WorkspaceSymbol )] = pair
566565 }
566+
567567 workspaceSymbolsList := []WorkspaceSymbolDefinitionsPair {}
568568 for _ , pair := range workspaceSymbols {
569569 workspaceSymbolsList = append (workspaceSymbolsList , pair )
@@ -725,19 +725,19 @@ func (sc *LSPServiceClientBase) searchContentForWorkspaceSymbols(ctx context.Con
725725 },
726726 },
727727 }
728- matchingSymbols := findDocumentSymbolsAtLocation (fileURI , symbols , protoLoc )
729- positions = append (positions , matchingSymbols ... )
730- positions = append ( positions , protocol. WorkspaceSymbol {
731- Location : protocol.OrPLocation_workspace_symbol {
732- Value : protoLoc ,
733- } ,
734- BaseSymbolInformation : protocol. BaseSymbolInformation {
735- Name : scanner . Text ()[ loc [ 0 ]: loc [ 1 ]],
736- Kind : 0 ,
737- Tags : []protocol. SymbolTag {} ,
738- ContainerName : "" ,
739- },
740- })
728+ if symbol , ok := findDocumentSymbolAtLocation (fileURI , symbols , protoLoc ); ok {
729+ positions = append (positions , symbol )
730+ } else {
731+ positions = append ( positions , protocol.WorkspaceSymbol {
732+ Location : protocol. OrPLocation_workspace_symbol {
733+ Value : protoLoc ,
734+ },
735+ BaseSymbolInformation : protocol. BaseSymbolInformation {
736+ Name : scanner . Text ()[ loc [ 0 ]: loc [ 1 ]] ,
737+ Kind : 0 ,
738+ } ,
739+ })
740+ }
741741 }
742742 lineNumber ++
743743 }
@@ -772,37 +772,44 @@ func (sc *LSPServiceClientBase) getDefinitionForPosition(ctx context.Context, ur
772772 return res
773773}
774774
775- func findDocumentSymbolsAtLocation (docURI uri.URI , symbols []protocol.DocumentSymbol , defLoc protocol.Location ) []protocol.WorkspaceSymbol {
776- var out []protocol.WorkspaceSymbol
777- findSymbolsAtLocationRecursive (docURI , symbols , defLoc , "" , & out )
778- return out
779- }
780-
781- func findSymbolsAtLocationRecursive (docURI uri.URI , symbols []protocol.DocumentSymbol , defLoc protocol.Location , containerName string , out * []protocol.WorkspaceSymbol ) {
782- for _ , symbol := range symbols {
783- symRange := preferredRange (symbol )
784- if rangeOverlaps (symRange , defLoc .Range ) {
785- ws := protocol.WorkspaceSymbol {
786- BaseSymbolInformation : protocol.BaseSymbolInformation {
787- Name : symbol .Name ,
788- Kind : symbol .Kind ,
789- Tags : symbol .Tags ,
790- ContainerName : containerName ,
791- },
792- Location : protocol.OrPLocation_workspace_symbol {
793- Value : protocol.Location {
794- URI : protocol .DocumentURI (docURI ),
795- Range : symRange ,
796- },
797- },
775+ func findDocumentSymbolAtLocation (docURI uri.URI , symbols []protocol.DocumentSymbol , defLoc protocol.Location ) (protocol.WorkspaceSymbol , bool ) {
776+ var bestSymbol protocol.WorkspaceSymbol
777+ var bestLength uint64
778+ found := false
779+
780+ var traverse func ([]protocol.DocumentSymbol , string )
781+ traverse = func (symbols []protocol.DocumentSymbol , containerName string ) {
782+ for _ , symbol := range symbols {
783+ symRange := preferredRange (symbol )
784+ if rangeOverlaps (symRange , defLoc .Range ) {
785+ length := rangeLength (symRange )
786+ if ! found || length < bestLength {
787+ bestSymbol = protocol.WorkspaceSymbol {
788+ BaseSymbolInformation : protocol.BaseSymbolInformation {
789+ Name : symbol .Name ,
790+ Kind : symbol .Kind ,
791+ Tags : symbol .Tags ,
792+ ContainerName : containerName ,
793+ },
794+ Location : protocol.OrPLocation_workspace_symbol {
795+ Value : protocol.Location {
796+ URI : protocol .DocumentURI (docURI ),
797+ Range : symRange ,
798+ },
799+ },
800+ }
801+ bestLength = length
802+ found = true
803+ }
804+ }
805+ if len (symbol .Children ) > 0 {
806+ traverse (symbol .Children , symbol .Name )
798807 }
799- * out = append (* out , ws )
800- }
801- // Traverse children
802- if len (symbol .Children ) > 0 {
803- findSymbolsAtLocationRecursive (docURI , symbol .Children , defLoc , symbol .Name , out )
804808 }
805809 }
810+
811+ traverse (symbols , "" )
812+ return bestSymbol , found
806813}
807814
808815func rangeOverlaps (r1 , r2 protocol.Range ) bool {
@@ -825,3 +832,15 @@ func positionLessEqual(p1, p2 protocol.Position) bool {
825832 }
826833 return false
827834}
835+
836+ func rangeLength (r protocol.Range ) uint64 {
837+ lineDiff := int64 (r .End .Line ) - int64 (r .Start .Line )
838+ if lineDiff < 0 {
839+ lineDiff = 0
840+ }
841+ charDiff := int64 (r .End .Character ) - int64 (r .Start .Character )
842+ if charDiff < 0 {
843+ charDiff = 0
844+ }
845+ return (uint64 (lineDiff ) << 32 ) | uint64 (charDiff )
846+ }
0 commit comments