Skip to content

Commit

Permalink
correctly handle var versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Aug 29, 2024
1 parent cc5e8a0 commit 3731b6a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
7 changes: 4 additions & 3 deletions lib/elixir_sense/core/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1499,8 +1499,6 @@ defmodule ElixirSense.Core.Compiler do
|> new_vars_scope
|> new_attributes_scope

# TODO magic with ElixirEnv instead of new_vars_scope?

{state, _env} = maybe_add_protocol_behaviour(state, %{env | module: full})

{_result, state, e_env} = expand(block, state, %{env | module: full})
Expand Down Expand Up @@ -1535,9 +1533,10 @@ defmodule ElixirSense.Core.Compiler do
end)

# restore vars from outer scope
# restore version counter
state = state
|> apply_optional_callbacks(%{env | module: full})
|> remove_vars_scope(state_orig)
|> remove_vars_scope(state_orig, true)
|> remove_attributes_scope
|> remove_module

Expand Down Expand Up @@ -1633,6 +1632,8 @@ defmodule ElixirSense.Core.Compiler do
{_e_args, state, env_for_expand} =
expand_args(args, %{state | prematch: {%{}, 0, :none}}, %{env_for_expand | context: :match})

# TODO expand defaults

{e_guard, state, env_for_expand} =
__MODULE__.Clauses.guard(
guards,
Expand Down
27 changes: 12 additions & 15 deletions lib/elixir_sense/core/metadata_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,21 @@ defmodule ElixirSense.Core.MetadataBuilder do
"""
@spec build(Macro.t(), nil | {pos_integer, pos_integer}) :: State.t()
def build(ast, cursor_position \\ nil) do
{_ast, state, _env} =
Compiler.expand(
ast,
%State{
cursor_position: cursor_position,
prematch:
if Version.match?(System.version(), ">= 1.15.0-dev") do
Code.get_compiler_option(:on_undefined_variable)
else
:warn
end
},
Compiler.env()
)
state_orig = %State{
cursor_position: cursor_position,
prematch:
if Version.match?(System.version(), ">= 1.15.0-dev") do
Code.get_compiler_option(:on_undefined_variable)
else
:warn
end
}

{_ast, state, _env} =Compiler.expand(ast, state_orig, Compiler.env())

state
|> remove_attributes_scope
|> remove_vars_scope(%{vars: {%{}, false}})
|> remove_vars_scope(state_orig)
|> remove_module
end

Expand Down
17 changes: 14 additions & 3 deletions lib/elixir_sense/core/state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ defmodule ElixirSense.Core.State do
scope_id_count: scope_id,
vars_info: [%{} | state.vars_info],
# elixir_ex entries
# each def starts versioning from 0
unused: 0,
vars: {%{}, false}
}
Expand All @@ -819,19 +820,28 @@ defmodule ElixirSense.Core.State do
%__MODULE__{state | attributes: [[] | state.attributes], scope_attributes: [[]]}
end

def remove_vars_scope(%__MODULE__{} = state, %{vars: vars}) do
def remove_vars_scope(%__MODULE__{} = state, %{vars: vars, unused: unused}, restore_version_counter \\ false) do
state = maybe_move_vars_to_outer_scope(state)
%__MODULE__{
state = %__MODULE__{
state
| scope_ids: tl(state.scope_ids),
vars_info: tl(state.vars_info),
vars_info_per_scope_id: update_vars_info_per_scope_id(state),
# restore elixir_ex fields
vars: vars
}

if restore_version_counter do
# this is used by defmodule as module body does not affect outside versioning
%__MODULE__{
state
| unused: unused
}
else
state
end
end

# TODO should we restore unused?
def remove_func_vars_scope(%__MODULE__{} = state, %{vars: vars, unused: unused}) do
%__MODULE__{
state
Expand All @@ -840,6 +850,7 @@ defmodule ElixirSense.Core.State do
vars_info_per_scope_id: update_vars_info_per_scope_id(state),
# restore elixir_ex fields
vars: vars,
# restore versioning
unused: unused
}
end
Expand Down

0 comments on commit 3731b6a

Please sign in to comment.