Skip to content

Commit 10978db

Browse files
committed
Allow to lookup Elixir source files under configured location
1 parent 6a9f011 commit 10978db

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

lib/elixir_sense/location.ex

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ defmodule ElixirSense.Location do
1818
}
1919
defstruct [:type, :file, :line, :column]
2020

21-
defguardp file_exists(file) when file not in ["non_existing", nil, ""]
22-
2321
@spec find_mod_fun_source(module, atom, non_neg_integer | {:gte, non_neg_integer} | :any) ::
2422
Location.t() | nil
2523
def find_mod_fun_source(mod, fun, arity) do
2624
case find_mod_file(mod) do
27-
{mod, file} when file_exists(file) ->
25+
file when is_binary(file) ->
2826
find_fun_position({mod, file}, fun, arity)
2927

3028
_ ->
@@ -34,10 +32,10 @@ defmodule ElixirSense.Location do
3432

3533
@spec find_type_source(module, atom, non_neg_integer | {:gte, non_neg_integer} | :any) ::
3634
Location.t() | nil
37-
def find_type_source(mod, fun, arity) do
35+
def find_type_source(mod, type, arity) do
3836
case find_mod_file(mod) do
39-
{mod, file} when file_exists(file) ->
40-
find_type_position({mod, file}, fun, arity)
37+
file when is_binary(file) ->
38+
find_type_position({mod, file}, type, arity)
4139

4240
_ ->
4341
nil
@@ -47,6 +45,10 @@ defmodule ElixirSense.Location do
4745
defp find_mod_file(Elixir), do: nil
4846

4947
defp find_mod_file(module) do
48+
find_elixir_file(module) || find_erlang_file(module)
49+
end
50+
51+
defp find_elixir_file(module) do
5052
file =
5153
if Code.ensure_loaded?(module) do
5254
case module.module_info(:compile)[:source] do
@@ -55,26 +57,45 @@ defmodule ElixirSense.Location do
5557
end
5658
end
5759

58-
file =
59-
if file && File.exists?(file, [:raw]) do
60+
if file do
61+
if File.exists?(file, [:raw]) do
6062
file
6163
else
62-
with {_module, _binary, beam_filename} <- :code.get_object_code(module),
63-
erl_file =
64-
beam_filename
65-
|> to_string
66-
|> String.replace(
67-
~r/(.+)\/ebin\/([^\s]+)\.beam$/,
68-
"\\1/src/\\2.erl"
64+
# If Elixir was built in a sandboxed environment,
65+
# `module.module_info(:compile)[:source]` would point to a non-existing
66+
# location; in this case try to find a "core" Elixir source file under
67+
# the configured Elixir source path.
68+
with elixir_src when is_binary(elixir_src) <-
69+
Application.get_env(:elixir_sense, :elixir_src),
70+
file =
71+
String.replace(
72+
file,
73+
Regex.recompile!(~r<^(?:.+)(/lib/.+\.ex)$>U),
74+
elixir_src <> "\\1"
6975
),
70-
true <- File.exists?(erl_file, [:raw]) do
71-
erl_file
76+
true <- File.exists?(file, [:raw]) do
77+
file
7278
else
7379
_ -> nil
7480
end
7581
end
82+
end
83+
end
7684

77-
{module, file}
85+
defp find_erlang_file(module) do
86+
with {_module, _binary, beam_filename} <- :code.get_object_code(module),
87+
erl_file =
88+
beam_filename
89+
|> to_string
90+
|> String.replace(
91+
Regex.recompile!(~r/(.+)\/ebin\/([^\s]+)\.beam$/),
92+
"\\1/src/\\2.erl"
93+
),
94+
true <- File.exists?(erl_file, [:raw]) do
95+
erl_file
96+
else
97+
_ -> nil
98+
end
7899
end
79100

80101
defp find_fun_position({mod, file}, fun, arity) do

0 commit comments

Comments
 (0)