@@ -5,13 +5,15 @@ defmodule ElixirLS.LanguageServer.Providers.References do
5
5
any function or module identified at the provided location.
6
6
"""
7
7
8
- alias ElixirLS.LanguageServer.SourceFile
8
+ alias ElixirLS.LanguageServer . { SourceFile , Build }
9
9
alias ElixirSense.Core . { Metadata , Parser , Source , Introspection }
10
10
11
11
def references ( text , line , character , _include_declaration ) do
12
- xref_at_cursor ( text , line , character )
13
- |> Enum . filter ( fn % { line: line } -> is_integer ( line ) end )
14
- |> Enum . map ( & build_location / 1 )
12
+ Build . with_build_lock ( fn ->
13
+ xref_at_cursor ( text , line , character )
14
+ |> Enum . filter ( fn % { line: line } -> is_integer ( line ) end )
15
+ |> Enum . map ( & build_location / 1 )
16
+ end )
15
17
end
16
18
17
19
def supported? do
@@ -48,19 +50,39 @@ defmodule ElixirLS.LanguageServer.Providers.References do
48
50
defp add_arity ( { mod , fun } , % { scope: { fun , arity } , module: mod } ) , do: { mod , fun , arity }
49
51
defp add_arity ( { mod , fun } , _env ) , do: { mod , fun , nil }
50
52
51
- def callers ( nil ) , do: [ ]
52
- def callers ( mfa ) , do: Mix.Tasks.Xref . calls ( ) |> Enum . filter ( caller_filter ( mfa ) )
53
+ defp callers ( mfa ) do
54
+ if Mix.Project . umbrella? ( ) do
55
+ umbrella_calls ( )
56
+ else
57
+ Mix.Tasks.Xref . calls ( )
58
+ end
59
+ |> Enum . filter ( caller_filter ( mfa ) )
60
+ end
61
+
62
+ def umbrella_calls ( ) do
63
+ build_dir = Path . expand ( Mix.Project . config ( ) [ :build_path ] )
64
+
65
+ Mix.Project . apps_paths ( )
66
+ |> Enum . flat_map ( fn { app , path } ->
67
+ Mix.Project . in_project ( app , path , [ build_path: build_dir ] , fn _ ->
68
+ Mix.Tasks.Xref . calls ( )
69
+ |> Enum . map ( fn % { file: file } = call ->
70
+ Map . put ( call , :file , Path . expand ( file ) )
71
+ end )
72
+ end )
73
+ end )
74
+ end
53
75
54
76
defp caller_filter ( { module , nil , nil } ) , do: & match? ( % { callee: { ^ module , _ , _ } } , & 1 )
55
77
defp caller_filter ( { module , func , nil } ) , do: & match? ( % { callee: { ^ module , ^ func , _ } } , & 1 )
56
78
defp caller_filter ( { module , func , arity } ) , do: & match? ( % { callee: { ^ module , ^ func , ^ arity } } , & 1 )
57
79
58
- defp build_location ( call ) do
80
+ defp build_location ( % { file: file , line: line } ) do
59
81
% {
60
- "uri" => SourceFile . path_to_uri ( call . file ) ,
82
+ "uri" => SourceFile . path_to_uri ( file ) ,
61
83
"range" => % {
62
- "start" => % { "line" => call . line - 1 , "character" => 0 } ,
63
- "end" => % { "line" => call . line - 1 , "character" => 0 }
84
+ "start" => % { "line" => line - 1 , "character" => 0 } ,
85
+ "end" => % { "line" => line - 1 , "character" => 0 }
64
86
}
65
87
}
66
88
end
0 commit comments