Repository: elm-tooling/elm-language-server (ts)

Issue:
Allow renaming type variables
Need to add logic in `references.ts` for type variables references.


Pull request:
Add type variable references/renames
Closes #404.

Patch:
diff --git a/src/compiler/references.ts b/src/compiler/references.ts
index 271ed7a..b838f9e 100644
--- a/src/compiler/references.ts
+++ b/src/compiler/references.ts
@@ -693,6 +693,70 @@ export class References {
             }
             break;
 
+          case "TypeVariable":
+            {
+              const topLevelAnnotation = TreeUtils.findParentOfType(
+                "type_annotation",
+                definitionNode.node,
+                true,
+              );
+
+              const typeVariableNodes: SyntaxNode[] = [];
+
+              if (topLevelAnnotation) {
+                const topLevelValueDeclaration = TreeUtils.getValueDeclaration(
+                  topLevelAnnotation,
+                );
+
+                const typeAnnotations = [
+                  topLevelAnnotation,
+                  ...(topLevelValueDeclaration?.descendantsOfType(
+                    "type_annotation",
+                  ) ?? []),
+                ];
+
+                typeVariableNodes.push(
+                  ...typeAnnotations.flatMap(
+                    (typeAnnotation) =>
+                      typeAnnotation
+                        .childForFieldName("typeExpression")
+                        ?.descendantsOfType("type_variable") ?? [],
+                  ),
+                );
+              }
+
+              const topLevelTypeOrTypeAlias =
+                TreeUtils.findParentOfType(
+                  "type_alias_declaration",
+                  definitionNode.node,
+                ) ??
+                TreeUtils.findParentOfType(
+                  "type_declaration",
+                  definitionNode.node,
+                );
+
+              if (topLevelTypeOrTypeAlias) {
+                typeVariableNodes.push(
+                  ...topLevelTypeOrTypeAlias.descendantsOfType([
+                    "type_variable",
+                    "lower_type_name",
+                  ]),
+                );
+              }
+
+              typeVariableNodes
+                .filter(
+                  (typeVariable) => typeVariable.text === definitionNode.name,
+                )
+                .forEach((typeVariable) =>
+                  references.push({
+                    node: typeVariable,
+                    uri: typeVariable.tree.uri,
+                  }),
+                );
+            }
+            break;
+
           default:
             break;
         }


Test patch:
diff --git a/test/referencesProviderTests/typeVariableReferences.test.ts b/test/referencesProviderTests/typeVariableReferences.test.ts
new file mode 100644
index 0000000..99bf70a
--- /dev/null
+++ b/test/referencesProviderTests/typeVariableReferences.test.ts
@@ -0,0 +1,66 @@
+import { ReferencesProviderTestBase } from "./referencesProviderTestBase";
+
+describe("typeVariableReferences", () => {
+  const testBase = new ReferencesProviderTestBase();
+
+  it(`simple type annotation type variable reference`, async () => {
+    const source = `
+--@ Module.elm
+module Module exposing (..)
+
+foo : Model a -> a
+          --^  --X
+foo = 42
+`;
+    await testBase.testReferences(source);
+  });
+
+  it(`nested type annotation type variable reference`, async () => {
+    const source = `
+--@ Module.elm
+module Module exposing (..)
+
+foo : Model a -> a
+          --^  --X
+foo = 
+    let
+        func : a -> Model a
+             --X        --X
+        func =
+            32
+
+    in
+    42
+`;
+    await testBase.testReferences(source);
+  });
+
+  it(`type alias type variable reference`, async () => {
+    const source = `
+--@ Module.elm
+module Module exposing (..)
+
+type alias Foo a b =
+             --^
+    { bar : a
+          --X
+    , baz : b
+    }
+`;
+    await testBase.testReferences(source);
+  });
+
+  it(`type declaration type variable reference`, async () => {
+    const source = `
+--@ Module.elm
+module Module exposing (..)
+
+type Maybe a
+         --^
+    = Just a
+         --X
+    | Nothing
+`;
+    await testBase.testReferences(source);
+  });
+});