Skip to content

Commit 1a3ae77

Browse files
committed
move all accesses to Mix.Project under build lock in dialyzer
1 parent 7abb79e commit 1a3ae77

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

apps/language_server/lib/language_server/dialyzer.ex

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
77

88
defstruct [
99
:project_dir,
10+
:deps_path,
1011
:parent,
1112
:timestamp,
1213
:plt,
@@ -112,7 +113,7 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
112113
_from,
113114
state
114115
) do
115-
diagnostics = to_diagnostics(warnings, state.warn_opts, state.warning_format, state.project_dir)
116+
diagnostics = to_diagnostics(warnings, state.warn_opts, state.warning_format, state.project_dir, state.deps_path)
116117

117118
Server.dialyzer_finished(state.parent, diagnostics, build_ref)
118119

@@ -150,12 +151,16 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
150151
def handle_cast({:analyze, build_ref, warn_opts, warning_format, project_dir}, state) do
151152
state =
152153
ElixirLS.LanguageServer.Build.with_build_lock(fn ->
154+
# we can safely access Mix.Project under build lock
153155
if Mix.Project.get() do
154156
Logger.info("[ElixirLS Dialyzer] Checking for stale beam files")
157+
deps_path = Mix.Project.deps_path()
158+
build_path = Mix.Project.build_path()
159+
155160
new_timestamp = adjusted_timestamp()
156161

157162
{removed_files, file_changes} =
158-
update_stale(state.md5, state.removed_files, state.file_changes, state.timestamp, project_dir)
163+
update_stale(state.md5, state.removed_files, state.file_changes, state.timestamp, project_dir, build_path)
159164

160165
state = %{
161166
state
@@ -165,7 +170,8 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
165170
file_changes: file_changes,
166171
build_ref: build_ref,
167172
warning_format: warning_format,
168-
project_dir: project_dir
173+
project_dir: project_dir,
174+
deps_path: deps_path
169175
}
170176

171177
trigger_analyze(state)
@@ -215,12 +221,12 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
215221
defp trigger_analyze(%{analysis_pid: nil} = state), do: do_analyze(state)
216222
defp trigger_analyze(state), do: state
217223

218-
defp update_stale(md5, removed_files, file_changes, timestamp, project_dir) do
224+
defp update_stale(md5, removed_files, file_changes, timestamp, project_dir, build_path) do
219225
prev_paths = Map.keys(md5) |> MapSet.new()
220226

221227
# FIXME: Private API
222228
all_paths =
223-
for path <- Mix.Utils.extract_files([Mix.Project.build_path()], [:beam]),
229+
for path <- Mix.Utils.extract_files([build_path], [:beam]),
224230
into: MapSet.new(),
225231
do: Path.relative_to(path, project_dir)
226232

@@ -446,7 +452,7 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
446452
# in, which breaks umbrella apps. We have to manually resolve the file
447453
# from the module instead.
448454
file = resolve_module_file(module, file, project_dir),
449-
in_project?(file, project_dir) do
455+
in_project?(Path.absname(file), project_dir) do
450456
{module, {file, line, warning}}
451457
end
452458

@@ -490,10 +496,8 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
490496
end
491497

492498
defp in_project?(path, project_dir) do
493-
# TODO return false for deps Mix.Project.config()[:deps_path]
494-
# project_dir is absolute path with universal separators
495-
# Path.absname result likewise
496-
File.exists?(path) and SourceFile.Path.path_in_dir?(Path.absname(path), project_dir)
499+
# path and project_dir is absolute path with universal separators
500+
File.exists?(path) and SourceFile.Path.path_in_dir?(path, project_dir)
497501
end
498502

499503
defp module_md5(file) do
@@ -511,17 +515,18 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
511515
end
512516
end
513517

514-
defp to_diagnostics(warnings_map, warn_opts, warning_format, project_dir) do
518+
defp to_diagnostics(warnings_map, warn_opts, warning_format, project_dir, deps_path) do
519+
dbg(deps_path)
520+
dbg(project_dir)
515521
tags_enabled = Analyzer.matching_tags(warn_opts)
516-
deps_path = Mix.Project.deps_path()
517522

518523
for {_beam_file, warnings} <- warnings_map,
519524
{source_file, position, data} <- warnings,
520525
{tag, _, _} = data,
521526
tag in tags_enabled,
522527
source_file = Path.absname(to_string(source_file)),
523528
in_project?(source_file, project_dir),
524-
not String.starts_with?(source_file, deps_path) do
529+
not SourceFile.Path.path_in_dir?(source_file, deps_path) do
525530
%Mix.Task.Compiler.Diagnostic{
526531
compiler_name: "ElixirLS Dialyzer",
527532
file: source_file,

0 commit comments

Comments
 (0)