Skip to content

Commit

Permalink
Handle empty object capabilities as truthy where applicable
Browse files Browse the repository at this point in the history
Another one of those "be vscode plox" things.
Servers seem to expect things like
{
	"capabilities": {
		"whateverProvider": {}
	}
}
to mean that the server is really a provider of whatever.
Earliest offender is the swift server being a code action provider.
  • Loading branch information
bstaletic committed Sep 14, 2023
1 parent 18b4d49 commit a8d1a8b
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions ycmd/completers/language_server/language_server_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,8 @@ def SignatureHelpAvailable( self ):
if not self.ServerIsReady():
return responses.SignatureHelpAvailalability.PENDING

if bool( self._server_capabilities.get( 'signatureHelpProvider' ) ):
if _IsCapabilityProvided( self._server_capabilities,
'signatureHelpProvider' ):
return responses.SignatureHelpAvailalability.AVAILABLE
else:
return responses.SignatureHelpAvailalability.NOT_AVAILABLE
Expand All @@ -1506,7 +1507,8 @@ def ComputeSignaturesInner( self, request_data ):
if not self.ServerIsReady():
return {}

if not self._server_capabilities.get( 'signatureHelpProvider' ):
if not _IsCapabilityProvided( self._server_capabilities,
'signatureHelpProvider' ):
return {}

self._UpdateServerWithCurrentFileContents( request_data )
Expand Down Expand Up @@ -1551,8 +1553,9 @@ def ComputeSemanticTokens( self, request_data ):
if not self._semantic_token_atlas:
return {}

range_supported = self._server_capabilities[ 'semanticTokensProvider' ].get(
'range', False )
range_supported = _IsCapabilityProvided(
self._server_capabilities[ 'semanticTokensProvider' ],
'range' )

self._UpdateServerWithCurrentFileContents( request_data )

Expand Down Expand Up @@ -1588,7 +1591,8 @@ def ComputeInlayHints( self, request_data ):
if not self._ServerIsInitialized():
return []

if 'inlayHintProvider' not in self._server_capabilities:
if not _IsCapabilityProvided( self._server_capabilities,
'inlayHintProvider' ):
return []

self._UpdateServerWithCurrentFileContents( request_data )
Expand Down Expand Up @@ -1763,7 +1767,8 @@ def GetSubcommandsMap( self ):
)

if ( self._server_capabilities and
'callHierarchyProvider' in self._server_capabilities ):
_IsCapabilityProvided( self._server_capabilities,
'callHierarchyProvider' ) ):
commands[ 'GoToCallees' ] = (
lambda self, request_data, args:
self.CallHierarchy( request_data, [ 'outgoing' ] )
Expand All @@ -1787,9 +1792,10 @@ def _GetSubcommandProvider( self, provider_list ):

for providers in provider_list:
if isinstance( providers, tuple ):
if all( capabilities.get( provider ) for provider in providers ):
if all( _IsCapabilityProvided( capabilities, provider )
for provider in providers ):
return providers
if capabilities.get( providers ):
if _IsCapabilityProvided( capabilities, providers ):
return providers
return None

Expand Down Expand Up @@ -2345,11 +2351,7 @@ def _SetUpSemanticTokenAtlas( self, capabilities: dict ):
if server_config is None:
return

server_full_support = server_config.get( 'full' )
if server_full_support == {}:
server_full_support = True

if not server_full_support:
if not _IsCapabilityProvided( server_config, 'full' ):
return

self._semantic_token_atlas = TokenAtlas( server_config[ 'legend' ] )
Expand Down Expand Up @@ -3539,6 +3541,11 @@ def DecodeModifiers( self, tokenModifiers ):
return tokens


def _IsCapabilityProvided( capabilities, query ):
capability = capabilities.get( query )
return bool( capability ) or capability == {}


def RetryOnFailure( expected_error_codes, num_retries = 3 ):
for i in range( num_retries ):
try:
Expand Down

0 comments on commit a8d1a8b

Please sign in to comment.