diff --git a/lib/elixir_sense/core/compiler.ex b/lib/elixir_sense/core/compiler.ex index e9494603..4aa6d535 100644 --- a/lib/elixir_sense/core/compiler.ex +++ b/lib/elixir_sense/core/compiler.ex @@ -1600,13 +1600,15 @@ defmodule ElixirSense.Core.Compiler do ) when module != nil and def_kind in [:def, :defp, :defmacro, :defmacrop, :defguard, :defguardp] do + state = + case call do + {:__cursor__, _, list} when is_list(list) -> + {_, state, _} = expand(call, state, %{env | function: {:__unknown__, 0}}) + state - state = case call do - {:__cursor__, _, list} when is_list(list) -> - {_, state, _} = expand(call, state, %{env | function: {:__unknown__, 0}}) - state - _ -> state - end + _ -> + state + end state_orig = state @@ -1825,14 +1827,16 @@ defmodule ElixirSense.Core.Compiler do {{{:., meta, [module, fun]}, meta, args}, state, env} else ast -> - state = if __MODULE__.Utils.has_cursor?(args) and not __MODULE__.Utils.has_cursor?(ast) do - # in case there was cursor in the original args but it's not present in macro result - # expand a fake node - {_ast, state, _env} = expand({:__cursor__, [], []}, state, env) - state - else - state - end + state = + if __MODULE__.Utils.has_cursor?(args) and not __MODULE__.Utils.has_cursor?(ast) do + # in case there was cursor in the original args but it's not present in macro result + # expand a fake node + {_ast, state, _env} = expand({:__cursor__, [], []}, state, env) + state + else + state + end + {ast, state, env} = expand(ast, state, env) {ast, state, env} end diff --git a/lib/elixir_sense/core/metadata.ex b/lib/elixir_sense/core/metadata.ex index ac3fab13..b59719e2 100644 --- a/lib/elixir_sense/core/metadata.ex +++ b/lib/elixir_sense/core/metadata.ex @@ -80,11 +80,8 @@ defmodule ElixirSense.Core.Metadata do {end_line, end_column} ]) - # IO.puts(metadata.source) - # dbg(needle) source_with_cursor = prefix <> "__cursor__(#{needle})" <> suffix - # IO.puts(source_with_cursor) - # dbg(metadata) + {prefix, source_with_cursor} nil -> @@ -98,8 +95,6 @@ defmodule ElixirSense.Core.Metadata do {prefix, source_with_cursor} end - # IO.puts(source_with_cursor) - {meta, cursor_env} = case Code.string_to_quoted(source_with_cursor, columns: true, token_metadata: true) do {:ok, ast} -> @@ -113,6 +108,7 @@ defmodule ElixirSense.Core.Metadata do if cursor_env != nil do {meta, cursor_env} else + # IO.puts(prefix <> "|") case NormalizedCode.Fragment.container_cursor_to_quoted(prefix, columns: true, token_metadata: true @@ -129,8 +125,7 @@ defmodule ElixirSense.Core.Metadata do cursor_env else case metadata.closest_env do - {pos, dist, env} -> - dbg({pos, dist}) + {_pos, _dist, env} -> env nil -> @@ -263,30 +258,21 @@ defmodule ElixirSense.Core.Metadata do |> Enum.min(fn -> nil end) end - def add_scope_vars( - %State.Env{} = env, + def find_var( %__MODULE__{vars_info_per_scope_id: vars_info_per_scope_id}, - {line, column}, - predicate \\ fn _ -> true end + variable, + version, + position ) do - scope_vars = vars_info_per_scope_id[env.scope_id] || %{} - env_vars_keys = env.vars |> Enum.map(&{&1.name, &1.version}) - - scope_vars_missing_in_env = - scope_vars - |> Enum.filter(fn {key, var} -> - key not in env_vars_keys and Enum.min(var.positions) <= {line, column} and - predicate.(var) + vars_info_per_scope_id + |> Enum.find_value(fn {_scope_id, vars} -> + vars + |> Enum.find_value(fn {{n, v}, info} -> + if n == variable and (v == version or version == :any) and position in info.positions do + info + end end) - |> Enum.map(fn {_, value} -> value end) - - env_vars = - for var <- env.vars do - key = {var.name, var.version} - Map.fetch!(scope_vars, key) - end - - %{env | vars: env_vars ++ scope_vars_missing_in_env} + end) end @spec at_module_body?(State.Env.t()) :: boolean() diff --git a/lib/elixir_sense/providers/completion/suggestion.ex b/lib/elixir_sense/providers/completion/suggestion.ex index 4a37d7de..20aeb2d5 100644 --- a/lib/elixir_sense/providers/completion/suggestion.ex +++ b/lib/elixir_sense/providers/completion/suggestion.ex @@ -122,11 +122,6 @@ defmodule ElixirSense.Providers.Completion.Suggestion do env = Metadata.get_env(metadata, {line, column}) - |> Metadata.add_scope_vars( - metadata, - {line, column}, - &(to_string(&1.name) != hint) - ) # if variable is rebound then in env there are many variables with the same name # find the one defined closest to cursor diff --git a/lib/elixir_sense/providers/definition/locator.ex b/lib/elixir_sense/providers/definition/locator.ex index f0a65938..46613c97 100644 --- a/lib/elixir_sense/providers/definition/locator.ex +++ b/lib/elixir_sense/providers/definition/locator.ex @@ -40,7 +40,6 @@ defmodule ElixirSense.Providers.Definition.Locator do env = Metadata.get_env(metadata, {line, column}) - |> Metadata.add_scope_vars(metadata, {line, column}) find( context, diff --git a/lib/elixir_sense/providers/references/locator.ex b/lib/elixir_sense/providers/references/locator.ex index 7dbf76e8..87a3f381 100644 --- a/lib/elixir_sense/providers/references/locator.ex +++ b/lib/elixir_sense/providers/references/locator.ex @@ -31,7 +31,6 @@ defmodule ElixirSense.Providers.References.Locator do module: module } = Metadata.get_env(metadata, {line, column}) - |> Metadata.add_scope_vars(metadata, {line, column}) # find last env of current module attributes = get_attributes(metadata, module)