Repository: nicoespeon/abracadabra
Pull request #772 (2022-12-04 18:29:27)

Do not show 'Change signature' quick fix when a function/method does not has parameters
Hide "Change signature" for function/method without parameters

Error:
![image](https://user-images.githubusercontent.com/8685132/205508512-9fab4315-b9aa-48ae-8af4-2e8d1b74dec0.png)
![image](https://user-images.githubusercontent.com/8685132/205508529-f6151ce0-4045-4d96-8943-b55f0f28ec04.png)

New:

![image](https://user-images.githubusercontent.com/8685132/205508603-cb43083a-c34f-4d7e-ac47-6d73ea6be098.png)
![image](https://user-images.githubusercontent.com/8685132/205508618-bc10d3a2-a3d2-45e3-9af5-82f4fe5d3d8e.png)

Even for React Components

Error:
![image](https://user-images.githubusercontent.com/8685132/205508760-d644f421-7b74-41fe-a980-ce795b9ddc74.png)

New
![image](https://user-images.githubusercontent.com/8685132/205508692-17105ede-0f34-4441-8c54-03d14389537f.png)



Patch:
diff --git a/src/refactorings/change-signature/change-signature.ts b/src/refactorings/change-signature/change-signature.ts
index 2843979f..e9a13480 100644
--- a/src/refactorings/change-signature/change-signature.ts
+++ b/src/refactorings/change-signature/change-signature.ts
@@ -158,11 +158,15 @@ export function createVisitor(
     FunctionDeclaration(path) {
       if (!selection.isInsidePath(path)) return;
 
+      if (!hasParameters(path.node)) return;
+
       onMatch(path, selection);
     },
     ArrowFunctionExpression(path) {
       if (!selection.isInsidePath(path)) return;
 
+      if (!hasParameters(path.node)) return;
+
       if (!t.isVariableDeclarator(path.parent)) return;
 
       if (!path.parent.loc) return;
@@ -171,6 +175,9 @@ export function createVisitor(
     },
     ClassMethod(path) {
       if (!selection.isInsidePath(path)) return;
+
+      if (!hasParameters(path.node)) return;
+
       onMatch(path, selection);
     }
   };
@@ -251,3 +258,9 @@ function createVisitorForReferences(
     }
   };
 }
+
+function hasParameters(
+  node: t.FunctionDeclaration | t.ArrowFunctionExpression | t.ClassMethod
+) {
+  return node.params.length > 0;
+}


Test patch:
diff --git a/src/refactorings/change-signature/change-signature.test.ts b/src/refactorings/change-signature/change-signature.test.ts
index 2bd7fac1..65f3a7e6 100644
--- a/src/refactorings/change-signature/change-signature.test.ts
+++ b/src/refactorings/change-signature/change-signature.test.ts
@@ -1,8 +1,10 @@
+import * as t from "../../ast";
 import { InMemoryEditor } from "../../editor/adapters/in-memory-editor";
 import { AbsolutePath, Code, ErrorReason } from "../../editor/editor";
+import { Selection } from "../../editor/selection";
 import { testEach } from "../../tests-helpers";
 
-import { changeSignature } from "./change-signature";
+import { changeSignature, createVisitor } from "./change-signature";
 
 type TestSample = {
   code: Code;
@@ -541,6 +543,45 @@ describe("Change Signature", () => {
     const extracted = await editor.codeOf(setup.path);
     expect(extracted).toBe(expected.currentFile);
   });
+
+  testEach<{ code: Code; selection?: Selection }>(
+    "should not show refactoring",
+    [
+      {
+        description: "on an arrow function without parameters",
+        code: `const add = () => {
+          return 0;
+        };`,
+        selection: Selection.cursorAt(0, 13)
+      },
+      {
+        description: "on an function without parameters",
+        code: `function add() {
+          return 0;
+        }`,
+        selection: Selection.cursorAt(0, 9)
+      },
+      {
+        description: "on an class method without parameters",
+        code: `class Math {
+          add() {
+            return 0;
+          }
+        }`,
+        selection: Selection.cursorAt(1, 23)
+      }
+    ],
+    ({ code, selection = Selection.cursorAt(0, 13) }) => {
+      const ast = t.parse(code);
+      let canConvert = false;
+      t.traverseAST(
+        ast,
+        createVisitor(selection, () => (canConvert = true))
+      );
+
+      expect(canConvert).toBeFalsy();
+    }
+  );
 });
 
 function validateOutput(