Skip to content

Commit 2bf02a3

Browse files
committed
fix crash in replace remote function code action when erlang module is aliased
handle aliased erlang modules
1 parent bcd004b commit 2bf02a3

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

apps/language_server/lib/language_server/providers/code_action/replace_remote_function.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ defmodule ElixirLS.LanguageServer.Providers.CodeAction.ReplaceRemoteFunction do
1313
alias ElixirLS.LanguageServer.SourceFile
1414
alias ElixirSense.Core.Parser
1515
alias ElixirSense.Core.Metadata
16+
alias ElixirSense.Core.Introspection
1617

1718
import ElixirLS.LanguageServer.Providers.CodeAction.Helpers
1819

@@ -157,17 +158,23 @@ defmodule ElixirLS.LanguageServer.Providers.CodeAction.ReplaceRemoteFunction do
157158

158159
@spec expand_alias(SourceFile.t(), [atom()], non_neg_integer()) :: {:ok, atom()} | :error
159160
defp expand_alias(source_file, module_alias, line_number) do
160-
# TODO use Macro.Env
161161
with {:ok, aliases} <- aliases_at(source_file, line_number) do
162162
aliases
163163
|> Enum.map(fn {module, aliased} ->
164164
module = module |> module_to_alias() |> List.first()
165-
aliased = module_to_alias(aliased)
166165

167-
{module, aliased}
166+
if Introspection.elixir_module?(aliased) do
167+
aliased = module_to_alias(aliased)
168+
{module, aliased}
169+
else
170+
{module, aliased}
171+
end
168172
end)
169173
|> Enum.find(fn {module, _aliased} -> List.starts_with?(module_alias, [module]) end)
170174
|> case do
175+
{_module, aliased} when is_atom(aliased) ->
176+
{:ok, aliased}
177+
171178
{_module, aliased} ->
172179
module_alias = aliased ++ Enum.drop(module_alias, 1)
173180

apps/language_server/test/providers/code_action/replace_remote_function_test.exs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,23 @@ defmodule ElixirLS.LanguageServer.Providers.CodeAction.ReplaceRemoteFunctionTest
181181

182182
assert result == ":ets.insert(a, b)"
183183
end
184+
185+
test "handles erlang functions aliased" do
186+
message = """
187+
:ets.inserd/2 is undefined or private. Did you mean:
188+
* insert/2
189+
* insert_new/2
190+
"""
191+
192+
{:ok, [result]} =
193+
~q{
194+
alias :ets, as: Foo
195+
Foo.inserd(a, b)
196+
}
197+
|> modify(message: message, suggestion: "Foo.insert(a, b)", line: 1)
198+
199+
assert result == "alias :ets, as: Foo\nFoo.insert(a, b)"
200+
end
184201
end
185202

186203
if Version.match?(System.version(), ">= 1.15.0") do
@@ -200,6 +217,25 @@ defmodule ElixirLS.LanguageServer.Providers.CodeAction.ReplaceRemoteFunctionTest
200217

201218
assert result == "alias ElixirLS.Test.RemoteFunction\nRemoteFunction.foo(42)"
202219
end
220+
221+
test "when erlang module aliased" do
222+
message = """
223+
ElixirLS.Test.RemoteFunction.fou/1 is undefined or private. Did you mean:
224+
225+
* foo/1
226+
"""
227+
228+
{:ok, [result]} =
229+
~q{
230+
alias :ets, as: Foo
231+
alias ElixirLS.Test.RemoteFunction
232+
RemoteFunction.fou(42)
233+
}
234+
|> modify(message: message, suggestion: "RemoteFunction.foo", line: 2)
235+
236+
assert result ==
237+
"alias :ets, as: Foo\nalias ElixirLS.Test.RemoteFunction\nRemoteFunction.foo(42)"
238+
end
203239
end
204240

205241
if Version.match?(System.version(), ">= 1.15.0") do

0 commit comments

Comments
 (0)