@@ -286,66 +286,7 @@ defmodule ElixirLS.LanguageServer.Build do
286
286
# added in https://github.com/elixir-lang/elixir/commit/9e07da862784ac7d18a1884141c49ab049e61691
287
287
# TODO refactor to use a custom state loader when we require elixir 1.15?
288
288
289
- # since elixir 1.10 mix disables undefined warnings for mix.exs
290
- # see discussion in https://github.com/elixir-lang/elixir/issues/9676
291
- # https://github.com/elixir-lang/elixir/blob/6f96693b355a9b670f2630fd8e6217b69e325c5a/lib/mix/lib/mix/cli.ex#L41
292
- old_undefined = Code . get_compiler_option ( :no_warn_undefined )
293
- Code . put_compiler_option ( :no_warn_undefined , :all )
294
-
295
- # We can get diagnostics if Mixfile fails to load
296
- { mixfile_status , mixfile_diagnostics } =
297
- if Version . match? ( System . version ( ) , ">= 1.15.3" ) do
298
- { result , raw_diagnostics } =
299
- with_diagnostics ( [ log: true ] , fn ->
300
- try do
301
- Code . compile_file ( mixfile )
302
- :ok
303
- catch
304
- kind , err ->
305
- { payload , stacktrace } = Exception . blame ( kind , err , __STACKTRACE__ )
306
- { :error , kind , payload , stacktrace }
307
- end
308
- end )
309
-
310
- diagnostics =
311
- raw_diagnostics
312
- |> Enum . map ( & Diagnostics . from_code_diagnostic ( & 1 , mixfile , root_path ) )
313
-
314
- case result do
315
- :ok ->
316
- { :ok , diagnostics }
317
-
318
- { :error , kind , err , stacktrace } ->
319
- { :error ,
320
- diagnostics ++
321
- [ Diagnostics . from_error ( kind , err , stacktrace , mixfile , root_path ) ] }
322
- end
323
- else
324
- case Kernel.ParallelCompiler . compile ( [ mixfile ] ) do
325
- { :ok , _ , warnings } ->
326
- { :ok ,
327
- Enum . map (
328
- warnings ,
329
- & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :warning , mixfile )
330
- ) }
331
-
332
- { :error , errors , warnings } ->
333
- {
334
- :error ,
335
- Enum . map (
336
- warnings ,
337
- & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :warning , mixfile )
338
- ) ++
339
- Enum . map (
340
- errors ,
341
- & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :error , mixfile )
342
- )
343
- }
344
- end
345
- end
346
-
347
- # restore warnings
348
- Code . put_compiler_option ( :no_warn_undefined , old_undefined )
289
+ { mixfile_status , mixfile_diagnostics } = compile_mixfile_with_diagnostics ( mixfile , root_path )
349
290
350
291
if mixfile_status == :ok do
351
292
# mixfile compiled successfully, we may attempt to load config
@@ -366,6 +307,70 @@ defmodule ElixirLS.LanguageServer.Build do
366
307
end
367
308
end
368
309
310
+ # Compile the mixfile and collect diagnostics.
311
+ defp compile_mixfile_with_diagnostics ( mixfile , root_path ) do
312
+ # since elixir 1.10 mix disables undefined warnings for mix.exs
313
+ # see discussion in https://github.com/elixir-lang/elixir/issues/9676
314
+ # https://github.com/elixir-lang/elixir/blob/6f96693b355a9b670f2630fd8e6217b69e325c5a/lib/mix/lib/mix/cli.ex#L41
315
+ old_undefined = Code . get_compiler_option ( :no_warn_undefined )
316
+ Code . put_compiler_option ( :no_warn_undefined , :all )
317
+
318
+ try do
319
+ if Version . match? ( System . version ( ) , ">= 1.15.3" ) do
320
+ { result , raw_diagnostics } =
321
+ with_diagnostics ( [ log: true ] , fn ->
322
+ try do
323
+ Code . compile_file ( mixfile )
324
+ :ok
325
+ catch
326
+ kind , err ->
327
+ { payload , stacktrace } = Exception . blame ( kind , err , __STACKTRACE__ )
328
+ { :error , kind , payload , stacktrace }
329
+ end
330
+ end )
331
+
332
+ diagnostics =
333
+ Enum . map ( raw_diagnostics , & Diagnostics . from_code_diagnostic ( & 1 , mixfile , root_path ) )
334
+
335
+ case result do
336
+ :ok ->
337
+ { :ok , diagnostics }
338
+
339
+ { :error , kind , err , stacktrace } ->
340
+ { :error ,
341
+ diagnostics ++ [ Diagnostics . from_error ( kind , err , stacktrace , mixfile , root_path ) ] }
342
+ end
343
+ else
344
+ case Kernel.ParallelCompiler . compile ( [ mixfile ] ) do
345
+ { :ok , _ , warnings } ->
346
+ diagnostics =
347
+ Enum . map (
348
+ warnings ,
349
+ & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :warning , mixfile )
350
+ )
351
+
352
+ { :ok , diagnostics }
353
+
354
+ { :error , errors , warnings } ->
355
+ diagnostics =
356
+ Enum . map (
357
+ warnings ,
358
+ & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :warning , mixfile )
359
+ ) ++
360
+ Enum . map (
361
+ errors ,
362
+ & Diagnostics . from_kernel_parallel_compiler_tuple ( & 1 , :error , mixfile )
363
+ )
364
+
365
+ { :error , diagnostics }
366
+ end
367
+ end
368
+ after
369
+ # restore warnings
370
+ Code . put_compiler_option ( :no_warn_undefined , old_undefined )
371
+ end
372
+ end
373
+
369
374
# Runs the "loadconfig" task and resets logger/environment settings, collecting diagnostics.
370
375
defp load_mix_config_with_diagnostics ( root_path ) do
371
376
# The project may override our logger config, so we reset it after loading their config
0 commit comments