Skip to content

Commit

Permalink
collect records in metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Oct 30, 2024
1 parent 3d7a3ea commit 6c293f2
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 4 deletions.
10 changes: 9 additions & 1 deletion lib/elixir_sense/core/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,14 @@ defmodule ElixirSense.Core.Compiler do
)
when call in [:defrecord, :defrecordp] and module != nil do
range = State.extract_range(meta)
{[name, _fields] = args, state, env} = expand(args, state, env)
{[name, fields] = args, state, env} = expand(args, state, env)

fields =
if Keyword.keyword?(fields) do
fields
else
[]
end

type =
case call do
Expand Down Expand Up @@ -1377,6 +1384,7 @@ defmodule ElixirSense.Core.Compiler do
type,
options
)
|> State.add_record(env, call, name, fields)
|> State.add_current_env_to_line(meta, env)

{{{:., meta, [Record, call]}, meta, args}, state, env}
Expand Down
12 changes: 12 additions & 0 deletions lib/elixir_sense/core/compiler/state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule ElixirSense.Core.Compiler.State do
alias ElixirSense.Core.State.{
CallInfo,
StructInfo,
RecordInfo,
ModFunInfo,
SpecInfo,
TypeInfo,
Expand Down Expand Up @@ -39,6 +40,7 @@ defmodule ElixirSense.Core.Compiler.State do
]
}
@type structs_t :: %{optional(module) => ElixirSense.Core.State.StructInfo.t()}
@type records_t :: %{optional({module, atom}) => ElixirSense.Core.State.RecordInfo.t()}
@type protocol_t :: {module, nonempty_list(module)}
@type var_type :: nil | {:atom, atom} | {:map, keyword} | {:struct, keyword, module}

Expand All @@ -50,6 +52,7 @@ defmodule ElixirSense.Core.Compiler.State do
types: types_t,
mods_funs_to_positions: mods_funs_to_positions_t,
structs: structs_t,
records: records_t,
calls: calls_t,
vars_info:
list(%{optional({atom, non_neg_integer}) => ElixirSense.Core.State.VarInfo.t()}),
Expand Down Expand Up @@ -89,6 +92,7 @@ defmodule ElixirSense.Core.Compiler.State do
types: %{},
mods_funs_to_positions: %{},
structs: %{},
records: %{},
calls: %{},
vars_info: [%{}],
vars_info_per_scope_id: %{},
Expand Down Expand Up @@ -356,6 +360,14 @@ defmodule ElixirSense.Core.Compiler.State do
%__MODULE__{state | structs: structs}
end

def add_record(%__MODULE__{} = state, env, type, name, fields) do
records =
state.records
|> Map.put({env.module, name}, %RecordInfo{type: type, fields: fields})

%__MODULE__{state | records: records}
end

defp get_current_attributes(%__MODULE__{} = state) do
state.scope_attributes |> :lists.reverse() |> List.flatten()
end
Expand Down
3 changes: 3 additions & 0 deletions lib/elixir_sense/core/metadata.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defmodule ElixirSense.Core.Metadata do
types: State.types_t(),
specs: State.specs_t(),
structs: State.structs_t(),
records: State.records_t(),
error: nil | term,
first_alias_positions: map(),
moduledoc_positions: map()
Expand All @@ -39,6 +40,7 @@ defmodule ElixirSense.Core.Metadata do
types: %{},
specs: %{},
structs: %{},
records: %{},
error: nil,
first_alias_positions: %{},
moduledoc_positions: %{}
Expand All @@ -58,6 +60,7 @@ defmodule ElixirSense.Core.Metadata do
types: acc.types,
specs: acc.specs,
structs: acc.structs,
records: acc.records,
mods_funs_to_positions: acc.mods_funs_to_positions,
lines_to_env: acc.lines_to_env,
vars_info_per_scope_id: acc.vars_info_per_scope_id,
Expand Down
1 change: 1 addition & 0 deletions lib/elixir_sense/core/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ defmodule ElixirSense.Core.Parser do
types: acc.types,
specs: acc.specs,
structs: acc.structs,
records: acc.records,
mods_funs_to_positions: acc.mods_funs_to_positions,
cursor_env: acc.cursor_env,
closest_env: acc.closest_env,
Expand Down
11 changes: 11 additions & 0 deletions lib/elixir_sense/core/state/record_info.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule ElixirSense.Core.State.RecordInfo do
@moduledoc """
Record definition info
"""
@type field_t :: {atom, any}
@type t :: %ElixirSense.Core.State.RecordInfo{
type: :defrecord | :defrecordp,
fields: list(field_t)
}
defstruct type: :defrecord, fields: []
end
27 changes: 24 additions & 3 deletions test/elixir_sense/core/metadata_builder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ defmodule ElixirSense.Core.MetadataBuilderTest do
alias ElixirSense.Core.MetadataBuilder
alias ElixirSense.Core.Source
alias ElixirSense.Core.State
alias ElixirSense.Core.State.{VarInfo, CallInfo, StructInfo, ModFunInfo, AttributeInfo}

alias ElixirSense.Core.State.{
VarInfo,
CallInfo,
StructInfo,
ModFunInfo,
AttributeInfo,
RecordInfo
}

describe "versioned_vars" do
test "in block" do
Expand Down Expand Up @@ -8523,6 +8531,21 @@ defmodule ElixirSense.Core.MetadataBuilderTest do
"""
|> string_to_state

assert %{
{MyRecords, :my_rec} => %RecordInfo{
type: :defrecord,
fields: []
},
{MyRecords, :user} => %RecordInfo{
type: :defrecord,
fields: [name: "meg", age: "25"]
},
{MyRecords, :userp} => %RecordInfo{
type: :defrecordp,
fields: [name: "meg", age: "25"]
}
} = state.records

assert %{
{MyRecords, :user, 1} => %ModFunInfo{
params: [[{:\\, [], [{:args, [], nil}, []]}]],
Expand Down Expand Up @@ -8826,8 +8849,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do
"""
|> string_to_state

# dbg(state.lines_to_env |> Enum.map(fn {k, v} -> {k, %{module: v.module, function: v.function, typespec: v.typespec}} end))

assert nil == get_line_typespec(state, 1)
assert nil == get_line_function(state, 1)
assert nil == get_line_module(state, 1)
Expand Down

0 comments on commit 6c293f2

Please sign in to comment.