Skip to content

Commit

Permalink
extract end positions from typespecs
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Jul 7, 2023
1 parent dc5896b commit 24e542c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 69 deletions.
82 changes: 38 additions & 44 deletions lib/elixir_sense/core/metadata_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ defmodule ElixirSense.Core.MetadataBuilder do
types
|> Enum.reduce(state, fn {type_name, type_args, spec, kind}, acc ->
acc
|> add_type(type_name, type_args, kind, spec, position, generated: true)
|> add_type(type_name, type_args, kind, spec, position, end_position, generated: true)
end)

state =
Expand All @@ -121,7 +121,7 @@ defmodule ElixirSense.Core.MetadataBuilder do
name,
mapped_args,
position,
nil,
end_position,
kind,
generated: true
)
Expand Down Expand Up @@ -439,27 +439,33 @@ defmodule ElixirSense.Core.MetadataBuilder do
|> result(ast)
end

defp pre_type(ast, state, {line, _column} = pos, type_name, type_args, spec, kind) do
defp pre_type(ast, state, meta, type_name, type_args, spec, kind) do
spec = TypeInfo.typespec_to_string(kind, spec)

{position = {line, _column}, end_position} = extract_range(meta)

state
|> add_type(type_name, type_args, spec, kind, pos, generated: state.generated)
|> add_type(type_name, type_args, spec, kind, position, end_position,
generated: state.generated
)
|> add_typespec_namespace(type_name, length(type_args))
|> add_current_env_to_line(line)
|> result(ast)
end

defp pre_spec(ast, state, {line, column} = pos, type_name, type_args, spec, kind) do
defp pre_spec(ast, state, meta, type_name, type_args, spec, kind) do
spec = TypeInfo.typespec_to_string(kind, spec)

{position = {line, _column}, end_position} = extract_range(meta)

state =
if kind in [:callback, :macrocallback] do
state
|> add_func_to_index(
:behaviour_info,
[{:atom, [line: line, column: column], nil}],
pos,
nil,
[{:atom, meta, nil}],
position,
end_position,
:def,
generated: true
)
Expand All @@ -468,7 +474,9 @@ defmodule ElixirSense.Core.MetadataBuilder do
end

state
|> add_spec(type_name, type_args, spec, kind, pos, generated: state.generated)
|> add_spec(type_name, type_args, spec, kind, position, end_position,
generated: state.generated
)
|> add_typespec_namespace(type_name, length(type_args))
|> add_current_env_to_line(line)
|> result(ast)
Expand Down Expand Up @@ -669,13 +677,10 @@ defmodule ElixirSense.Core.MetadataBuilder do
)
when kind in [:type, :typep, :opaque] and is_atom(name) and
(is_nil(type_args) or is_list(type_args)) do
line = Keyword.fetch!(meta_attr, :line)
column = Keyword.fetch!(meta_attr, :column)

pre_type(
ast,
state,
{line, column},
meta_attr,
name,
List.wrap(type_args),
expand_aliases_in_ast(state, spec),
Expand All @@ -693,13 +698,10 @@ defmodule ElixirSense.Core.MetadataBuilder do
)
when kind in [:spec, :callback, :macrocallback] and is_atom(name) and
(is_nil(type_args) or is_list(type_args)) do
line = Keyword.fetch!(meta_attr, :line)
column = Keyword.fetch!(meta_attr, :column)

pre_spec(
ast,
state,
{line, column},
meta_attr,
name,
expand_aliases_in_ast(state, List.wrap(type_args)),
expand_aliases_in_ast(state, spec),
Expand All @@ -715,13 +717,10 @@ defmodule ElixirSense.Core.MetadataBuilder do
)
when kind in [:spec, :callback, :macrocallback] and is_atom(name) and
(is_nil(type_args) or is_list(type_args)) do
line = Keyword.fetch!(meta_attr, :line)
column = Keyword.fetch!(meta_attr, :column)

pre_spec(
ast,
state,
{line, column},
meta_attr,
name,
expand_aliases_in_ast(state, List.wrap(type_args)),
expand_aliases_in_ast(state, spec),
Expand All @@ -737,13 +736,10 @@ defmodule ElixirSense.Core.MetadataBuilder do
)
when kind in [:spec, :callback, :macrocallback] and is_atom(name) and
(is_nil(type_args) or is_list(type_args)) do
line = Keyword.fetch!(meta_attr, :line)
column = Keyword.fetch!(meta_attr, :column)

pre_spec(
ast,
state,
{line, column},
meta_attr,
name,
expand_aliases_in_ast(state, List.wrap(type_args)),
expand_aliases_in_ast(state, spec),
Expand Down Expand Up @@ -1067,8 +1063,7 @@ defmodule ElixirSense.Core.MetadataBuilder do

defp pre({type, meta, fields} = ast, state)
when type in [:defstruct, :defexception] do
line = Keyword.fetch!(meta, :line)
column = Keyword.fetch!(meta, :column)
{position, end_position} = extract_range(meta)

fields =
case fields do
Expand All @@ -1089,7 +1084,7 @@ defmodule ElixirSense.Core.MetadataBuilder do
end

state
|> add_struct_or_exception(type, fields, {line, column})
|> add_struct_or_exception(type, fields, position, end_position)
|> result(ast)
end

Expand Down Expand Up @@ -1167,8 +1162,7 @@ defmodule ElixirSense.Core.MetadataBuilder do
)
when is_call(call, params) and is_call_meta(meta) and call in [:defrecord, :defrecordp] and
is_atom(name) do
line = Keyword.fetch!(meta1, :line)
column = Keyword.fetch!(meta1, :column)
{position = {line, column}, end_position} = extract_range(meta1)

module = concat_module_expression(state, module_expression)

Expand All @@ -1185,17 +1179,17 @@ defmodule ElixirSense.Core.MetadataBuilder do
|> add_func_to_index(
name,
[{:\\, [], [{:args, [], nil}, []]}],
{line, column},
nil,
position,
end_position,
type,
options
)
|> new_named_func(name, 2)
|> add_func_to_index(
name,
[{:record, [], nil}, {:args, [], nil}],
{line, column},
nil,
position,
end_position,
type,
options
)
Expand Down Expand Up @@ -1929,7 +1923,7 @@ defmodule ElixirSense.Core.MetadataBuilder do

defp maybe_add_protocol_behaviour(state, _), do: state

defp add_struct_or_exception(state, type, fields, {line, column}) do
defp add_struct_or_exception(state, type, fields, {line, column} = position, end_position) do
fields =
fields ++
if type == :defexception do
Expand All @@ -1951,16 +1945,16 @@ defmodule ElixirSense.Core.MetadataBuilder do
|> add_func_to_index(
:exception,
[{:msg, [line: line, column: column], nil}],
{line, column},
nil,
position,
end_position,
:def,
options
)
|> add_func_to_index(
:message,
[{:exception, [line: line, column: column], nil}],
{line, column},
nil,
position,
end_position,
:def,
options
)
Expand All @@ -1970,20 +1964,20 @@ defmodule ElixirSense.Core.MetadataBuilder do
|> add_func_to_index(
:exception,
[{:args, [line: line, column: column], nil}],
{line, column},
nil,
position,
end_position,
:def,
options
)
else
state
end
|> add_func_to_index(:__struct__, [], {line, column}, nil, :def, options)
|> add_func_to_index(:__struct__, [], position, end_position, :def, options)
|> add_func_to_index(
:__struct__,
[{:kv, [line: line, column: column], nil}],
{line, column},
nil,
position,
end_position,
:def,
options
)
Expand Down
23 changes: 15 additions & 8 deletions lib/elixir_sense/core/state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,16 @@ defmodule ElixirSense.Core.State do
Enum.reduce(modules, state, fn mod, state -> add_require(state, mod) end)
end

def add_type(%__MODULE__{} = state, type_name, type_args, spec, kind, pos, options \\ []) do
def add_type(
%__MODULE__{} = state,
type_name,
type_args,
spec,
kind,
pos,
end_pos,
options \\ []
) do
arg_names =
type_args
|> Enum.map(&Macro.to_string/1)
Expand All @@ -1077,8 +1086,7 @@ defmodule ElixirSense.Core.State do
specs: [spec],
generated: [Keyword.get(options, :generated, false)],
positions: [pos],
# no end pos info in AST as of elixir 1.15
end_positions: [nil]
end_positions: [end_pos]
}

current_module_variants = get_current_module_variants(state)
Expand All @@ -1095,7 +1103,7 @@ defmodule ElixirSense.Core.State do
%TypeInfo{
ti
| positions: [pos | positions],
end_positions: [nil | ti.end_positions],
end_positions: [end_pos | ti.end_positions],
generated: [Keyword.get(options, :generated, false) | ti.generated],
args: [arg_names | args],
specs: [spec | specs],
Expand All @@ -1112,7 +1120,7 @@ defmodule ElixirSense.Core.State do
%__MODULE__{state | types: types}
end

def add_spec(%__MODULE__{} = state, type_name, type_args, spec, kind, pos, options) do
def add_spec(%__MODULE__{} = state, type_name, type_args, spec, kind, pos, end_pos, options) do
arg_names =
type_args
|> Enum.map(&Macro.to_string/1)
Expand All @@ -1124,8 +1132,7 @@ defmodule ElixirSense.Core.State do
kind: kind,
generated: [Keyword.get(options, :generated, false)],
positions: [pos],
# no end pos info in AST as of elixir 1.15
end_positions: [nil]
end_positions: [end_pos]
}

current_module_variants = get_current_module_variants(state)
Expand All @@ -1142,7 +1149,7 @@ defmodule ElixirSense.Core.State do
%SpecInfo{
ti
| positions: [pos | positions],
end_positions: [nil | ti.end_positions],
end_positions: [end_pos | ti.end_positions],
generated: [Keyword.get(options, :generated, false) | ti.generated],
args: [arg_names | args],
specs: [spec | specs]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule ElixirSense.Providers.Suggestion.Reducers.DocsSnippets do
@doc """
A reducer that adds suggestions for @doc, @moduledoc and @typedoc.
"""
def add_snippets(hint, env, _metadata, %{at_module_body?: true}, acc) do
def add_snippets(hint, _env, _metadata, %{at_module_body?: true}, acc) do
list =
for {label, snippet, doc, priority} <- @module_attr_snippets,
Matcher.match?(label, hint) do
Expand Down
Loading

0 comments on commit 24e542c

Please sign in to comment.