@@ -14,7 +14,8 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
14
14
:warning_format ,
15
15
:apps_paths ,
16
16
:project_dir ,
17
- :next_build
17
+ :next_build ,
18
+ :plt
18
19
]
19
20
20
21
Record . defrecordp ( :iplt_info , [
@@ -95,11 +96,9 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
95
96
end
96
97
97
98
@ impl GenServer
98
- def handle_call ( { :suggest_contracts , files } , _from , state ) do
99
+ def handle_call ( { :suggest_contracts , files } , _from , state = % { plt: plt } ) when plt != nil do
99
100
specs =
100
101
try do
101
- # TODO maybe store plt in state?
102
- plt = :dialyzer_iplt . from_file ( elixir_incremental_plt_path ( ) )
103
102
SuccessTypings . suggest_contracts ( plt , files )
104
103
catch
105
104
:throw = kind , { :dialyzer_error , message } = payload ->
@@ -145,10 +144,15 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
145
144
146
145
{ opts , warning_modules_to_apps } = build_dialyzer_opts ( )
147
146
147
+ if state . plt do
148
+ :dialyzer_plt . delete ( state . plt )
149
+ end
150
+
148
151
{ :ok , pid } =
149
152
Task . start_link ( fn ->
150
- warnings = do_analyze ( opts , warning_modules_to_apps )
151
- send ( parent , { :analysis_finished , warnings , build_ref } )
153
+ { warnings , plt } = do_analyze ( opts , warning_modules_to_apps )
154
+ Manifest . transfer_plt ( plt , parent )
155
+ send ( parent , { :analysis_finished , warnings , build_ref , plt } )
152
156
end )
153
157
154
158
% {
@@ -157,7 +161,8 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
157
161
warning_format: warning_format ,
158
162
apps_paths: apps_paths ,
159
163
project_dir: project_dir ,
160
- analysis_pid: pid
164
+ analysis_pid: pid ,
165
+ plt: nil
161
166
}
162
167
else
163
168
state
@@ -175,7 +180,7 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
175
180
176
181
@ impl GenServer
177
182
def handle_info (
178
- { :analysis_finished , warnings_map , build_ref } ,
183
+ { :analysis_finished , warnings_map , build_ref , plt } ,
179
184
state
180
185
) do
181
186
diagnostics =
@@ -188,14 +193,21 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
188
193
)
189
194
190
195
Server . dialyzer_finished ( state . parent , diagnostics , build_ref )
191
- state = % { state | analysis_pid: nil }
196
+ state = % { state | analysis_pid: nil , plt: plt }
192
197
193
198
case state . next_build do
194
199
nil -> { :noreply , state }
195
200
msg -> handle_cast ( msg , % { state | next_build: nil } )
196
201
end
197
202
end
198
203
204
+ def handle_info (
205
+ { :"ETS-TRANSFER" , _ , _ , _ } ,
206
+ state
207
+ ) do
208
+ { :noreply , state }
209
+ end
210
+
199
211
defp build_dialyzer_opts ( ) do
200
212
# assume that all required apps has been loaded during build
201
213
# notable exception is erts which is not loaded by default but we load it manually during startup
@@ -326,7 +338,7 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
326
338
# warnings returned by dialyzer public api are stripped to https://www.erlang.org/doc/man/dialyzer#type-dial_warning
327
339
# file paths are app relative but we need to know which umbrella app they come from
328
340
# we load PLT info directly and read raw warnings
329
- { us , { _dialyzer_plt , plt_info } } =
341
+ { us , { dialyzer_plt , plt_info } } =
330
342
:timer . tc ( fn ->
331
343
:dialyzer_iplt . plt_and_info_from_file ( elixir_incremental_plt_path ( ) )
332
344
end )
@@ -335,17 +347,20 @@ defmodule ElixirLS.LanguageServer.DialyzerIncremental do
335
347
336
348
iplt_info ( warning_map: warning_map ) = plt_info
337
349
# filter by modules from project app/umbrella apps
338
- warning_map
339
- |> Map . take ( Map . keys ( warning_modules_to_apps ) )
340
- |> Enum . group_by (
341
- fn { module , _warnings } ->
342
- Map . fetch! ( warning_modules_to_apps , module )
343
- end ,
344
- fn { module , warnings } ->
345
- # raw warnings may be duplicated
346
- { module , Enum . uniq ( warnings ) }
347
- end
348
- )
350
+ warnings =
351
+ warning_map
352
+ |> Map . take ( Map . keys ( warning_modules_to_apps ) )
353
+ |> Enum . group_by (
354
+ fn { module , _warnings } ->
355
+ Map . fetch! ( warning_modules_to_apps , module )
356
+ end ,
357
+ fn { module , warnings } ->
358
+ # raw warnings may be duplicated
359
+ { module , Enum . uniq ( warnings ) }
360
+ end
361
+ )
362
+
363
+ { warnings , dialyzer_plt }
349
364
catch
350
365
:throw = kind , { :dialyzer_error , message } = payload ->
351
366
{ _payload , stacktrace } = Exception . blame ( kind , payload , __STACKTRACE__ )
0 commit comments