Skip to content

Commit

Permalink
Allow choosing "which range" should be used when converting LSP Locat…
Browse files Browse the repository at this point in the history
…ion-like objects

This fixes all of the remaining bugs when requesting outgoing calls of
an incoming call hierarchy item.

Specifically, we *want* `selectionRange` for the hierarchy root and for
`root_location` of incoming call hierarchy items.

JDT is special and needs `range` in the second case.
  • Loading branch information
bstaletic committed Jun 13, 2024
1 parent d6010fc commit 9e73042
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
15 changes: 15 additions & 0 deletions ycmd/completers/java/java_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,3 +650,18 @@ def GetServerName( self ):

def GetCommandLine( self ):
return self._command


def Hierarchy( self, request_data, args ):
# JDT.LS is a special snowflake and needs special snowflake treatement
# See: https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3184
result = super().Hierarchy( request_data, args )
preparation_item, direction, kind = args
if kind == 'call' and direction == 'incoming':
for item in result:
# The base class does almost the same,
# but uses `selectionRange` instead of `range`.
item[ 'root_location' ] = responses.BuildGoToResponseFromLocation(
*language_server_completer._LspLocationToLocationAndDescription(
request_data, item[ 'from' ] ) )
return result
19 changes: 11 additions & 8 deletions ycmd/completers/language_server/language_server_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2686,7 +2686,9 @@ def InitialHierarchy( self, request_data, args ):

preparation_item[ 0 ][ 'locations' ] = [
responses.BuildGoToResponseFromLocation(
*_LspLocationToLocationAndDescription( request_data, location ) )
*_LspLocationToLocationAndDescription( request_data,
location,
'selectionRange' ) )
for location in preparation_item ]
kind_string = lsp.SYMBOL_KIND[ preparation_item[ 0 ][ 'kind' ] ]
preparation_item[ 0 ][ 'kind' ] = kind_string
Expand Down Expand Up @@ -2735,12 +2737,10 @@ def Hierarchy( self, request_data, args ):
for location in lsp_locations ]

if direction == 'incomingCalls':
loc = {
'uri': hierarchy_item[ 'uri' ],
'range': hierarchy_item[ 'range' ]
}
item[ 'root_location' ] = responses.BuildGoToResponseFromLocation(
*_LspLocationToLocationAndDescription( request_data, loc ) )
*_LspLocationToLocationAndDescription( request_data,
hierarchy_item,
'selectionRange' ) )
else:
item[ 'kind' ] = lsp.SYMBOL_KIND[ item[ 'kind' ] ]
item[ 'locations' ] = [
Expand Down Expand Up @@ -3396,7 +3396,9 @@ def BuildGoToLocationFromSymbol( symbol ):
return locations


def _LspLocationToLocationAndDescription( request_data, location ):
def _LspLocationToLocationAndDescription( request_data,
location,
range_property = 'range' ):
"""Convert a LSP Location to a ycmd location."""
try:
filename = lsp.UriToFilePath( location[ 'uri' ] )
Expand All @@ -3413,9 +3415,10 @@ def _LspLocationToLocationAndDescription( request_data, location ):
'GoTo location' )
file_contents = []

range = location[ range_property ]
return _BuildLocationAndDescription( filename,
file_contents,
location[ 'range' ][ 'start' ] )
range[ 'start' ] )


def _LspToYcmdLocation( file_contents, location ):
Expand Down
6 changes: 3 additions & 3 deletions ycmd/tests/rust/subcommands_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,14 +635,14 @@ def test_Subcommands_IncomingCallHierarchy( self, app ):
LocationMatcher( filepath, 6, 11 ) ),
# rust-analyzer always returns column 1 for root_location,
# which is useless for us... unfortunately.
'root_location': LocationMatcher( filepath, 5, 1 )
'root_location': LocationMatcher( filepath, 5, 4 )
} ),
has_entries( {
'locations': contains_exactly(
LocationMatcher( filepath, 11, 5 ) ),
# rust-analyzer always returns column 1 for root_location,
# which is useless for us... unfortunately.
'root_location': LocationMatcher( filepath, 9, 1 )
'root_location': LocationMatcher( filepath, 9, 4 )
} )
),
requests.codes.ok ],
Expand All @@ -653,7 +653,7 @@ def test_Subcommands_IncomingCallHierarchy( self, app ):
LocationMatcher( filepath, 10, 13 ) ),
# rust-analyzer always returns column 1 for root_location,
# which is useless for us... unfortunately.
'root_location': LocationMatcher( filepath, 9, 1 )
'root_location': LocationMatcher( filepath, 9, 4 )
} )
),
requests.codes.ok ],
Expand Down

0 comments on commit 9e73042

Please sign in to comment.