Skip to content

Commit e1f7272

Browse files
committed
adopt actual_mod_fun api
correctly do alias expansion in buffer call references - previously call alias was expanded with wrong env do not expand aliases twice in definition provider
1 parent 98a676b commit e1f7272

File tree

16 files changed

+108
-145
lines changed

16 files changed

+108
-145
lines changed

apps/elixir_ls_utils/lib/completion_engine.ex

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -514,27 +514,30 @@ defmodule ElixirLS.Utils.CompletionEngine do
514514
end
515515

516516
# do not suggest attributes outside of a module
517-
defp expand_attribute(_, %State.Env{scope: scope}, %Metadata{} = _metadata)
518-
when scope in [Elixir, nil],
517+
defp expand_attribute(_, %State.Env{module: module}, %Metadata{} = _metadata)
518+
when module == nil,
519519
do: no()
520520

521521
defp expand_attribute(
522522
hint,
523-
%State.Env{attributes: attributes, scope: scope},
523+
%State.Env{attributes: attributes} = env,
524524
%Metadata{} = _metadata
525525
) do
526526
attribute_names =
527527
attributes
528528
|> Enum.map(fn %State.AttributeInfo{name: name} -> name end)
529529

530530
attribute_names =
531-
case scope do
532-
{_fun, _arity} ->
531+
case env do
532+
%State.Env{function: {_fun, _arity}} ->
533533
attribute_names
534534

535-
module when not is_nil(module) ->
535+
%State.Env{module: module} when not is_nil(module) ->
536536
# include module attributes in module scope
537537
attribute_names ++ BuiltinAttributes.all()
538+
539+
_ ->
540+
[]
538541
end
539542

540543
for(

apps/elixir_ls_utils/test/complete_test.exs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,8 @@ defmodule ElixirLS.Utils.CompletionEngineTest do
11041104
name: :nothing
11051105
}
11061106
],
1107-
scope: {:some, 0}
1107+
module: My,
1108+
function: {:some, 0}
11081109
}
11091110

11101111
assert expand(~c"@numb", env) == [%{type: :attribute, name: "@number", summary: nil}]
@@ -1126,17 +1127,17 @@ defmodule ElixirLS.Utils.CompletionEngineTest do
11261127
test "builtin attribute name completion" do
11271128
env_function = %Env{
11281129
attributes: [],
1129-
scope: {:some, 0}
1130+
module: Some.Module,
1131+
function: {:some, 0}
11301132
}
11311133

11321134
env_module = %Env{
11331135
attributes: [],
1134-
scope: Some.Module
1136+
module: Some.Module
11351137
}
11361138

11371139
env_outside_module = %Env{
1138-
attributes: [],
1139-
scope: Elixir
1140+
attributes: []
11401141
}
11411142

11421143
assert expand(~c"@befo", env_function) == []
@@ -1567,7 +1568,7 @@ defmodule ElixirLS.Utils.CompletionEngineTest do
15671568
type: {:atom, Date}
15681569
}
15691570
],
1570-
scope: MyMod
1571+
module: MyMod
15711572
})
15721573

15731574
assert [%{name: "Range"}] =
@@ -1578,7 +1579,7 @@ defmodule ElixirLS.Utils.CompletionEngineTest do
15781579
type: {:atom, Date}
15791580
}
15801581
],
1581-
scope: MyMod
1582+
module: MyMod
15821583
})
15831584
end
15841585
end

apps/language_server/lib/language_server/providers/completion.ex

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ defmodule ElixirLS.LanguageServer.Providers.Completion do
1111
alias ElixirLS.LanguageServer.{SourceFile, Parser}
1212
import ElixirLS.LanguageServer.Protocol, only: [range: 4]
1313
alias ElixirLS.Utils.Matcher
14+
alias ElixirSense.Core.State
1415
alias ElixirSense.Core.Normalized.Code, as: NormalizedCode
1516
alias ElixirLS.LanguageServer.MarkdownUtils
1617
require Logger
@@ -144,11 +145,11 @@ defmodule ElixirLS.LanguageServer.Providers.Completion do
144145
env = ElixirSense.Core.Metadata.get_env(metadata, {line, character})
145146

146147
scope =
147-
case env.scope do
148-
scope when scope in [Elixir, nil] -> :file
149-
module when is_atom(module) -> :module
150-
{_, _} -> :function
151-
{:typespec, _, _} -> :typespec
148+
case env do
149+
%State.Env{module: nil} -> :file
150+
%State.Env{function: {_, _}} -> :function
151+
%State.Env{typespec: {_, _}} -> :typespec
152+
%State.Env{} -> :module
152153
end
153154

154155
def_before =

apps/language_server/lib/language_server/providers/completion/reducers/callbacks.ex

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,17 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Callbacks do
2727
@doc """
2828
A reducer that adds suggestions of callbacks.
2929
"""
30-
def add_callbacks(hint, env, buffer_metadata, context, acc) do
30+
def add_callbacks(
31+
hint,
32+
env = %State.Env{module: module, typespec: nil},
33+
buffer_metadata,
34+
context,
35+
acc
36+
)
37+
when module != nil do
3138
text_before = context.text_before
3239

33-
%State.Env{protocol: protocol, behaviours: behaviours, scope: scope} = env
40+
%State.Env{protocol: protocol, behaviours: behaviours} = env
3441

3542
list =
3643
Enum.flat_map(behaviours, fn
@@ -138,14 +145,18 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Callbacks do
138145
Regex.match?(~r/\s(def|defmacro)\s+([_\p{Ll}\p{Lo}][\p{L}\p{N}_]*[?!]?)?$/u, text_before) ->
139146
{:halt, %{acc | result: list}}
140147

141-
match?({_f, _a}, scope) ->
148+
env.function != nil ->
142149
{:cont, acc}
143150

144151
true ->
145152
{:cont, %{acc | result: acc.result ++ list}}
146153
end
147154
end
148155

156+
def add_callbacks(_hint, _env, _buffer_metadata, _context, acc) do
157+
{:cont, acc}
158+
end
159+
149160
defp def_prefix?(hint, spec) do
150161
if String.starts_with?(spec, "@macrocallback") do
151162
String.starts_with?("defmacro", hint)

apps/language_server/lib/language_server/providers/completion/reducers/overridable.ex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Overridable do
1414
@doc """
1515
A reducer that adds suggestions of overridable functions.
1616
"""
17-
def add_overridable(_hint, %State.Env{scope: {_f, _a}}, _metadata, _cursor_context, acc),
18-
do: {:cont, acc}
1917

20-
def add_overridable(hint, env, metadata, _cursor_context, acc) do
18+
def add_overridable(
19+
hint,
20+
env = %State.Env{typespec: nil, module: module},
21+
metadata,
22+
_cursor_context,
23+
acc
24+
)
25+
when not is_nil(module) do
2126
%State.Env{protocol: protocol, behaviours: behaviours, module: module} = env
2227

2328
# overridable behaviour callbacks are returned by Reducers.Callbacks
@@ -80,6 +85,9 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Overridable do
8085
{:cont, %{acc | result: acc.result ++ Enum.sort(list)}}
8186
end
8287

88+
def add_overridable(_hint, %State.Env{}, _metadata, _cursor_context, acc),
89+
do: {:cont, acc}
90+
8391
defp def_prefix?(hint, type) when type in [:defmacro, :defmacrop] do
8492
String.starts_with?("defmacro", hint)
8593
end

apps/language_server/lib/language_server/providers/completion/reducers/params.ex

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Params do
1111
alias ElixirSense.Core.Introspection
1212
alias ElixirSense.Core.Metadata
1313
alias ElixirSense.Core.Source
14-
alias ElixirSense.Core.State
1514
alias ElixirSense.Core.TypeInfo
1615
alias ElixirLS.Utils.Matcher
1716

@@ -30,13 +29,6 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Params do
3029
def add_options(hint, env, buffer_metadata, cursor_context, acc) do
3130
prefix = cursor_context.text_before
3231

33-
%State.Env{
34-
requires: requires,
35-
aliases: aliases,
36-
module: module,
37-
scope: scope
38-
} = env
39-
4032
binding_env = Binding.from_env(env, buffer_metadata)
4133

4234
%Metadata{mods_funs_to_positions: mods_funs, types: metadata_types} = buffer_metadata
@@ -50,15 +42,11 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Params do
5042
{mod, fun, true, :mod_fun} <-
5143
Introspection.actual_mod_fun(
5244
{mod, fun},
53-
env.functions,
54-
env.macros,
55-
requires,
56-
if(elixir_prefix, do: [], else: aliases),
57-
module,
58-
scope,
45+
env,
5946
mods_funs,
6047
metadata_types,
61-
{1, 1}
48+
{1, 1},
49+
not elixir_prefix
6250
) do
6351
list =
6452
if Code.ensure_loaded?(mod) do

apps/language_server/lib/language_server/providers/completion/reducers/protocol.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Protocol do
2626
@doc """
2727
A reducer that adds suggestions of protocol functions.
2828
"""
29-
def add_functions(_hint, %State.Env{scope: {_f, _a}}, _metadata, _cursor_context, acc),
29+
def add_functions(_hint, %State.Env{typespec: {_f, _a}}, _metadata, _cursor_context, acc),
30+
do: {:cont, acc}
31+
32+
def add_functions(_hint, %State.Env{module: nil}, _metadata, _cursor_context, acc),
3033
do: {:cont, acc}
3134

3235
def add_functions(_hint, %State.Env{protocol: nil}, _metadata, _cursor_context, acc),

apps/language_server/lib/language_server/providers/completion/reducers/returns.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.Returns do
2323
"""
2424
def add_returns(
2525
"" = _hint,
26-
%State.Env{scope: {fun, arity}} = env,
26+
%State.Env{function: {fun, arity}} = env,
2727
buffer_metadata,
2828
_context,
2929
acc

apps/language_server/lib/language_server/providers/completion/reducers/type_specs.ex

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.TypeSpecs do
3333

3434
# We only list type specs when inside typespec scope
3535
def add_types(hint, env, file_metadata, %{at_module_body?: _}, acc) do
36-
if match?({:typespec, _, _}, env.scope) do
36+
if match?({_, _}, env.typespec) do
3737
%State.Env{
3838
aliases: aliases,
39-
module: module,
40-
scope: scope
39+
module: module
4140
} = env
4241

4342
%Metadata{mods_funs_to_positions: mods_funs, types: metadata_types} = file_metadata
@@ -52,9 +51,7 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.TypeSpecs do
5251
list =
5352
find_typespecs_for_mod_and_hint(
5453
{mod, hint},
55-
aliases,
56-
module,
57-
scope,
54+
env,
5855
mods_funs,
5956
metadata_types
6057
)
@@ -71,6 +68,7 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.TypeSpecs do
7168
end
7269

7370
defp expand({{kind, _} = type, hint}, env, aliases) when kind in [:attribute, :variable] do
71+
# TODO Binding should return expanded aliases
7472
case Binding.expand(env, type) do
7573
{:atom, module} -> {Introspection.expand_alias(module, aliases), hint}
7674
_ -> {nil, ""}
@@ -83,18 +81,17 @@ defmodule ElixirLS.LanguageServer.Providers.Completion.Reducers.TypeSpecs do
8381

8482
defp find_typespecs_for_mod_and_hint(
8583
{mod, hint},
86-
aliases,
87-
module,
88-
scope,
84+
env,
8985
mods_funs,
9086
metadata_types
9187
) do
92-
case Introspection.actual_module(mod, aliases, module, scope, mods_funs) do
88+
# alias already expanded by Source.split_module_and_hint
89+
case Introspection.actual_module(mod, env, mods_funs, false) do
9390
{actual_mod, true} ->
94-
find_module_types(actual_mod, {mod, hint}, metadata_types, module)
91+
find_module_types(actual_mod, {mod, hint}, metadata_types, env.module)
9592

9693
{nil, false} ->
97-
find_module_types(module, {mod, hint}, metadata_types, module)
94+
find_module_types(env.module, {mod, hint}, metadata_types, env.module)
9895

9996
{_, false} ->
10097
[]

apps/language_server/lib/language_server/providers/definition/locator.ex

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ defmodule ElixirLS.LanguageServer.Providers.Definition.Locator do
154154
case Binding.expand(binding_env, type) do
155155
{:atom, module} ->
156156
do_find_function_or_module(
157-
{{:atom, Introspection.expand_alias(module, env.aliases)}, function},
157+
{{:atom, module}, function},
158158
context,
159159
env,
160160
metadata,
@@ -170,7 +170,7 @@ defmodule ElixirLS.LanguageServer.Providers.Definition.Locator do
170170
defp do_find_function_or_module(
171171
{nil, :super},
172172
context,
173-
%State.Env{scope: {function, arity}, module: module} = env,
173+
%State.Env{function: {function, arity}, module: module} = env,
174174
metadata,
175175
binding_env,
176176
visited
@@ -200,26 +200,15 @@ defmodule ElixirLS.LanguageServer.Providers.Definition.Locator do
200200
_binding_env,
201201
_visited
202202
) do
203-
%State.Env{
204-
module: current_module,
205-
requires: requires,
206-
aliases: aliases,
207-
scope: scope
208-
} = env
209-
210203
m = get_module(module, context, env, metadata)
211204

212205
case {m, function}
213206
|> Introspection.actual_mod_fun(
214-
env.functions,
215-
env.macros,
216-
requires,
217-
aliases,
218-
current_module,
219-
scope,
207+
env,
220208
metadata.mods_funs_to_positions,
221209
metadata.types,
222-
context.begin
210+
context.begin,
211+
true
223212
) do
224213
{_, _, false, _} ->
225214
nil

apps/language_server/lib/language_server/providers/hover/docs.ex

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,11 @@ defmodule ElixirLS.LanguageServer.Providers.Hover.Docs do
181181
{Binding.expand(binding_env, mod), fun}
182182
|> expand(env.aliases)
183183
|> Introspection.actual_mod_fun(
184-
env.functions,
185-
env.macros,
186-
env.requires,
187-
env.aliases,
188-
env.module,
189-
env.scope,
184+
env,
190185
metadata.mods_funs_to_positions,
191186
metadata.types,
192-
context.begin
187+
context.begin,
188+
false
193189
)
194190

195191
case actual do

0 commit comments

Comments
 (0)