From 9dab90cb912c93d9266b5715b070f213af714db8 Mon Sep 17 00:00:00 2001 From: goose Date: Thu, 13 Jul 2023 15:40:21 +0700 Subject: [PATCH] Fix metadata builder to correctly handle pin operator Fixes #223 --- lib/elixir_sense/core/metadata_builder.ex | 3 ++ .../core/metadata_builder_test.exs | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/elixir_sense/core/metadata_builder.ex b/lib/elixir_sense/core/metadata_builder.ex index 683bb6e4..672b6e42 100644 --- a/lib/elixir_sense/core/metadata_builder.ex +++ b/lib/elixir_sense/core/metadata_builder.ex @@ -1820,6 +1820,9 @@ defmodule ElixirSense.Core.MetadataBuilder do {:list, list |> Enum.map(&get_binding_type(state, &1))} end + # pinned variable + def get_binding_type(state, {:^, _, [pinned]}), do: get_binding_type(state, pinned) + # local call def get_binding_type(state, {var, _, args}) when is_atom(var) and is_list(args) do {:local_call, var, Enum.map(args, &get_binding_type(state, &1))} diff --git a/test/elixir_sense/core/metadata_builder_test.exs b/test/elixir_sense/core/metadata_builder_test.exs index 6ef1728c..475ded6b 100644 --- a/test/elixir_sense/core/metadata_builder_test.exs +++ b/test/elixir_sense/core/metadata_builder_test.exs @@ -948,6 +948,42 @@ defmodule ElixirSense.Core.MetadataBuilderTest do ] = state |> get_line_vars(8) end + test "vars binding by pattern matching with pin operators" do + state = + """ + defmodule MyModule do + def func(a) do + b = 1 + case a do + %{b: ^2} = a1 -> 2 + %{b: ^b} = a2 -> b + end + end + end + """ + |> string_to_state + + vars = state |> get_line_vars(5) + + assert %VarInfo{ + name: :a1, + positions: [{5, 18}], + scope_id: 6, + is_definition: true, + type: {:map, [b: {:integer, 2}], nil} + } = Enum.find(vars, &(&1.name == :a1)) + + vars = state |> get_line_vars(6) + + assert %VarInfo{ + name: :a2, + positions: [{6, 18}], + scope_id: 7, + is_definition: true, + type: {:map, [b: {:variable, :b}], nil} + } = Enum.find(vars, &(&1.name == :a2)) + end + test "rebinding vars" do state = """