@@ -34,6 +34,10 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
34
34
location: location_t
35
35
}
36
36
37
+ # Location in annotations from OTP 23 and previous contain only line number.
38
+ # OTP 24 annotations may also be {line, column}, depending on compiler
39
+ # options.
40
+ @ typep erl_location_t :: non_neg_integer | { non_neg_integer , non_neg_integer }
37
41
@ typep key_t :: :modules | :functions | :types | :callbacks
38
42
@ typep symbol_t :: module | { module , atom , non_neg_integer }
39
43
@ typep state_t :: % {
@@ -223,15 +227,15 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
223
227
224
228
## Helpers
225
229
226
- defp find_module_line ( module , path ) do
230
+ defp find_module_location ( module , path ) do
227
231
if String . ends_with? ( path , ".erl" ) do
228
232
ErlangSourceFile . module_line ( path )
229
233
else
230
234
SourceFile . module_line ( module )
231
235
end
232
236
end
233
237
234
- defp find_function_line ( module , function , arity , path ) do
238
+ defp find_function_location ( module , function , arity , path ) do
235
239
if String . ends_with? ( path , ".erl" ) do
236
240
ErlangSourceFile . function_line ( path , function )
237
241
else
@@ -360,8 +364,8 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
360
364
chunked_module_paths
361
365
|> do_process_chunked ( fn chunk ->
362
366
for { module , path } <- chunk do
363
- line = find_module_line ( module , path )
364
- build_result ( :modules , module , path , line )
367
+ location = find_module_location ( module , path )
368
+ build_result ( :modules , module , path , location )
365
369
end
366
370
end )
367
371
end )
@@ -373,9 +377,9 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
373
377
Code . ensure_loaded? ( module ) ,
374
378
{ function , arity } <- module . module_info ( :exports ) do
375
379
{ function , arity } = SourceFile . strip_macro_prefix ( { function , arity } )
376
- line = find_function_line ( module , function , arity , path )
380
+ location = find_function_location ( module , function , arity , path )
377
381
378
- build_result ( :functions , { module , function , arity } , path , line )
382
+ build_result ( :functions , { module , function , arity } , path , location )
379
383
end
380
384
end )
381
385
end )
@@ -388,13 +392,13 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
388
392
{ kind , { type , type_ast , args } } <-
389
393
ElixirSense.Core.Normalized.Typespec . get_types ( module ) ,
390
394
kind in [ :type , :opaque ] do
391
- line =
395
+ location =
392
396
case type_ast do
393
- { _ , line , _ , _ } -> line
394
- { _ , line , _ } -> line
397
+ { _ , location , _ , _ } -> location
398
+ { _ , location , _ } -> location
395
399
end
396
400
397
- build_result ( :types , { module , type , length ( args ) } , path , line )
401
+ build_result ( :types , { module , type , length ( args ) } , path , location )
398
402
end
399
403
end )
400
404
end )
@@ -405,11 +409,11 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
405
409
for { module , path } <- chunk ,
406
410
function_exported? ( module , :behaviour_info , 1 ) ,
407
411
# TODO: Don't call into here directly
408
- { { callback , arity } , [ { :type , line , _ , _ } ] } <-
412
+ { { callback , arity } , [ { :type , location , _ , _ } ] } <-
409
413
ElixirSense.Core.Normalized.Typespec . get_callbacks ( module ) do
410
414
{ callback , arity } = SourceFile . strip_macro_prefix ( { callback , arity } )
411
415
412
- build_result ( :callbacks , { module , callback , arity } , path , line )
416
+ build_result ( :callbacks , { module , callback , arity } , path , location )
413
417
end
414
418
end )
415
419
end )
@@ -477,23 +481,14 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
477
481
end )
478
482
end
479
483
480
- @ spec build_result (
481
- key_t ,
482
- symbol_t ,
483
- String . t ( ) ,
484
- nil | non_neg_integer | { non_neg_integer , non_neg_integer }
485
- ) :: symbol_information_t
486
- defp build_result ( key , symbol , path , { line , _ } ) do
487
- build_result ( key , symbol , path , line )
488
- end
489
-
490
- defp build_result ( key , symbol , path , line ) do
484
+ @ spec build_result ( key_t , symbol_t , String . t ( ) , nil | erl_location_t ) :: symbol_information_t
485
+ defp build_result ( key , symbol , path , location ) do
491
486
% {
492
487
kind: @ symbol_codes |> Map . fetch! ( key ) ,
493
488
name: symbol_name ( key , symbol ) ,
494
489
location: % {
495
490
uri: SourceFile . path_to_uri ( path ) ,
496
- range: build_range ( line )
491
+ range: build_range ( location )
497
492
}
498
493
}
499
494
end
@@ -515,14 +510,21 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
515
510
"#{ inspect ( module ) } .#{ callback } /#{ arity } "
516
511
end
517
512
518
- @ spec build_range ( nil | non_neg_integer ) :: range_t
513
+ @ spec build_range ( nil | erl_location_t ) :: range_t
519
514
defp build_range ( nil ) do
520
515
% {
521
516
start: % { line: 0 , character: 0 } ,
522
517
end: % { line: 1 , character: 0 }
523
518
}
524
519
end
525
520
521
+ defp build_range ( { line , _column } ) do
522
+ % {
523
+ start: % { line: max ( line - 1 , 0 ) , character: 0 } ,
524
+ end: % { line: line , character: 0 }
525
+ }
526
+ end
527
+
526
528
defp build_range ( line ) do
527
529
% {
528
530
start: % { line: max ( line - 1 , 0 ) , character: 0 } ,
0 commit comments