@@ -1685,7 +1685,7 @@ def GetDetailedDiagnostic( self, request_data ):
16851685 message = diagnostic [ 'message' ]
16861686 try :
16871687 code = diagnostic [ 'code' ]
1688- message += f' [{ code } ]'
1688+ message += f' [{ code } ]' # noqa
16891689 except KeyError :
16901690 pass
16911691
@@ -1785,6 +1785,18 @@ def GetSubcommandsMap( self ):
17851785 lambda self , request_data , args : self .GetType ( request_data )
17861786 )
17871787
1788+ if ( self ._server_capabilities and
1789+ _IsCapabilityProvided ( self ._server_capabilities ,
1790+ 'typeHierarchyProvider' ) ):
1791+ commands [ 'TypeHierarchy' ] = (
1792+ lambda self , request_data , args :
1793+ self .InitialHierarchy ( request_data , [ 'type' ] )
1794+ )
1795+ commands [ 'ResolveTypeHierarchyItem' ] = (
1796+ lambda self , request_data , args :
1797+ self .Hierarchy ( request_data , [ * args , 'type' ] )
1798+ )
1799+
17881800 if ( self ._server_capabilities and
17891801 _IsCapabilityProvided ( self ._server_capabilities ,
17901802 'callHierarchyProvider' ) ):
@@ -1796,6 +1808,14 @@ def GetSubcommandsMap( self ):
17961808 lambda self , request_data , args :
17971809 self .CallHierarchy ( request_data , [ 'incoming' ] )
17981810 )
1811+ commands [ 'CallHierarchy' ] = (
1812+ lambda self , request_data , args :
1813+ self .InitialHierarchy ( request_data , [ 'call' ] )
1814+ )
1815+ commands [ 'ResolveCallHierarchyItem' ] = (
1816+ lambda self , request_data , args :
1817+ self .Hierarchy ( request_data , [ * args , 'call' ] )
1818+ )
17991819
18001820 commands .update ( self .GetCustomSubcommands () )
18011821
@@ -2643,14 +2663,105 @@ def GoToDocumentOutline( self, request_data ):
26432663 return _SymbolInfoListToGoTo ( request_data , result )
26442664
26452665
2666+ def InitialHierarchy ( self , request_data , args ):
2667+ if not self .ServerIsReady ():
2668+ raise RuntimeError ( 'Server is initializing. Please wait.' )
2669+
2670+ kind = args [ 0 ]
2671+
2672+ self ._UpdateServerWithFileContents ( request_data )
2673+ request_id = self .GetConnection ().NextRequestId ()
2674+ message = lsp .PrepareHierarchy ( request_id , request_data , kind .title () )
2675+ prepare_response = self .GetConnection ().GetResponse (
2676+ request_id ,
2677+ message ,
2678+ REQUEST_TIMEOUT_COMMAND )
2679+ preparation_item = prepare_response .get ( 'result' ) or []
2680+ if not preparation_item :
2681+ raise RuntimeError ( f'No { kind } hierarchy found.' )
2682+
2683+ assert len ( preparation_item ) == 1 , (
2684+ 'Not available: Multiple hierarchies were received, '
2685+ 'this is not currently supported.' )
2686+
2687+ preparation_item [ 0 ][ 'locations' ] = [
2688+ responses .BuildGoToResponseFromLocation (
2689+ * _LspLocationToLocationAndDescription ( request_data ,
2690+ location ,
2691+ 'selectionRange' ) )
2692+ for location in preparation_item ]
2693+ kind_string = lsp .SYMBOL_KIND [ preparation_item [ 0 ][ 'kind' ] ]
2694+ preparation_item [ 0 ][ 'kind' ] = kind_string
2695+ return preparation_item
2696+
2697+
2698+ def Hierarchy ( self , request_data , args ):
2699+ if not self .ServerIsReady ():
2700+ raise RuntimeError ( 'Server is initializing. Please wait.' )
2701+
2702+ preparation_item , direction , kind = args
2703+
2704+ if item := ( preparation_item .get ( 'from' ) or
2705+ preparation_item .get ( 'to' ) ):
2706+ preparation_item = item
2707+ else :
2708+ del preparation_item [ 'locations' ]
2709+ kind_number = lsp .SYMBOL_KIND .index ( preparation_item [ 'kind' ] )
2710+ preparation_item [ 'kind' ] = kind_number
2711+
2712+ if kind == 'call' :
2713+ direction += 'Calls'
2714+ self ._UpdateServerWithFileContents ( request_data )
2715+ request_id = self .GetConnection ().NextRequestId ()
2716+ message = lsp .Hierarchy ( request_id , kind , direction , preparation_item )
2717+ response = self .GetConnection ().GetResponse ( request_id ,
2718+ message ,
2719+ REQUEST_TIMEOUT_COMMAND )
2720+
2721+ result = response .get ( 'result' )
2722+ if result :
2723+ for item in result :
2724+ if kind == 'call' :
2725+ name_and_kind_key = 'to' if direction == 'outgoingCalls' else 'from'
2726+ hierarchy_item = item [ name_and_kind_key ]
2727+ kind_string = lsp .SYMBOL_KIND [ hierarchy_item [ 'kind' ] ]
2728+ item [ 'kind' ] = kind_string
2729+ item [ 'name' ] = hierarchy_item [ 'name' ]
2730+ lsp_locations = [ {
2731+ 'uri' : hierarchy_item [ 'uri' ],
2732+ 'range' : r }
2733+ for r in item [ 'fromRanges' ] ]
2734+ item [ 'locations' ] = [
2735+ responses .BuildGoToResponseFromLocation (
2736+ * _LspLocationToLocationAndDescription ( request_data , location ) )
2737+ for location in lsp_locations ]
2738+
2739+ if direction == 'incomingCalls' :
2740+ item [ 'root_location' ] = responses .BuildGoToResponseFromLocation (
2741+ * _LspLocationToLocationAndDescription ( request_data ,
2742+ hierarchy_item ,
2743+ 'selectionRange' ) )
2744+ else :
2745+ item [ 'kind' ] = lsp .SYMBOL_KIND [ item [ 'kind' ] ]
2746+ item [ 'locations' ] = [
2747+ responses .BuildGoToResponseFromLocation (
2748+ * _LspLocationToLocationAndDescription ( request_data , location ) )
2749+ for location in [ item ] ]
2750+ return result
2751+ if kind == 'call' :
2752+ raise RuntimeError (
2753+ f'No { direction .rstrip ( "Calls" ) } { kind } s found.' )
2754+ else :
2755+ raise RuntimeError ( f'No { direction } found.' )
2756+
26462757
26472758 def CallHierarchy ( self , request_data , args ):
26482759 if not self .ServerIsReady ():
26492760 raise RuntimeError ( 'Server is initializing. Please wait.' )
26502761
26512762 self ._UpdateServerWithFileContents ( request_data )
26522763 request_id = self .GetConnection ().NextRequestId ()
2653- message = lsp .PrepareCallHierarchy ( request_id , request_data )
2764+ message = lsp .PrepareHierarchy ( request_id , request_data , 'Call' )
26542765 prepare_response = self .GetConnection ().GetResponse (
26552766 request_id ,
26562767 message ,
@@ -2666,7 +2777,10 @@ def CallHierarchy( self, request_data, args ):
26662777 preparation_item = preparation_item [ 0 ]
26672778
26682779 request_id = self .GetConnection ().NextRequestId ()
2669- message = lsp .CallHierarchy ( request_id , args [ 0 ], preparation_item )
2780+ message = lsp .Hierarchy ( request_id ,
2781+ 'call' ,
2782+ args [ 0 ] + 'Calls' ,
2783+ preparation_item )
26702784 response = self .GetConnection ().GetResponse ( request_id ,
26712785 message ,
26722786 REQUEST_TIMEOUT_COMMAND )
@@ -3282,7 +3396,9 @@ def BuildGoToLocationFromSymbol( symbol ):
32823396 return locations
32833397
32843398
3285- def _LspLocationToLocationAndDescription ( request_data , location ):
3399+ def _LspLocationToLocationAndDescription ( request_data ,
3400+ location ,
3401+ range_property = 'range' ):
32863402 """Convert a LSP Location to a ycmd location."""
32873403 try :
32883404 filename = lsp .UriToFilePath ( location [ 'uri' ] )
@@ -3299,9 +3415,10 @@ def _LspLocationToLocationAndDescription( request_data, location ):
32993415 'GoTo location' )
33003416 file_contents = []
33013417
3418+ range = location [ range_property ]
33023419 return _BuildLocationAndDescription ( filename ,
33033420 file_contents ,
3304- location [ ' range' ] [ 'start' ] )
3421+ range [ 'start' ] )
33053422
33063423
33073424def _LspToYcmdLocation ( file_contents , location ):
0 commit comments