Skip to content

Commit f51019e

Browse files
authored
Diagnostics refactor (#1040)
* handle uppercase hint * extract line in one more case * wip * wip * build release assets with recent version * fix tests on < 1.16 * format * improve rendering of TokenMissingError for heredocs * fix warning * format * deduplicate rendered messages * try to get line from stacktrace if position unknown * add tests
1 parent b30939c commit f51019e

File tree

10 files changed

+1133
-402
lines changed

10 files changed

+1133
-402
lines changed

.github/workflows/release-asset.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ jobs:
4242
- name: Set up BEAM
4343
uses: erlef/setup-beam@v1
4444
with:
45-
elixir-version: 1.14.x
46-
otp-version: 25.x
45+
elixir-version: 1.15.x
46+
otp-version: 26.x
4747

4848
- name: Install dependencies
4949
run: mix deps.get

apps/debug_adapter/lib/debug_adapter/server.ex

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,15 +1101,16 @@ defmodule ElixirLS.DebugAdapter.Server do
11011101
"expensive" => false
11021102
}
11031103

1104-
args_scope = if frame.args != :undefined do
1105-
%{
1106-
"name" => "arguments",
1107-
"variablesReference" => args_id,
1108-
"namedVariables" => 0,
1109-
"indexedVariables" => Enum.count(frame.args),
1110-
"expensive" => false
1111-
}
1112-
end
1104+
args_scope =
1105+
if frame.args != :undefined do
1106+
%{
1107+
"name" => "arguments",
1108+
"variablesReference" => args_id,
1109+
"namedVariables" => 0,
1110+
"indexedVariables" => Enum.count(frame.args),
1111+
"expensive" => false
1112+
}
1113+
end
11131114

11141115
messages_scope = %{
11151116
"name" => "messages",
@@ -1129,7 +1130,11 @@ defmodule ElixirLS.DebugAdapter.Server do
11291130

11301131
scopes =
11311132
[vars_scope, versioned_vars_scope, process_info_scope]
1132-
|> Kernel.++(if frame.args != :undefined and Enum.count(frame.args) > 0, do: [args_scope], else: [])
1133+
|> Kernel.++(
1134+
if frame.args != :undefined and Enum.count(frame.args) > 0,
1135+
do: [args_scope],
1136+
else: []
1137+
)
11331138
|> Kernel.++(if Enum.count(frame.messages) > 0, do: [messages_scope], else: [])
11341139

11351140
{state, scopes}

apps/debug_adapter/test/debugger_test.exs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,8 +2322,7 @@ defmodule ElixirLS.DebugAdapter.ServerTest do
23222322
assert Proto in :int.interpreted()
23232323

23242324
assert [
2325-
{{Proto, 2},
2326-
[:active, :enable, :null, {BreakpointCondition, :check_0}]}
2325+
{{Proto, 2}, [:active, :enable, :null, {BreakpointCondition, :check_0}]}
23272326
] = :int.all_breaks(Proto)
23282327

23292328
assert %{{Proto, :go, 1} => [2]} = :sys.get_state(server).function_breakpoints
@@ -2434,8 +2433,7 @@ defmodule ElixirLS.DebugAdapter.ServerTest do
24342433
assert Proto.List in :int.interpreted()
24352434

24362435
assert [
2437-
{{Proto.List, 7},
2438-
[:active, :enable, :null, {BreakpointCondition, :check_0}]}
2436+
{{Proto.List, 7}, [:active, :enable, :null, {BreakpointCondition, :check_0}]}
24392437
] = :int.all_breaks(Proto.List)
24402438

24412439
assert %{{Proto.List, :go, 1} => [7]} = :sys.get_state(server).function_breakpoints

apps/language_server/lib/language_server/build.ex

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ defmodule ElixirLS.LanguageServer.Build do
6262

6363
deps_diagnostics =
6464
deps_raw_diagnostics
65-
|> Enum.map(&Diagnostics.code_diagnostic/1)
65+
|> Enum.map(&Diagnostics.from_code_diagnostic(&1, mixfile, root_path))
6666

6767
case deps_result do
6868
:ok ->
@@ -71,7 +71,10 @@ defmodule ElixirLS.LanguageServer.Build do
7171
run_mix_compile(Keyword.get(opts, :force?, false))
7272

7373
compile_diagnostics =
74-
Diagnostics.normalize(compile_diagnostics, root_path, mixfile)
74+
compile_diagnostics
75+
|> Enum.map(
76+
&Diagnostics.from_mix_task_compiler_diagnostic(&1, mixfile, root_path)
77+
)
7578

7679
Server.build_finished(
7780
parent,
@@ -95,7 +98,7 @@ defmodule ElixirLS.LanguageServer.Build do
9598
mixfile_diagnostics ++
9699
deps_diagnostics ++
97100
[
98-
Diagnostics.error_to_diagnostic(
101+
Diagnostics.from_error(
99102
kind,
100103
err,
101104
stacktrace,
@@ -270,16 +273,54 @@ defmodule ElixirLS.LanguageServer.Build do
270273

271274
# We can get diagnostics if Mixfile fails to load
272275
{mixfile_status, mixfile_diagnostics} =
273-
case Kernel.ParallelCompiler.compile([mixfile]) do
274-
{:ok, _, warnings} ->
275-
{:ok, Enum.map(warnings, &Diagnostics.mixfile_diagnostic(&1, :warning))}
276-
277-
{:error, errors, warnings} ->
278-
{
279-
:error,
280-
Enum.map(warnings, &Diagnostics.mixfile_diagnostic(&1, :warning)) ++
281-
Enum.map(errors, &Diagnostics.mixfile_diagnostic(&1, :error))
282-
}
276+
if Version.match?(System.version(), ">= 1.15.3") do
277+
{result, raw_diagnostics} =
278+
with_diagnostics([log: true], fn ->
279+
try do
280+
Code.compile_file(mixfile)
281+
:ok
282+
catch
283+
kind, err ->
284+
{payload, stacktrace} = Exception.blame(kind, err, __STACKTRACE__)
285+
{:error, kind, payload, stacktrace}
286+
end
287+
end)
288+
289+
diagnostics =
290+
raw_diagnostics
291+
|> Enum.map(&Diagnostics.from_code_diagnostic(&1, mixfile, root_path))
292+
293+
case result do
294+
:ok ->
295+
{:ok, diagnostics}
296+
297+
{:error, kind, err, stacktrace} ->
298+
{:error,
299+
diagnostics ++
300+
[Diagnostics.from_error(kind, err, stacktrace, mixfile, root_path)]}
301+
end
302+
else
303+
case Kernel.ParallelCompiler.compile([mixfile]) do
304+
{:ok, _, warnings} ->
305+
{:ok,
306+
Enum.map(
307+
warnings,
308+
&Diagnostics.from_kernel_parallel_compiler_tuple(&1, :warning, mixfile)
309+
)}
310+
311+
{:error, errors, warnings} ->
312+
{
313+
:error,
314+
Enum.map(
315+
warnings,
316+
&Diagnostics.from_kernel_parallel_compiler_tuple(&1, :warning, mixfile)
317+
) ++
318+
Enum.map(
319+
errors,
320+
&Diagnostics.from_kernel_parallel_compiler_tuple(&1, :error, mixfile)
321+
)
322+
}
323+
end
283324
end
284325

285326
# restore warnings
@@ -325,18 +366,18 @@ defmodule ElixirLS.LanguageServer.Build do
325366
end
326367
end)
327368

369+
config_path = SourceFile.Path.absname(Mix.Project.config()[:config_path], root_path)
370+
328371
config_diagnostics =
329372
config_raw_diagnostics
330-
|> Enum.map(&Diagnostics.code_diagnostic/1)
373+
|> Enum.map(&Diagnostics.from_code_diagnostic(&1, config_path, root_path))
331374

332375
case config_result do
333376
{:error, kind, err, stacktrace} ->
334-
config_path = Mix.Project.config()[:config_path]
335-
336377
{:error,
337378
mixfile_diagnostics ++
338379
config_diagnostics ++
339-
[Diagnostics.error_to_diagnostic(kind, err, stacktrace, config_path, root_path)]}
380+
[Diagnostics.from_error(kind, err, stacktrace, config_path, root_path)]}
340381

341382
:ok ->
342383
{:ok, mixfile_diagnostics ++ config_diagnostics}

0 commit comments

Comments
 (0)