Skip to content

Commit e37d142

Browse files
authored
Debugger: Allow disabling auto interpreting (#616)
* Debugger: Allow disabling auto interpreting On larger projects, the overhead of interpreting all the modules in the project (including all dependencies) causes an unbearable slowdown. This commit makes it possible to disable the auto interpreting of modules and instead rely on files that are in `requireFiles` (which are interpreted) Fixes #615 * Add interpretModulesPatterns * Fix formatting * Update variable naming * Add try catch when interpretting by pattern Also improve some naming * Fix error * Fix formatting
1 parent a244c94 commit e37d142

File tree

1 file changed

+62
-18
lines changed
  • apps/elixir_ls_debugger/lib/debugger

1 file changed

+62
-18
lines changed

apps/elixir_ls_debugger/lib/debugger/server.ex

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ defmodule ElixirLS.Debugger.Server do
673673
prev_env = Mix.env()
674674
task = config["task"]
675675
task_args = config["taskArgs"]
676+
auto_interpret_files? = Map.get(config, "debugAutoInterpretAllModules", true)
676677

677678
set_stack_trace_mode(config["stackTraceMode"])
678679
set_env_vars(config["env"])
@@ -714,10 +715,20 @@ defmodule ElixirLS.Debugger.Server do
714715
config
715716
|> Map.get("excludeModules", [])
716717

717-
interpret_modules_in(Mix.Project.build_path(), exclude_module_names)
718+
exclude_module_pattern =
719+
exclude_module_names
720+
|> Enum.map(&wildcard_module_name_to_pattern/1)
721+
722+
if auto_interpret_files? do
723+
auto_interpret_modules(Mix.Project.build_path(), exclude_module_pattern)
724+
end
718725

719726
if required_files = config["requireFiles"], do: require_files(required_files)
720727

728+
if interpret_modules_patterns = config["debugInterpretModulesPatterns"] do
729+
interpret_specified_modules(interpret_modules_patterns, exclude_module_pattern)
730+
end
731+
721732
ElixirLS.Debugger.Output.send_event("initialized", %{})
722733
end
723734

@@ -762,26 +773,12 @@ defmodule ElixirLS.Debugger.Server do
762773
}
763774
end
764775

765-
defp interpret_modules_in(path, exclude_module_names) do
766-
exclude_module_pattern =
767-
exclude_module_names
768-
|> Enum.map(&wildcard_module_name_to_pattern/1)
769-
776+
defp auto_interpret_modules(path, exclude_module_pattern) do
770777
path
771778
|> Path.join("**/*.beam")
772779
|> Path.wildcard()
773780
|> Enum.map(&(Path.basename(&1, ".beam") |> String.to_atom()))
774-
|> Enum.filter(&interpretable?(&1, exclude_module_pattern))
775-
|> Enum.map(fn mod ->
776-
try do
777-
{:module, _} = :int.ni(mod)
778-
catch
779-
_, _ ->
780-
IO.warn(
781-
"Module #{inspect(mod)} cannot be interpreted. Consider adding it to `excludeModules`."
782-
)
783-
end
784-
end)
781+
|> interpret_modules(exclude_module_pattern)
785782
end
786783

787784
defp wildcard_module_name_to_pattern(module_name) do
@@ -792,7 +789,7 @@ defmodule ElixirLS.Debugger.Server do
792789
|> Regex.compile!()
793790
end
794791

795-
defp interpretable?(module, exclude_module_pattern) do
792+
defp should_interpret?(module, exclude_module_pattern) do
796793
:int.interpretable(module) == true and !:code.is_sticky(module) and module != __MODULE__ and
797794
not excluded_module?(module, exclude_module_pattern)
798795
end
@@ -865,6 +862,33 @@ defmodule ElixirLS.Debugger.Server do
865862
do: save_and_reload(module, beam_bin)
866863
end
867864

865+
defp interpret_specified_modules(file_patterns, exclude_module_pattern) do
866+
regexes =
867+
Enum.flat_map(file_patterns, fn pattern ->
868+
case Regex.compile(pattern) do
869+
{:ok, regex} ->
870+
[regex]
871+
872+
{:error, error} ->
873+
IO.puts(
874+
:standard_error,
875+
"Unable to compile file pattern (#{inspect(pattern)}) into a regex. Received error: #{inspect(error)}"
876+
)
877+
878+
[]
879+
end
880+
end)
881+
882+
ElixirSense.all_modules()
883+
|> Enum.filter(fn module_name ->
884+
Enum.find(regexes, fn regex ->
885+
Regex.match?(regex, module_name)
886+
end)
887+
end)
888+
|> Enum.map(fn module_name -> Module.concat(Elixir, module_name) end)
889+
|> interpret_modules(exclude_module_pattern)
890+
end
891+
868892
defp save_and_reload(module, beam_bin) do
869893
:ok = File.write(Path.join(@temp_beam_dir, to_string(module) <> ".beam"), beam_bin)
870894
true = :code.delete(module)
@@ -912,4 +936,24 @@ defmodule ElixirLS.Debugger.Server do
912936
{:error, "Cannot interpret module #{inspect(module)}"}
913937
end
914938
end
939+
940+
defp interpret_modules(modules, exclude_module_pattern) do
941+
modules
942+
|> Enum.each(fn mod ->
943+
if should_interpret?(mod, exclude_module_pattern) do
944+
interpret_module(mod)
945+
end
946+
end)
947+
end
948+
949+
defp interpret_module(mod) do
950+
try do
951+
{:module, _} = :int.ni(mod)
952+
catch
953+
_, _ ->
954+
IO.warn(
955+
"Module #{inspect(mod)} cannot be interpreted. Consider adding it to `excludeModules`."
956+
)
957+
end
958+
end
915959
end

0 commit comments

Comments
 (0)