Repository: hrzndhrn/recode
Pull request #62 (2023-08-01 15:33:05)

Prefix more instances of unused variables with _


Patch:
diff --git a/lib/recode/task/unused_variable.ex b/lib/recode/task/unused_variable.ex
index 8a15f58..c898a1d 100644
--- a/lib/recode/task/unused_variable.ex
+++ b/lib/recode/task/unused_variable.ex
@@ -32,11 +32,8 @@ defmodule Recode.Task.UnusedVariable do
     end
   end
 
-  defp prepend_unused_variable_with_underscore(
-         {{:=, _meta, [{var_name, var_meta, _var_value} = var, _other]}, _zipper_meta} = zipper,
-         issues
-       ) do
-    if unused?(zipper, var) do
+  defp process_unused({var_name, var_meta, nil} = var, search_zipper, zipper, issues) do
+    if unused?(search_zipper, var) do
       zipper = add_underscore(zipper, var)
 
       issue = Issue.new(__MODULE__, "Unused variable: #{var_name}", var_meta)
@@ -47,8 +44,57 @@ defmodule Recode.Task.UnusedVariable do
     end
   end
 
+  defp process_unused(_var, _search_zipper, zipper, issues) do
+    {zipper, issues}
+  end
+
+  defp prepend_unused_variable_with_underscore(
+         {{:=, _meta, [var, _other]}, _zipper_meta} = zipper,
+         issues
+       ) do
+    process_unused(var, Zipper.top(zipper), zipper, issues)
+  end
+
   defp prepend_unused_variable_with_underscore(
-         {_ast, _zipper_meta} = zipper,
+         {{:def, _meta, [{_fun_name, _fun_meta, nil}, _content]}, _zipper_meta} = zipper,
+         issues
+       ) do
+    {zipper, issues}
+  end
+
+  defp prepend_unused_variable_with_underscore(
+         {{:def, _meta, [{_fun_name, _fun_meta, params}, _content]}, _zipper_meta} = zipper,
+         issues
+       ) do
+    {fzipper, fissues} =
+      Enum.reduce(params, {zipper, issues}, fn var, {z, i} ->
+        process_unused(var, zipper, z, i)
+      end)
+
+    {fzipper, fissues}
+  end
+
+  defp prepend_unused_variable_with_underscore(
+         {{:defp, _meta, [{_fun_name, _fun_meta, nil}, _content]}, _zipper_meta} = zipper,
+         issues
+       ) do
+    {zipper, issues}
+  end
+
+  defp prepend_unused_variable_with_underscore(
+         {{:defp, _meta, [{_fun_name, _fun_meta, params}, _content]}, _zipper_meta} = zipper,
+         issues
+       ) do
+    {fzipper, fissues} =
+      Enum.reduce(params, {zipper, issues}, fn var, {z, i} ->
+        process_unused(var, zipper, z, i)
+      end)
+
+    {fzipper, fissues}
+  end
+
+  defp prepend_unused_variable_with_underscore(
+         zipper,
          issues
        ) do
     {zipper, issues}
@@ -67,16 +113,20 @@ defmodule Recode.Task.UnusedVariable do
   end
 
   defp unused?(zipper, {name, metadata, _value}) do
-    {_zipper, references} =
-      Zipper.traverse(zipper, [], fn
-        {{^name, ref_metadata, _value} = ref, _zipper_meta} = zipper, references
-        when metadata != ref_metadata ->
-          {zipper, [ref | references]}
-
-        zipper, references ->
-          {zipper, references}
-      end)
+    if String.starts_with?(Atom.to_string(name), "_") do
+      false
+    else
+      {_zipper, references} =
+        Zipper.traverse(zipper, [], fn
+          {{^name, ref_metadata, _value} = ref, _zipper_meta} = zipper, references
+          when metadata != ref_metadata ->
+            {zipper, [ref | references]}
 
-    references == []
+          zipper, references ->
+            {zipper, references}
+        end)
+
+      references == []
+    end
   end
 end


Test patch:
diff --git a/test/recode/task/unused_variable_test.exs b/test/recode/task/unused_variable_test.exs
index e92ec31..6d5325d 100644
--- a/test/recode/task/unused_variable_test.exs
+++ b/test/recode/task/unused_variable_test.exs
@@ -24,6 +24,82 @@ defmodule Recode.Task.UnusedVariableTest do
       |> assert_code(expected)
     end
 
+    test "fix simple unused variables in comments" do
+      code = """
+      def foo(bar) do
+        # bar is not used
+      end
+      """
+
+      expected = """
+      def foo(_bar) do
+        # bar is not used
+      end
+      """
+
+      code
+      |> run_task(UnusedVariable, autocorrect: true)
+      |> assert_code(expected)
+    end
+
+    test "fix in fun call" do
+      code = """
+      def foo() do
+        bar = String.to_atom()
+        IO.inspect(bar)
+      end
+      """
+
+      expected = """
+      def foo() do
+        bar = String.to_atom()
+        IO.inspect(bar)
+      end
+      """
+
+      code
+      |> run_task(UnusedVariable, autocorrect: true)
+      |> assert_code(expected)
+    end
+
+    test "fix in module" do
+      code = """
+      defmodule MyMod do
+        require Logger
+
+        defp download(items, dir) do
+          Enum.map(items, fn item ->
+            download(item, dir)
+          end)
+        end
+
+        defp download(item, dir) do
+          Logger.info("Downloading")
+        end
+      end
+      """
+
+      expected = """
+      defmodule MyMod do
+        require Logger
+
+        defp download(items, dir) do
+          Enum.map(items, fn item ->
+            download(item, dir)
+          end)
+        end
+
+        defp download(_item, _dir) do
+          Logger.info("Downloading")
+        end
+      end
+      """
+
+      code
+      |> run_task(UnusedVariable, autocorrect: true)
+      |> assert_code(expected)
+    end
+
     test "fix multiple unused variables" do
       code = """
       def foo(bar) do