Skip to content

Commit

Permalink
do not try to alias Elixir proxy
Browse files Browse the repository at this point in the history
do not try to alias implementation parent modules
do not try to alias mix tasks
optimise find_elixir_modules_that_require_alias
  • Loading branch information
lukaszsamson committed Jul 13, 2023
1 parent 4b4627f commit 1166a2f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 deletions.
60 changes: 38 additions & 22 deletions lib/elixir_sense/providers/suggestion/complete.ex
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,6 @@ defmodule ElixirSense.Providers.Suggestion.Complete do
result
end
end)
|> Enum.reject(fn
%{required_alias: _, subtype: :implementation} ->
# reject protocol implementations, there is rarely a reason to alias them
true

_ ->
false
end)
end

defp valid_alias_piece?(<<?., char, rest::binary>>) when char in ?A..?Z,
Expand Down Expand Up @@ -647,26 +639,50 @@ defmodule ElixirSense.Providers.Suggestion.Complete do
get_modules(true, env)
|> Enum.sort()
|> Enum.dedup()
|> Enum.reduce([], fn module, acc ->
module_parts = module |> String.split(".")

maybe_index =
Enum.find_index(module_parts, fn module_part -> Matcher.match?(module_part, hint) end)

case maybe_index do
nil ->
|> Enum.reduce([], fn
"Elixir." <> module = full_module, acc ->
subtype = Introspection.get_module_subtype(String.to_atom(full_module))
# skip mix tasks and protocol implementations as it's not common to need to alias those
if subtype not in [:implementation, :task] do
# do not search for a match in Elixir. prefix - no need to alias it
module_parts = module |> String.split(".")

case module_parts do
[_] ->
# no need to alias if module is 1 part
acc

[_root | rest] ->
maybe_index =
Enum.find_index(rest, fn module_part -> Matcher.match?(module_part, hint) end)

case maybe_index do
nil ->
acc

index ->
required_alias = Enum.slice(module_parts, 0..(index + 1))
suggestion = Enum.at(required_alias, -1)
required_alias = required_alias |> Module.concat() |> Atom.to_string()

prepend_if_different(acc, {suggestion, required_alias})
end
end
else
acc
end

index ->
required_alias = Enum.slice(module_parts, 0..index)
[suggestion | _] = Enum.reverse(required_alias)
required_alias = required_alias |> Module.concat() |> Atom.to_string()
[{suggestion, required_alias} | acc]
end
_erlang_module, acc ->
# skip erlang modules
acc
end)
|> Enum.filter(fn {suggestion, _required_alias} -> valid_alias_piece?("." <> suggestion) end)
end

defp prepend_if_different([], new), do: [new]
defp prepend_if_different([new | _rest] = list, new), do: list
defp prepend_if_different(list, new), do: [new | list]

defp match_modules(hint, root, env) do
hint_parts = hint |> String.split(".")
hint_parts_length = length(hint_parts)
Expand Down
10 changes: 10 additions & 0 deletions test/elixir_sense/providers/suggestion/complete_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,16 @@ defmodule ElixirSense.Providers.Suggestion.CompleteTest do
refute Enum.find(results, fn expansion -> expansion[:required_alias] == String.Chars end)
end

test "does not suggest required_alias for Elixir proxy" do
env = %Env{
aliases: []
}

results = expand(~c"Elixi", env, required_alias: true)

refute Enum.find(results, fn expansion -> expansion[:required_alias] == Elixir end)
end

test "elixir submodule no completion" do
assert expand(~c"IEx.Xyz") == []
end
Expand Down

0 comments on commit 1166a2f

Please sign in to comment.