Skip to content

Commit 9c40536

Browse files
committed
extract compile_mixfile_with_diagnostics
1 parent c191134 commit 9c40536

File tree

1 file changed

+65
-60
lines changed
  • apps/language_server/lib/language_server

1 file changed

+65
-60
lines changed

apps/language_server/lib/language_server/build.ex

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -286,66 +286,7 @@ defmodule ElixirLS.LanguageServer.Build do
286286
# added in https://github.com/elixir-lang/elixir/commit/9e07da862784ac7d18a1884141c49ab049e61691
287287
# TODO refactor to use a custom state loader when we require elixir 1.15?
288288

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)
349290

350291
if mixfile_status == :ok do
351292
# mixfile compiled successfully, we may attempt to load config
@@ -366,6 +307,70 @@ defmodule ElixirLS.LanguageServer.Build do
366307
end
367308
end
368309

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+
369374
# Runs the "loadconfig" task and resets logger/environment settings, collecting diagnostics.
370375
defp load_mix_config_with_diagnostics(root_path) do
371376
# The project may override our logger config, so we reset it after loading their config

0 commit comments

Comments
 (0)