Skip to content

Commit

Permalink
Fixed unused variable code action (#628)
Browse files Browse the repository at this point in the history
The quote character around the variable name was changed, this broke
the code action for replace unused variables.
  • Loading branch information
scohen authored Feb 29, 2024
1 parent 163ff91 commit a06bb03
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 72 deletions.
8 changes: 2 additions & 6 deletions apps/remote_control/lib/lexical/remote_control/build/error.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ defmodule Lexical.RemoteControl.Build.Error do

defp format_message("undefined" <> _ = message) do
# All undefined function messages explain the *same* thing inside the parentheses
message |> String.replace(@undefined_function_pattern, "") |> format_token()
String.replace(message, @undefined_function_pattern, "")
end

defp format_message(message) when is_binary(message) do
Expand All @@ -61,17 +61,13 @@ defmodule Lexical.RemoteControl.Build.Error do
# Same reason as the `undefined` message above, we can remove the things in parentheses
case String.split(message, "is unused (", parts: 2) do
[prefix, _] ->
format_token(prefix) <> "is unused"
prefix <> "is unused"

_ ->
message
end
end

defp format_token(string_contains_token) do
String.replace(string_contains_token, "\"", "`")
end

@doc """
The `diagnostics_from_mix/2` is only for Elixir version > 1.15
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.EExTest do
|> document_with_content()
|> compile()

assert result.message =~ ~s[`something` is unused]
assert result.message =~ ~s["something" is unused]
assert result.position in [1, {1, 5}]
assert result.severity == :warning
assert result.source == "EEx"
Expand All @@ -115,7 +115,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.EExTest do

assert {:ok, [%Result{} = result]} = compile(document)

assert result.message == ~s[variable `something` is unused]
assert result.message == ~s[variable "something" is unused]
assert decorate(document, result.position) == "<%= «something» = 6 %>"
assert result.severity == :warning
assert result.source == "EEx"
Expand Down Expand Up @@ -147,7 +147,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.EExTest do
assert {:error, [%Result{} = result]} = compile(document)

if Features.with_diagnostics?() do
assert result.message =~ "undefined variable `thing`"
assert result.message =~ "undefined variable \"thing\""
else
assert result.message =~ "undefined function thing/0"
end
Expand All @@ -167,7 +167,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.EExTest do

assert {:error, [%Result{} = result]} = compile(document)

assert result.message == "undefined variable `thing`"
assert result.message == "undefined variable \"thing\""
assert decorate(document, result.position) == "<%= «thing» %>"
assert result.severity == :error
assert result.source == "EEx"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ defmodule Lexical.RemoteControl.Build.Document.Compilers.HeexTest do
assert {:error, [%Result{} = result]} = compile(document)

if Features.with_diagnostics?() do
assert result.message =~ ~S[undefined variable `thing`]
assert result.message =~ ~S[undefined variable "thing"]
else
assert result.message =~ "undefined function thing/0"
assert result.position in [1, {1, 10}]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles undefined variable" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
a
Expand All @@ -81,15 +80,14 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
|> compile()
|> diagnostic()

assert diagnostic.message in [~s[undefined variable `a`], ~s[undefined function a/0]]
assert diagnostic.message in [~s[undefined variable "a"], ~s[undefined function a/0]]
assert decorate(document_text, diagnostic.position) =~ "«a\n»"
end

@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles undefined variable when #{inspect(@feature_condition)}" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
a
Expand All @@ -102,15 +100,14 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
|> compile()
|> diagnostic()

assert diagnostic.message == ~s[undefined variable `a`]
assert diagnostic.message == ~s[undefined variable "a"]
assert decorate(document_text, diagnostic.position) =~ "«a»"
end

@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles unsued variable warning" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
a = 1
Expand All @@ -123,15 +120,14 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
|> compile()
|> diagnostic()

assert diagnostic.message =~ ~s[variable `a` is unused]
assert diagnostic.message =~ ~s[variable "a" is unused]
assert decorate(document_text, diagnostic.position) =~ "«a = 1\n»"
end

@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles unsued variable warning when #{inspect(@feature_condition)}" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
a = 1
Expand All @@ -144,15 +140,14 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
|> compile()
|> diagnostic()

assert diagnostic.message == ~s[variable `a` is unused]
assert diagnostic.message == ~s[variable "a" is unused]
assert decorate(document_text, diagnostic.position) =~ "«a»"
end

@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles unused function warning" do
document_text =
~S[
document_text = ~S[
defmodule UnusedDefp do
defp unused do
end
Expand All @@ -173,8 +168,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles unused function warning when #{inspect(@feature_condition)}" do
document_text =
~S[
document_text = ~S[
defmodule UnusedDefp do
defp unused do
end
Expand All @@ -193,8 +187,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles FunctionClauseError" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def add(a, b) when is_integer(a) and is_integer(b) do
a + b
Expand All @@ -216,8 +209,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles UndefinedError for erlang moudle" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
:slave.stop
end
Expand All @@ -233,8 +225,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles UndefinedError for erlang function without defined module" do
document_text =
~S[
document_text = ~S[
:slave.stop(:name, :name)
]
Expand All @@ -252,8 +243,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles UndefinedError" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
print(:bar)
Expand All @@ -275,8 +265,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles UndefinedError when #{inspect(@feature_condition)}" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
def bar do
print(:bar)
Expand All @@ -298,8 +287,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles multiple UndefinedError in one line" do
document_text =
~S/
document_text = ~S/
defmodule Foo do
def bar do
[print(:bar), a, b]
Expand All @@ -319,8 +307,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles multiple UndefinedError in one line when #{inspect(@feature_condition)}" do
document_text =
~S/
document_text = ~S/
defmodule Foo do
def bar do
[print(:bar), a, b]
Expand All @@ -333,19 +320,18 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
|> compile()
|> diagnostics()

assert a.message == ~s[undefined variable `a`]
assert a.message == ~s[undefined variable "a"]
assert decorate(document_text, a.position) =~ "«a»"

assert b.message == ~s[undefined variable `b`]
assert b.message == ~s[undefined variable "b"]
assert decorate(document_text, b.position) =~ "«b»"

assert func_diagnotic.message == ~s[undefined function print/1]
assert decorate(document_text, func_diagnotic.position) =~ "«print»(:bar)"
end

test "handles UndefinedError without moudle" do
document_text =
~S[
document_text = ~S[
IO.ins
]
Expand Down Expand Up @@ -387,8 +373,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles ArgumentError when in module" do
document_text =
~s[
document_text = ~s[
defmodule Foo do
:a |> {1, 2}
end
Expand All @@ -406,8 +391,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles ArgumentError when in function" do
document_text =
~s[
document_text = ~s[
defmodule Foo do
def foo do
:a |> {1, 2}
Expand Down Expand Up @@ -444,8 +428,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles Protocol.UndefinedError for comprehension" do
document_text =
~S[
document_text = ~S[
defmodule Foo do
for i <- 1, do: i
end]
Expand All @@ -460,8 +443,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles Protocol.UndefinedError for comprehension when no module" do
document_text =
~S[
document_text = ~S[
for i <- 1, do: i
]

Expand All @@ -475,8 +457,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles RuntimeError" do
document_text =
~S[defmodule Foo do
document_text = ~S[defmodule Foo do
raise RuntimeError.exception("This is a runtime error")
end
]
Expand All @@ -493,8 +474,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles ExUnit.DuplicateTestError" do
document_text =
~s[
document_text = ~s[
defmodule FooTest do
use ExUnit.Case, async: true
Expand All @@ -518,8 +498,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles ExUnit.DuplicateDescribeError" do
document_text =
~s[
document_text = ~s[
defmodule FooTest do
use ExUnit.Case, async: true
Expand Down Expand Up @@ -548,8 +527,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles struct `KeyError` when is in a function block" do
document_text =
~s(
document_text = ~s(
defmodule Foo do
defstruct [:a, :b]
end
Expand All @@ -573,8 +551,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: false
@tag execute_if(@feature_condition)
test "handles struct `CompileError` when is in a function params" do
document_text =
~S/
document_text = ~S/
defmodule Foo do
defstruct [:a, :b]
end
Expand Down Expand Up @@ -603,8 +580,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
@feature_condition span_in_diagnostic?: true
@tag execute_if(@feature_condition)
test "handles struct `CompileError` when is in a function params and #{inspect(@feature_condition)}" do
document_text =
~S/
document_text = ~S/
defmodule Foo do
defstruct [:a, :b]
end
Expand All @@ -623,13 +599,12 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
assert unknown.message == "unknown key :c for struct Foo"
assert decorate(document_text, unknown.position) =~ "def bar(«%Foo{c: c}) do\n»"

assert undefined.message == "variable `c` is unused"
assert undefined.message == "variable \"c\" is unused"
assert decorate(document_text, undefined.position) =~ "def bar(%Foo{c: «c»}) do"
end

test "handles struct enforce key error" do
document_text =
~s(
document_text = ~s(
defmodule Foo do
@enforce_keys [:a, :b]
defstruct [:a, :b]
Expand All @@ -654,8 +629,7 @@ defmodule Lexical.RemoteControl.Build.ErrorTest do
end

test "handles record missing key's error" do
document_text =
~s[
document_text = ~s[
defmodule Bar do
import Record
defrecord :user, name: nil, age: nil
Expand Down
Loading

0 comments on commit a06bb03

Please sign in to comment.