@@ -18,13 +18,11 @@ defmodule ElixirSense.Location do
18
18
}
19
19
defstruct [ :type , :file , :line , :column ]
20
20
21
- defguardp file_exists ( file ) when file not in [ "non_existing" , nil , "" ]
22
-
23
21
@ spec find_mod_fun_source ( module , atom , non_neg_integer | { :gte , non_neg_integer } | :any ) ::
24
22
Location . t ( ) | nil
25
23
def find_mod_fun_source ( mod , fun , arity ) do
26
24
case find_mod_file ( mod ) do
27
- { mod , file } when file_exists ( file ) ->
25
+ file when is_binary ( file ) ->
28
26
find_fun_position ( { mod , file } , fun , arity )
29
27
30
28
_ ->
@@ -34,10 +32,10 @@ defmodule ElixirSense.Location do
34
32
35
33
@ spec find_type_source ( module , atom , non_neg_integer | { :gte , non_neg_integer } | :any ) ::
36
34
Location . t ( ) | nil
37
- def find_type_source ( mod , fun , arity ) do
35
+ def find_type_source ( mod , type , arity ) do
38
36
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 )
41
39
42
40
_ ->
43
41
nil
@@ -47,6 +45,10 @@ defmodule ElixirSense.Location do
47
45
defp find_mod_file ( Elixir ) , do: nil
48
46
49
47
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
50
52
file =
51
53
if Code . ensure_loaded? ( module ) do
52
54
case module . module_info ( :compile ) [ :source ] do
@@ -55,26 +57,45 @@ defmodule ElixirSense.Location do
55
57
end
56
58
end
57
59
58
- file =
59
- if file && File . exists? ( file , [ :raw ] ) do
60
+ if file do
61
+ if File . exists? ( file , [ :raw ] ) do
60
62
file
61
63
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"
69
75
) ,
70
- true <- File . exists? ( erl_file , [ :raw ] ) do
71
- erl_file
76
+ true <- File . exists? ( file , [ :raw ] ) do
77
+ file
72
78
else
73
79
_ -> nil
74
80
end
75
81
end
82
+ end
83
+ end
76
84
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
78
99
end
79
100
80
101
defp find_fun_position ( { mod , file } , fun , arity ) do
0 commit comments