From ab094c99b56df4874e9ed17cf2823b6b9f61e5ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 00:20:54 +0000 Subject: [PATCH 1/4] Bump tree-sitter-cli from 0.20.8 to 0.25.3 Bumps [tree-sitter-cli](https://github.com/tree-sitter/tree-sitter) from 0.20.8 to 0.25.3. - [Release notes](https://github.com/tree-sitter/tree-sitter/releases) - [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.8...v0.25.3) --- updated-dependencies: - dependency-name: tree-sitter-cli dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 18 +++++++++++------- package.json | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97a119dc..04e9f3fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "jest-diff": "^29.7.0", "jest-mock-extended": "^3.0.5", "prettier": "^3.1.1", - "tree-sitter-cli": "^0.20.8", + "tree-sitter-cli": "^0.25.3", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "typescript": "5.3.3" @@ -6137,13 +6137,17 @@ "dev": true }, "node_modules/tree-sitter-cli": { - "version": "0.20.8", - "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", - "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.3.tgz", + "integrity": "sha512-Bk6ZUXG+cKnwZpfR/te4NDrKld90p6350eqWlbLwSpV9/8vmL/x8LCw+3k7quY9oMDaYoMXHMvokXJbkM5A7bA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "tree-sitter": "cli.js" + }, + "engines": { + "node": ">=12.0.0" } }, "node_modules/trough": { @@ -11162,9 +11166,9 @@ "dev": true }, "tree-sitter-cli": { - "version": "0.20.8", - "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz", - "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.3.tgz", + "integrity": "sha512-Bk6ZUXG+cKnwZpfR/te4NDrKld90p6350eqWlbLwSpV9/8vmL/x8LCw+3k7quY9oMDaYoMXHMvokXJbkM5A7bA==", "dev": true }, "trough": { diff --git a/package.json b/package.json index 1ede5503..491494d6 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "jest-diff": "^29.7.0", "jest-mock-extended": "^3.0.5", "prettier": "^3.1.1", - "tree-sitter-cli": "^0.20.8", + "tree-sitter-cli": "^0.25.3", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "typescript": "5.3.3" From f4acd6be65cc266f534da50c02fc2f388902bf09 Mon Sep 17 00:00:00 2001 From: Razze Date: Sun, 30 Mar 2025 18:27:36 +0200 Subject: [PATCH 2/4] Update tree-sitter --- package-lock.json | 90 +++++++++++++++++++++++++++++-------------- package.json | 6 +-- tree-sitter-elm.wasm | Bin 189901 -> 181224 bytes 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04e9f3fb..83fb9117 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,13 +22,13 @@ "vscode-languageserver": "^9.0.1", "vscode-languageserver-textdocument": "1.0.11", "vscode-uri": "^3.0.8", - "web-tree-sitter": "^0.20.8" + "web-tree-sitter": "^0.25.3" }, "bin": { "elm-language-server": "out/node/index.js" }, "devDependencies": { - "@elm-tooling/tree-sitter-elm": "^5.7.0", + "@elm-tooling/tree-sitter-elm": "^5.8.0", "@types/jest": "^29.5.11", "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.15.0", @@ -835,13 +835,23 @@ } }, "node_modules/@elm-tooling/tree-sitter-elm": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@elm-tooling/tree-sitter-elm/-/tree-sitter-elm-5.7.0.tgz", - "integrity": "sha512-ezKHIczyZx6bFtktLFRPbvW/7LzL0XdI1Y5OoxkNaSrfh2m0Bm8yilbB4Hya4VQN7mJktXhhzAMGab8nKm/2Bw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@elm-tooling/tree-sitter-elm/-/tree-sitter-elm-5.8.0.tgz", + "integrity": "sha512-AOCJlUumWqetQxXkRf3ZpztbTNeyBB2NfuOKokZgLSF7TboctgOCpR7MMrJk9/uGn8rPbcg1gOyhZOQBl1MOpQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { - "nan": "^2.18.0" + "node-addon-api": "^8.2.1", + "node-gyp-build": "^4.8.2" + }, + "peerDependencies": { + "tree-sitter": "^0.21.1" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } } }, "node_modules/@eslint-community/eslint-utils": { @@ -5160,18 +5170,34 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/node-addon-api": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", + "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6579,9 +6605,10 @@ } }, "node_modules/web-tree-sitter": { - "version": "0.20.8", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.8.tgz", - "integrity": "sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==" + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.25.3.tgz", + "integrity": "sha512-e0hdXG+nJ18Zd/QJFhSx0DNTSMz7miwUjKyJ/lglTnZo6ke08++BQzXkaeaqnGJFi9qq+nPJg2L8hYAjduToHQ==", + "license": "MIT" }, "node_modules/which": { "version": "2.0.2", @@ -7307,12 +7334,13 @@ } }, "@elm-tooling/tree-sitter-elm": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@elm-tooling/tree-sitter-elm/-/tree-sitter-elm-5.7.0.tgz", - "integrity": "sha512-ezKHIczyZx6bFtktLFRPbvW/7LzL0XdI1Y5OoxkNaSrfh2m0Bm8yilbB4Hya4VQN7mJktXhhzAMGab8nKm/2Bw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@elm-tooling/tree-sitter-elm/-/tree-sitter-elm-5.8.0.tgz", + "integrity": "sha512-AOCJlUumWqetQxXkRf3ZpztbTNeyBB2NfuOKokZgLSF7TboctgOCpR7MMrJk9/uGn8rPbcg1gOyhZOQBl1MOpQ==", "dev": true, "requires": { - "nan": "^2.18.0" + "node-addon-api": "^8.2.1", + "node-gyp-build": "^4.8.2" } }, "@eslint-community/eslint-utils": { @@ -10455,18 +10483,24 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node-addon-api": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", + "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", + "dev": true + }, + "node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11463,9 +11497,9 @@ } }, "web-tree-sitter": { - "version": "0.20.8", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.8.tgz", - "integrity": "sha512-weOVgZ3aAARgdnb220GqYuh7+rZU0Ka9k9yfKtGAzEYMa6GgiCzW9JjQRJyCJakvibQW+dfjJdihjInKuuCAUQ==" + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.25.3.tgz", + "integrity": "sha512-e0hdXG+nJ18Zd/QJFhSx0DNTSMz7miwUjKyJ/lglTnZo6ke08++BQzXkaeaqnGJFi9qq+nPJg2L8hYAjduToHQ==" }, "which": { "version": "2.0.2", diff --git a/package.json b/package.json index 491494d6..faf5ef27 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,10 @@ "vscode-languageserver": "^9.0.1", "vscode-languageserver-textdocument": "1.0.11", "vscode-uri": "^3.0.8", - "web-tree-sitter": "^0.20.8" + "web-tree-sitter": "^0.25.3" }, "devDependencies": { - "@elm-tooling/tree-sitter-elm": "^5.7.0", + "@elm-tooling/tree-sitter-elm": "^5.8.0", "@types/jest": "^29.5.11", "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.15.0", @@ -62,7 +62,7 @@ "watch": "npm run copy-wasm && tsc -watch -p ./", "lint": "eslint -c .eslintrc.js --ext .ts src", "lint:fix": "eslint --fix -c .eslintrc.js --ext .ts src", - "build-tree-sitter": "tree-sitter build-wasm ./node_modules/@elm-tooling/tree-sitter-elm", + "build-tree-sitter": "tree-sitter build --wasm ./node_modules/@elm-tooling/tree-sitter-elm", "test": "jest --coverage", "generate-toc": "doctoc README.md" }, diff --git a/tree-sitter-elm.wasm b/tree-sitter-elm.wasm index aa7cef58b683a681030d9f7126e9e7dcf21c3f5c..9da0251315962bab483bcefff78a94eb3b280064 100755 GIT binary patch literal 181224 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 literal 189901 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 Date: Sun, 30 Mar 2025 18:45:16 +0200 Subject: [PATCH 3/4] Remove custom types and rename SyntaxNode to new name --- src/common/providers/astProvider.ts | 8 +- .../addMissingRecordFieldCodeAction.ts | 4 +- .../codeAction/addNewFunctionParameter.ts | 10 +- .../codeAction/extractFunctionCodeAction.ts | 8 +- .../codeAction/extractTypeAliasCodeAction.ts | 4 +- .../providers/codeAction/importCodeAction.ts | 6 +- src/common/providers/codeLensProvider.ts | 11 +- src/common/providers/completionProvider.ts | 12 +- src/common/providers/definitionProvider.ts | 4 +- .../providers/diagnostics/elmLsDiagnostics.ts | 6 +- .../providers/documentSymbolProvider.ts | 4 +- src/common/providers/findTestsProvider.ts | 10 +- src/common/providers/foldingProvider.ts | 8 +- src/common/providers/renameProvider.ts | 14 +- .../providers/selectionRangeProvider.ts | 4 +- .../providers/workspaceSymbolProvider.ts | 6 +- src/common/util/hintHelper.ts | 14 +- src/common/util/importUtils.ts | 4 +- src/common/util/refactorEditUtils.ts | 30 ++-- src/common/util/referenceNode.ts | 4 +- src/common/util/renameUtils.ts | 6 +- src/common/util/symbolTranslator.ts | 6 +- src/common/util/treeUtils.ts | 145 ++++++++---------- src/compiler/binder.ts | 30 ++-- src/compiler/diagnostics.ts | 8 +- src/compiler/forest.ts | 4 +- src/compiler/imports.ts | 12 +- src/compiler/patternMatches.ts | 29 ++-- src/compiler/references.ts | 35 ++--- src/compiler/typeCache.ts | 68 +++----- src/compiler/typeChecker.ts | 52 +++---- src/compiler/typeInference.ts | 19 +-- src/compiler/utils/expressionTree.ts | 120 +++++++-------- .../utils/recordFieldReferenceTable.ts | 4 +- src/compiler/utils/syntaxNodeMap.ts | 4 +- src/compiler/utils/syntaxNodeSet.ts | 4 +- src/typings/web-tree-sitter/index.d.ts | 54 ------- test/diagnosticTests/elmDiagnostics.test.ts | 20 +-- 38 files changed, 337 insertions(+), 454 deletions(-) delete mode 100644 src/typings/web-tree-sitter/index.d.ts diff --git a/src/common/providers/astProvider.ts b/src/common/providers/astProvider.ts index 8571b5f9..57ef11de 100644 --- a/src/common/providers/astProvider.ts +++ b/src/common/providers/astProvider.ts @@ -8,7 +8,7 @@ import { FileChangeType, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import Parser, { Edit, Point, SyntaxNode } from "web-tree-sitter"; +import Parser, { Edit, Point, Node } from "web-tree-sitter"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { Position, @@ -28,11 +28,11 @@ export class ASTProvider { private treeChangeEvent = new Emitter<{ sourceFile: ISourceFile; - declaration?: SyntaxNode; + declaration?: Node; }>(); readonly onTreeChange: Event<{ sourceFile: ISourceFile; - declaration?: SyntaxNode; + declaration?: Node; }> = this.treeChangeEvent.event; private treeDeleteEvent = new Emitter<{ uri: string }>(); @@ -132,7 +132,7 @@ export class ASTProvider { hasContentChanges ? tree : undefined, ); - let changedDeclaration: SyntaxNode | undefined; + let changedDeclaration: Node | undefined; tree ?.getChangedRanges(newTree) diff --git a/src/common/providers/codeAction/addMissingRecordFieldCodeAction.ts b/src/common/providers/codeAction/addMissingRecordFieldCodeAction.ts index 23738330..745f506d 100644 --- a/src/common/providers/codeAction/addMissingRecordFieldCodeAction.ts +++ b/src/common/providers/codeAction/addMissingRecordFieldCodeAction.ts @@ -1,5 +1,5 @@ import { Range, TextEdit } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { CodeActionProvider, ICodeAction } from ".."; import { ISourceFile } from "../../../compiler/forest"; import { getSpaces } from "../../util/refactorEditUtils"; @@ -97,7 +97,7 @@ function getEdits( function createFields( fields: [string, Type][], - targetRecord: SyntaxNode, + targetRecord: Node, checker: TypeChecker, sourceFile: ISourceFile, ): { [uri: string]: TextEdit[] } { diff --git a/src/common/providers/codeAction/addNewFunctionParameter.ts b/src/common/providers/codeAction/addNewFunctionParameter.ts index 914d9106..c8b0294a 100644 --- a/src/common/providers/codeAction/addNewFunctionParameter.ts +++ b/src/common/providers/codeAction/addNewFunctionParameter.ts @@ -3,7 +3,7 @@ import { TreeUtils } from "../../util/treeUtils"; import { Diagnostics } from "../../../compiler/diagnostics"; import { CodeActionProvider, ICodeAction } from "../codeActionProvider"; import { ICodeActionParams } from "../paramsExtensions"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; const errorCodes = [Diagnostics.MissingValue.code]; const fixId = "add_new_function_parameter"; @@ -40,8 +40,8 @@ function getActions( } function getActionsForValueDeclaration( - valueDeclaration: SyntaxNode, - nodeAtPosition: SyntaxNode, + valueDeclaration: Node, + nodeAtPosition: Node, params: ICodeActionParams, ): CodeAction | undefined { const lastFunctionParameter = valueDeclaration?.firstChild?.lastChild; @@ -76,8 +76,8 @@ function getActionsForValueDeclaration( function getEditsForSignatureUpdate( params: ICodeActionParams, - nodeAtPosition: SyntaxNode, - valueDeclaration: SyntaxNode, + nodeAtPosition: Node, + valueDeclaration: Node, ): TextEdit[] { const typeAnnotation = TreeUtils.getTypeAnnotation(valueDeclaration); const lastParameterType = diff --git a/src/common/providers/codeAction/extractFunctionCodeAction.ts b/src/common/providers/codeAction/extractFunctionCodeAction.ts index 8dd25dc5..5409d1bb 100644 --- a/src/common/providers/codeAction/extractFunctionCodeAction.ts +++ b/src/common/providers/codeAction/extractFunctionCodeAction.ts @@ -1,5 +1,5 @@ import { CodeActionKind, Position, TextEdit } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { RefactorEditUtils } from "../../util/refactorEditUtils"; import { TreeUtils } from "../../util/treeUtils"; import { TFunction } from "../../../compiler/typeInference"; @@ -87,7 +87,7 @@ CodeActionProvider.registerRefactorAction(refactorName, { line: rootNode.endPosition.row, character: 0, }; - let targetScope: SyntaxNode; + let targetScope: Node; let addTypeAnnotation = true; switch (actionName) { @@ -128,7 +128,7 @@ CodeActionProvider.registerRefactorAction(refactorName, { break; } - const args: SyntaxNode[] = []; + const args: Node[] = []; const nodeParent = node.parent; const imports = checker.getAllImports(params.sourceFile); @@ -152,7 +152,7 @@ CodeActionProvider.registerRefactorAction(refactorName, { } // If we find it in the scope we are extracting, it should not be a arg - let scope: SyntaxNode | null = val; + let scope: Node | null = val; while (scope && scope.id !== nodeParent?.id) { if (params.sourceFile.symbolLinks?.get(scope)?.get(val.text)) { return; diff --git a/src/common/providers/codeAction/extractTypeAliasCodeAction.ts b/src/common/providers/codeAction/extractTypeAliasCodeAction.ts index e312f68b..1d82c878 100644 --- a/src/common/providers/codeAction/extractTypeAliasCodeAction.ts +++ b/src/common/providers/codeAction/extractTypeAliasCodeAction.ts @@ -1,5 +1,5 @@ import { CodeActionKind, Position, TextEdit } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { RefactorEditUtils } from "../../util/refactorEditUtils"; import { TreeUtils } from "../../util/treeUtils"; import { @@ -118,7 +118,7 @@ CodeActionProvider.registerRefactorAction(refactorName, { ): IRefactorEdit => { const edits: TextEdit[] = []; - const nodes: SyntaxNode[] = []; + const nodes: Node[] = []; if (action === "extract_type_alias_partial_type_expr") { const startNode = TreeUtils.getNamedDescendantForPosition( params.sourceFile.tree.rootNode, diff --git a/src/common/providers/codeAction/importCodeAction.ts b/src/common/providers/codeAction/importCodeAction.ts index cad88093..26435749 100644 --- a/src/common/providers/codeAction/importCodeAction.ts +++ b/src/common/providers/codeAction/importCodeAction.ts @@ -1,6 +1,6 @@ import { CodeAction, TextEdit } from "vscode-languageserver"; import { Range } from "vscode-languageserver-textdocument"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { ISourceFile } from "../../../compiler/forest"; import { ImportUtils, IPossibleImport } from "../../util/importUtils"; import { RefactorEditUtils } from "../../util/refactorEditUtils"; @@ -149,7 +149,7 @@ function getEditFromPossibleImport( } function getValueToImport( - valueNode: SyntaxNode, + valueNode: Node, possibleImport: IPossibleImport, ): string | undefined { return valueNode.type !== "upper_case_qid" && valueNode.type !== "value_qid" @@ -157,7 +157,7 @@ function getValueToImport( : undefined; } -function getTargetModule(valueNode: SyntaxNode): string { +function getTargetModule(valueNode: Node): string { return valueNode.namedChildren .slice(0, valueNode.namedChildren.length - 2) // Dots are also namedNodes .map((a) => a.text) diff --git a/src/common/providers/codeLensProvider.ts b/src/common/providers/codeLensProvider.ts index 08f2c7b5..3a2aed4c 100644 --- a/src/common/providers/codeLensProvider.ts +++ b/src/common/providers/codeLensProvider.ts @@ -9,7 +9,7 @@ import { Range, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { IProgram } from "../../compiler/program"; import { ISourceFile } from "../../compiler/forest"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; @@ -174,8 +174,8 @@ export class CodeLensProvider { }; private createExposingCodeLens( - node: SyntaxNode, - nameNode: SyntaxNode, + node: Node, + nameNode: Node, uri: string, isFunctionOrPort: boolean, ): ICodeLens { @@ -193,10 +193,7 @@ export class CodeLensProvider { }; } - private createReferenceCodeLens( - placementNode: SyntaxNode, - uri: string, - ): ICodeLens { + private createReferenceCodeLens(placementNode: Node, uri: string): ICodeLens { return { range: Range.create( Position.create( diff --git a/src/common/providers/completionProvider.ts b/src/common/providers/completionProvider.ts index fedef668..c6bf94ec 100644 --- a/src/common/providers/completionProvider.ts +++ b/src/common/providers/completionProvider.ts @@ -12,7 +12,7 @@ import { TextEdit, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { IProgram } from "../../compiler/program"; import { ISourceFile } from "../../compiler/forest"; import { comparePosition, PositionUtil } from "../positionUtil"; @@ -473,7 +473,7 @@ export class CompletionProvider { private getExposedFromModule( program: IProgram, sourceFile: ISourceFile, - exposingListNode: SyntaxNode, + exposingListNode: Node, range: Range, ): CompletionItem[] | undefined { // Skip as clause to always get Module Name @@ -755,7 +755,7 @@ export class CompletionProvider { } private getRecordCompletions( - node: SyntaxNode, + node: Node, sourceFile: ISourceFile, range: Range, program: IProgram, @@ -847,7 +847,7 @@ export class CompletionProvider { private getRecordCompletionsUsingInference( checker: TypeChecker, - targetNode: SyntaxNode, + targetNode: Node, replaceRange: Range, ): CompletionItem[] { const result: CompletionItem[] = []; @@ -972,7 +972,7 @@ export class CompletionProvider { private findDefinitionsForScope( checker: TypeChecker, - node: SyntaxNode, + node: Node, sourceFile: ISourceFile, range: Range, ): CompletionItem[] { @@ -1190,7 +1190,7 @@ export class CompletionProvider { } private getSubmodulesOrValues( - node: SyntaxNode, + node: Node, sourceFile: ISourceFile, program: IProgram, range: Range, diff --git a/src/common/providers/definitionProvider.ts b/src/common/providers/definitionProvider.ts index 87160e4b..f0243558 100644 --- a/src/common/providers/definitionProvider.ts +++ b/src/common/providers/definitionProvider.ts @@ -8,7 +8,7 @@ import { TextDocumentPositionParams, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { TreeUtils } from "../util/treeUtils"; import { ITextDocumentPositionParams } from "./paramsExtensions"; @@ -59,7 +59,7 @@ export class DefinitionProvider { }; private createLocationFromDefinition( - definitionNode: SyntaxNode | undefined, + definitionNode: Node | undefined, uri: string, ): Location | undefined { if (definitionNode) { diff --git a/src/common/providers/diagnostics/elmLsDiagnostics.ts b/src/common/providers/diagnostics/elmLsDiagnostics.ts index c5999f70..9bdbd9f0 100644 --- a/src/common/providers/diagnostics/elmLsDiagnostics.ts +++ b/src/common/providers/diagnostics/elmLsDiagnostics.ts @@ -13,7 +13,7 @@ import { Parser, Query, QueryResult, - SyntaxNode, + Node, Tree, } from "web-tree-sitter"; import { IProgram } from "../../../compiler/program"; @@ -654,7 +654,7 @@ export class ElmLsDiagnostics { const patternMatches = this.patternsQuery.matches(tree.rootNode); - const scopeCache = new SyntaxNodeMap(); + const scopeCache = new SyntaxNodeMap(); patternMatches .filter(Utils.notUndefined) @@ -1075,7 +1075,7 @@ export class ElmLsDiagnostics { return diagnostics; } - private getNodeRange(node: SyntaxNode): Range { + private getNodeRange(node: Node): Range { const end = PositionUtil.FROM_TS_POSITION(node.endPosition).toVSPosition(); return { start: PositionUtil.FROM_TS_POSITION(node.startPosition).toVSPosition(), diff --git a/src/common/providers/documentSymbolProvider.ts b/src/common/providers/documentSymbolProvider.ts index 96c82801..3e97420f 100644 --- a/src/common/providers/documentSymbolProvider.ts +++ b/src/common/providers/documentSymbolProvider.ts @@ -7,7 +7,7 @@ import { SymbolInformation, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { SymbolInformationTranslator } from "../util/symbolTranslator"; import { ThrottledCancellationToken } from "../cancellation"; @@ -44,7 +44,7 @@ export class DocumentSymbolProvider { ? new ThrottledCancellationToken(token) : undefined; - const traverse: (node: SyntaxNode) => void = (node: SyntaxNode): void => { + const traverse: (node: Node) => void = (node: Node): void => { cancellationToken?.throwIfCancellationRequested(); const symbolInformation = diff --git a/src/common/providers/findTestsProvider.ts b/src/common/providers/findTestsProvider.ts index dc9ee6f3..877d8a93 100644 --- a/src/common/providers/findTestsProvider.ts +++ b/src/common/providers/findTestsProvider.ts @@ -1,6 +1,6 @@ import { container } from "tsyringe"; import { Connection, ResponseError } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { ISourceFile } from "../../compiler/forest"; import { IProgram, Program } from "../../compiler/program"; import { TypeChecker } from "../../compiler/typeChecker"; @@ -106,7 +106,7 @@ function rootSuite( // export for testing export function findTestFunctionCall( - node: SyntaxNode, + node: Node, typeChecker: TypeChecker, ): EFunctionCallExpr | undefined { const letIn = findChildExpr("LetInExpr", node); @@ -214,7 +214,7 @@ const typeByNodeType: Map = new Map([ function findExpr( key: K, - node: SyntaxNode | undefined, + node: Node | undefined, ): ExpressionNodeTypes[K] | undefined { if (!node) { return undefined; @@ -231,7 +231,7 @@ function findExpr( function findChildExpr( key: K, - node: SyntaxNode | undefined, + node: Node | undefined, ): ExpressionNodeTypes[K] | undefined { if (!node) { return undefined; @@ -248,7 +248,7 @@ function findChildExpr( function findAllExprs( key: K, - node: SyntaxNode | undefined, + node: Node | undefined, ): ExpressionNodeTypes[K][] | undefined { if (!node) { return undefined; diff --git a/src/common/providers/foldingProvider.ts b/src/common/providers/foldingProvider.ts index 3e7eb5c3..91469f2c 100644 --- a/src/common/providers/foldingProvider.ts +++ b/src/common/providers/foldingProvider.ts @@ -6,7 +6,7 @@ import { FoldingRangeParams, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { IFoldingRangeParams } from "./paramsExtensions"; @@ -36,9 +36,9 @@ export class FoldingRangeProvider { const folds: FoldingRange[] = []; const tree: Tree = param.sourceFile.tree; - const findLastIdenticalNamedSibling: (node: SyntaxNode) => SyntaxNode = ( - node: SyntaxNode, - ): SyntaxNode => { + const findLastIdenticalNamedSibling: (node: Node) => Node = ( + node: Node, + ): Node => { // eslint-disable-next-line no-constant-condition while (true) { const nextSibling = node.nextNamedSibling; diff --git a/src/common/providers/renameProvider.ts b/src/common/providers/renameProvider.ts index d977bb3b..e7df563a 100644 --- a/src/common/providers/renameProvider.ts +++ b/src/common/providers/renameProvider.ts @@ -12,7 +12,7 @@ import { WorkspaceEdit, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { IProgram } from "../../compiler/program"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { RenameUtils } from "../util/renameUtils"; @@ -126,8 +126,8 @@ export class RenameProvider { public static getRenameEdits( affectedNodes: | { - originalNode: SyntaxNode; - references: { node: SyntaxNode; uri: string }[]; + originalNode: Node; + references: { node: Node; uri: string }[]; } | undefined, newName: string, @@ -189,9 +189,9 @@ export class RenameProvider { private createModuleDeclarationRenameChange( affectedNodes: | { - originalNode: SyntaxNode; + originalNode: Node; references: { - node: SyntaxNode; + node: Node; uri: string; }[]; } @@ -223,8 +223,8 @@ export class RenameProvider { newName: string, affectedNodes: | { - originalNode: SyntaxNode; - references: { node: SyntaxNode; uri: string }[]; + originalNode: Node; + references: { node: Node; uri: string }[]; } | undefined, ): string { diff --git a/src/common/providers/selectionRangeProvider.ts b/src/common/providers/selectionRangeProvider.ts index bcc038cb..6acb7219 100644 --- a/src/common/providers/selectionRangeProvider.ts +++ b/src/common/providers/selectionRangeProvider.ts @@ -7,7 +7,7 @@ import { SelectionRangeParams, } from "vscode-languageserver"; import { URI } from "vscode-uri"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { PositionUtil } from "../positionUtil"; import { ElmWorkspaceMatcher } from "../util/elmWorkspaceMatcher"; import { TreeUtils } from "../util/treeUtils"; @@ -59,7 +59,7 @@ export class SelectionRangeProvider { }; private getParentNode( - node: SyntaxNode, + node: Node, previousRange: Range, ): SelectionRange | undefined { if (node.parent) { diff --git a/src/common/providers/workspaceSymbolProvider.ts b/src/common/providers/workspaceSymbolProvider.ts index 3deac869..b8b7a32f 100644 --- a/src/common/providers/workspaceSymbolProvider.ts +++ b/src/common/providers/workspaceSymbolProvider.ts @@ -4,7 +4,7 @@ import { SymbolInformation, WorkspaceSymbolParams, } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { IProgram } from "../../compiler/program"; import { SymbolInformationTranslator } from "../util/symbolTranslator"; @@ -32,9 +32,7 @@ export class WorkspaceSymbolProvider { if (!sourceFile.writeable) { return; } - const traverse: (node: SyntaxNode) => void = ( - node: SyntaxNode, - ): void => { + const traverse: (node: Node) => void = (node: Node): void => { if (this.isPatternInSymbol(param.query, node.text)) { const symbolInformation = SymbolInformationTranslator.translateNodeToSymbolInformation( diff --git a/src/common/util/hintHelper.ts b/src/common/util/hintHelper.ts index cdfdf40b..69ca2381 100644 --- a/src/common/util/hintHelper.ts +++ b/src/common/util/hintHelper.ts @@ -1,9 +1,9 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { TreeUtils } from "./treeUtils"; export class HintHelper { public static createHint( - node: SyntaxNode | undefined, + node: Node | undefined, typeString?: string, ): string | undefined { if (!node) { @@ -43,7 +43,7 @@ export class HintHelper { } public static createHintFromFunctionParameter( - node: SyntaxNode | undefined, + node: Node | undefined, typeString?: string, ): string { const annotation = TreeUtils.getTypeOrTypeAliasOfFunctionParameter(node); @@ -72,7 +72,7 @@ export class HintHelper { } public static createHintFromDefinitionInLet( - declaration: SyntaxNode | undefined, + declaration: Node | undefined, typeString?: string, ): string | undefined { if (declaration) { @@ -95,7 +95,7 @@ export class HintHelper { } } - public static createHintFromFieldType(node: SyntaxNode): string { + public static createHintFromFieldType(node: Node): string { const typeAlias = TreeUtils.findParentOfType( "type_alias_declaration", node, @@ -127,7 +127,7 @@ export class HintHelper { } private static createHintFromDefinition( - declaration: SyntaxNode | undefined, + declaration: Node | undefined, typeString?: string, ): string | undefined { if (!declaration) { @@ -199,7 +199,7 @@ export class HintHelper { } private static createHintFromModule( - moduleNode: SyntaxNode | undefined, + moduleNode: Node | undefined, ): string | undefined { if (moduleNode) { let comment = ""; diff --git a/src/common/util/importUtils.ts b/src/common/util/importUtils.ts index 7dfc95c9..10139208 100644 --- a/src/common/util/importUtils.ts +++ b/src/common/util/importUtils.ts @@ -1,14 +1,14 @@ import { comparePackageRanking } from "../providers/ranking"; import { ISourceFile } from "../../compiler/forest"; import { NodeType } from "./treeUtils"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { IProgram } from "../../compiler/program"; export interface IPossibleImport { module: string; value: string; type: NodeType; - node: SyntaxNode; + node: Node; valueToImport?: string; package?: string; } diff --git a/src/common/util/refactorEditUtils.ts b/src/common/util/refactorEditUtils.ts index a4fd9f6e..f06f1290 100644 --- a/src/common/util/refactorEditUtils.ts +++ b/src/common/util/refactorEditUtils.ts @@ -1,10 +1,10 @@ import { Position, Range, TextEdit } from "vscode-languageserver"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { TreeUtils } from "./treeUtils"; export class RefactorEditUtils { public static findLineNumberAfterCurrentFunction( - nodeAtPosition: SyntaxNode, + nodeAtPosition: Node, ): number | undefined { if (!nodeAtPosition.parent) { return undefined; @@ -18,7 +18,7 @@ export class RefactorEditUtils { } public static findLineNumberBeforeCurrentFunction( - nodeAtPosition: SyntaxNode, + nodeAtPosition: Node, ): number | undefined { if (!nodeAtPosition.parent) { return undefined; @@ -259,7 +259,7 @@ export class RefactorEditUtils { } public static changeQualifiedReferenceModule( - node: SyntaxNode, + node: Node, newModuleName: string, ): TextEdit | undefined { if (node.parent && node.parent.type === "value_qid") { @@ -286,9 +286,7 @@ export class RefactorEditUtils { } } - public static removeQualifiedReference( - node: SyntaxNode, - ): TextEdit | undefined { + public static removeQualifiedReference(node: Node): TextEdit | undefined { if (node.parent && node.parent.type === "value_qid") { const moduleNode = TreeUtils.findFirstNamedChildOfType( "upper_case_identifier", @@ -380,7 +378,7 @@ export class RefactorEditUtils { } } - public static removeRecordPatternValue(pattern: SyntaxNode): TextEdit { + public static removeRecordPatternValue(pattern: Node): TextEdit { let startPosition = pattern.startPosition; let endPosition = pattern.endPosition; @@ -404,9 +402,7 @@ export class RefactorEditUtils { ); } - public static removeFunction( - nodeAtPosition: SyntaxNode, - ): TextEdit | undefined { + public static removeFunction(nodeAtPosition: Node): TextEdit | undefined { const valueDeclaration = TreeUtils.findParentOfType( "value_declaration", nodeAtPosition, @@ -439,7 +435,7 @@ export class RefactorEditUtils { } } - public static removeTypeAlias(node: SyntaxNode | null): TextEdit | undefined { + public static removeTypeAlias(node: Node | null): TextEdit | undefined { if (!node) { return undefined; } @@ -464,9 +460,7 @@ export class RefactorEditUtils { ); } - public static removeTypeValue( - nodeAtPosition: SyntaxNode, - ): TextEdit | undefined { + public static removeTypeValue(nodeAtPosition: Node): TextEdit | undefined { const unionVariants = TreeUtils.findParentOfType( "type_declaration", nodeAtPosition, @@ -506,7 +500,7 @@ export class RefactorEditUtils { ); } - public static removeType(node: SyntaxNode | null): TextEdit | undefined { + public static removeType(node: Node | null): TextEdit | undefined { if (!node) { return undefined; } @@ -532,7 +526,7 @@ export class RefactorEditUtils { } public static addUnionVariant( - typeDeclaration: SyntaxNode, + typeDeclaration: Node, name: string, params: string[], ): TextEdit | undefined { @@ -557,7 +551,7 @@ export class RefactorEditUtils { } private static removeValueFromExposingList( - exposedNodes: SyntaxNode[], + exposedNodes: Node[], valueName: string, forceRemoveLastComma = false, ): TextEdit | undefined { diff --git a/src/common/util/referenceNode.ts b/src/common/util/referenceNode.ts index 78252353..6b6ffe96 100644 --- a/src/common/util/referenceNode.ts +++ b/src/common/util/referenceNode.ts @@ -1,8 +1,8 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { NodeType } from "./treeUtils"; export interface IReferenceNode { - node: SyntaxNode; + node: Node; nodeType: NodeType; uri: string; } diff --git a/src/common/util/renameUtils.ts b/src/common/util/renameUtils.ts index b4875401..f407335a 100644 --- a/src/common/util/renameUtils.ts +++ b/src/common/util/renameUtils.ts @@ -1,6 +1,6 @@ import { IProgram } from "../../compiler/program"; import { Position, ResponseError } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { References } from "../../compiler/references"; import { TreeUtils } from "./treeUtils"; @@ -11,9 +11,9 @@ export class RenameUtils { position: Position, ): | { - originalNode: SyntaxNode; + originalNode: Node; references: { - node: SyntaxNode; + node: Node; uri: string; }[]; } diff --git a/src/common/util/symbolTranslator.ts b/src/common/util/symbolTranslator.ts index f8b85869..4acf9f73 100644 --- a/src/common/util/symbolTranslator.ts +++ b/src/common/util/symbolTranslator.ts @@ -4,12 +4,12 @@ import { SymbolInformation, SymbolKind, } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; export class SymbolInformationTranslator { public static translateNodeToSymbolInformation( uri: string, - node: SyntaxNode, + node: Node, ): SymbolInformation | undefined { switch (node.type) { case "value_declaration": @@ -78,7 +78,7 @@ export class SymbolInformationTranslator { private static createSymbolInformation( name: string, - node: SyntaxNode, + node: Node, symbolKind: SymbolKind, uri: string, ): SymbolInformation { diff --git a/src/common/util/treeUtils.ts b/src/common/util/treeUtils.ts index a94ff60b..e81cb69a 100644 --- a/src/common/util/treeUtils.ts +++ b/src/common/util/treeUtils.ts @@ -1,5 +1,5 @@ import { Position } from "vscode-languageserver"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { ISourceFile } from "../../compiler/forest"; import { comparePosition, positionEquals } from "../positionUtil"; import { TRecord, Type } from "../../compiler/typeInference"; @@ -29,21 +29,21 @@ export type NodeType = const functionNameRegex = new RegExp("[a-zA-Z0-9_]+"); export class TreeUtils { - public static getModuleNameNode(tree: Tree): SyntaxNode | undefined { - const moduleDeclaration: SyntaxNode | undefined = + public static getModuleNameNode(tree: Tree): Node | undefined { + const moduleDeclaration: Node | undefined = this.findModuleDeclaration(tree); return moduleDeclaration?.childForFieldName("name") ?? undefined; } - public static getModuleNameCommentNode(tree: Tree): SyntaxNode | undefined { - const moduleDeclaration: SyntaxNode | undefined = + public static getModuleNameCommentNode(tree: Tree): Node | undefined { + const moduleDeclaration: Node | undefined = this.findModuleDeclaration(tree); return moduleDeclaration?.nextNamedSibling?.type === "block_comment" ? moduleDeclaration.nextNamedSibling : undefined; } - public static getModuleExposingListNodes(tree: Tree): SyntaxNode[] { + public static getModuleExposingListNodes(tree: Tree): Node[] { const moduleNode = TreeUtils.findModuleDeclaration(tree); if (moduleNode) { @@ -57,15 +57,15 @@ export class TreeUtils { public static findFirstNamedChildOfType( type: string, - node: SyntaxNode, - ): SyntaxNode | undefined { + node: Node, + ): Node | undefined { return node.children.find((child) => child.type === type); } public static findAllNamedChildrenOfType( type: string | string[], - node: SyntaxNode, - ): SyntaxNode[] | undefined { + node: Node, + ): Node[] | undefined { const result = Array.isArray(type) ? node.children.filter((child) => type.includes(child.type)) : node.children.filter((child) => child.type === type); @@ -74,9 +74,9 @@ export class TreeUtils { } public static findExposedFunctionNode( - node: SyntaxNode, + node: Node, functionName: string, - ): SyntaxNode | undefined { + ): Node | undefined { if (node) { const exposingList = this.findFirstNamedChildOfType( "exposing_list", @@ -119,9 +119,9 @@ export class TreeUtils { } public static findExposedTypeOrTypeAliasNode( - node: SyntaxNode, + node: Node, typeName: string, - ): SyntaxNode | undefined { + ): Node | undefined { if (node) { const exposingList = this.findFirstNamedChildOfType( "exposing_list", @@ -180,7 +180,7 @@ export class TreeUtils { tree: Tree, unionConstructorName: string, moduleNamePrefix?: string, - ): SyntaxNode[] | undefined { + ): Node[] | undefined { const upperCaseQid = TreeUtils.descendantsOfType( tree.rootNode, "upper_case_qid", @@ -202,7 +202,7 @@ export class TreeUtils { public static findOperator( sourceFile: ISourceFile, operatorName: string, - ): SyntaxNode | undefined { + ): Node | undefined { const rootSymbols = sourceFile.symbolLinks?.get(sourceFile.tree.rootNode); const operatorNode = rootSymbols?.get(operatorName)?.node; @@ -224,7 +224,7 @@ export class TreeUtils { public static findTypeDeclaration( tree: Tree, typeName: string, - ): SyntaxNode | undefined { + ): Node | undefined { const types = this.findAllTypeDeclarations(tree); if (types) { return types.find( @@ -236,13 +236,13 @@ export class TreeUtils { } } - public static findModuleDeclaration(tree: Tree): SyntaxNode | undefined { + public static findModuleDeclaration(tree: Tree): Node | undefined { return tree.rootNode.childForFieldName("moduleDeclaration") ?? undefined; } public static findAllTopLevelFunctionDeclarations( tree: Tree, - ): SyntaxNode[] | undefined { + ): Node[] | undefined { const result = tree.rootNode.children.filter( (a) => a.type === "value_declaration", ); @@ -250,8 +250,8 @@ export class TreeUtils { } public static getFunctionNameNodeFromDefinition( - node: SyntaxNode, - ): SyntaxNode | undefined { + node: Node, + ): Node | undefined { if (node.type === "lower_case_identifier") { return node; } @@ -265,19 +265,19 @@ export class TreeUtils { } public static getTypeOrTypeAliasOrPortNameNodeFromDefinition( - node: SyntaxNode, - ): SyntaxNode | undefined { + node: Node, + ): Node | undefined { return node.childForFieldName("name") ?? undefined; } - public static isTypeUsage(upperCaseQid: SyntaxNode): boolean { + public static isTypeUsage(upperCaseQid: Node): boolean { return ( !!TreeUtils.findParentOfType("type_ref", upperCaseQid) || upperCaseQid.parent?.type === "exposed_type" ); } - public static isConstructorUsage(upperCaseQid: SyntaxNode): boolean { + public static isConstructorUsage(upperCaseQid: Node): boolean { return upperCaseQid.parent?.type === "value_expr"; } @@ -285,7 +285,7 @@ export class TreeUtils { tree: Tree, typeOrTypeAliasName: string, nodeType: NodeType, - ): SyntaxNode[] { + ): Node[] { const upperCaseQids = TreeUtils.descendantsOfType( tree.rootNode, "upper_case_qid", @@ -303,7 +303,7 @@ export class TreeUtils { }); } - public static findAllTypeDeclarations(tree: Tree): SyntaxNode[] | undefined { + public static findAllTypeDeclarations(tree: Tree): Node[] | undefined { return this.findAllNamedChildrenOfType("type_declaration", tree.rootNode); } @@ -313,7 +313,7 @@ export class TreeUtils { public static findImportClauseByName( tree: Tree, moduleName: string, - ): SyntaxNode | undefined { + ): Node | undefined { const allImports = this.findAllImportClauseNodes(tree); if (allImports) { return allImports.find( @@ -326,8 +326,8 @@ export class TreeUtils { } public static getTypeOrTypeAliasOfFunctionParameter( - node: SyntaxNode | undefined, - ): SyntaxNode | undefined { + node: Node | undefined, + ): Node | undefined { if ( node && node.parent && @@ -359,8 +359,8 @@ export class TreeUtils { } public static getReturnTypeOrTypeAliasOfFunctionDefinition( - node: SyntaxNode | undefined, - ): SyntaxNode | undefined { + node: Node | undefined, + ): Node | undefined { if (node && node.previousNamedSibling?.type === "type_annotation") { const typeAnnotationNodes = TreeUtils.descendantsOfType( node.previousNamedSibling, @@ -374,7 +374,7 @@ export class TreeUtils { } public static getRecordTypeOfFunctionRecordParameter( - node: SyntaxNode | undefined, + node: Node | undefined, program: IProgram, ): TRecord | undefined { const checker = program.getTypeChecker(); @@ -403,10 +403,10 @@ export class TreeUtils { } public static getTypeAliasOfRecordField( - node: SyntaxNode | undefined, + node: Node | undefined, sourceFile: ISourceFile, program: IProgram, - ): SyntaxNode | undefined { + ): Node | undefined { const fieldName = node?.parent?.firstNamedChild?.text; let recordType = TreeUtils.getTypeAliasOfRecord(node, sourceFile, program); @@ -460,12 +460,12 @@ export class TreeUtils { } public static getTypeAliasOfRecord( - node: SyntaxNode | undefined, + node: Node | undefined, sourceFile: ISourceFile, program: IProgram, - ): SyntaxNode | undefined { + ): Node | undefined { if (node?.parent?.parent) { - let type: SyntaxNode | undefined | null = + let type: Node | undefined | null = TreeUtils.findFirstNamedChildOfType( "record_base_identifier", node.parent.parent, @@ -543,7 +543,7 @@ export class TreeUtils { } public static getAllFieldsFromTypeAlias( - node: SyntaxNode | undefined, + node: Node | undefined, ): { field: string; type: string }[] | undefined { const result: { field: string; type: string }[] = []; if (node) { @@ -567,17 +567,14 @@ export class TreeUtils { return result.length === 0 ? undefined : result; } - public static descendantsOfType( - node: SyntaxNode, - type: string, - ): SyntaxNode[] { + public static descendantsOfType(node: Node, type: string): Node[] { return node.descendantsOfType(type); } public static getNamedDescendantForPosition( - node: SyntaxNode, + node: Node, position: Position, - ): SyntaxNode { + ): Node { const previousCharColumn = position.character === 0 ? 0 : position.character - 1; const charBeforeCursor = node.text @@ -603,10 +600,7 @@ export class TreeUtils { } } - public static getDescendantForPosition( - node: SyntaxNode, - position: Position, - ): SyntaxNode { + public static getDescendantForPosition(node: Node, position: Position): Node { const previousCharColumn = position.character === 0 ? 0 : position.character - 1; const charBeforeCursor = node.text @@ -635,7 +629,7 @@ export class TreeUtils { public static getNamedDescendantForRange( sourceFile: ISourceFile, range: Range, - ): SyntaxNode { + ): Node { if (positionEquals(range.start, range.end)) { return this.getNamedDescendantForPosition(sourceFile.tree.rootNode, { character: range.start.character, @@ -658,7 +652,7 @@ export class TreeUtils { public static getDescendantForRange( sourceFile: ISourceFile, range: Range, - ): SyntaxNode { + ): Node { if (positionEquals(range.start, range.end)) { return this.getDescendantForPosition(sourceFile.tree.rootNode, { character: range.start.character, @@ -679,17 +673,17 @@ export class TreeUtils { } public static findPreviousNode( - node: SyntaxNode, + node: Node, position: Position, - ): SyntaxNode | undefined { - function nodeHasTokens(n: SyntaxNode): boolean { + ): Node | undefined { + function nodeHasTokens(n: Node): boolean { return n.endIndex - n.startIndex !== 0; } function findRightmostChildWithTokens( - childrenList: SyntaxNode[], + childrenList: Node[], startIndex: number, - ): SyntaxNode | undefined { + ): Node | undefined { for (let i = startIndex - 1; i >= 0; i--) { if (nodeHasTokens(childrenList[i])) { return childrenList[i]; @@ -697,7 +691,7 @@ export class TreeUtils { } } - function findRightmostNode(n: SyntaxNode): SyntaxNode | undefined { + function findRightmostNode(n: Node): Node | undefined { if (n.children.length === 0) { return n; } @@ -743,9 +737,9 @@ export class TreeUtils { } public static getNamedDescendantForLineBeforePosition( - node: SyntaxNode, + node: Node, position: Position, - ): SyntaxNode { + ): Node { const previousLine = position.line === 0 ? 0 : position.line - 1; return node.namedDescendantForPosition({ @@ -755,9 +749,9 @@ export class TreeUtils { } public static getNamedDescendantForLineAfterPosition( - node: SyntaxNode, + node: Node, position: Position, - ): SyntaxNode { + ): Node { const followingLine = position.line + 1; return node.namedDescendantForPosition({ @@ -768,9 +762,9 @@ export class TreeUtils { public static findParentOfType( typeToLookFor: string, - node: SyntaxNode, + node: Node, topLevel = false, - ): SyntaxNode | undefined { + ): Node | undefined { if ( node.type === typeToLookFor && (!topLevel || node.parent?.type === "file") @@ -782,14 +776,14 @@ export class TreeUtils { } } - public static getLastImportNode(tree: Tree): SyntaxNode | undefined { + public static getLastImportNode(tree: Tree): Node | undefined { const allImportNodes = this.findAllImportClauseNodes(tree); if (allImportNodes?.length) { return allImportNodes[allImportNodes.length - 1]; } } - public static isReferenceFullyQualified(node: SyntaxNode): boolean { + public static isReferenceFullyQualified(node: Node): boolean { return ( node.previousNamedSibling?.type === "dot" && node.previousNamedSibling?.previousNamedSibling?.type === @@ -797,9 +791,7 @@ export class TreeUtils { ); } - public static getTypeAnnotation( - valueDeclaration?: SyntaxNode, - ): SyntaxNode | undefined { + public static getTypeAnnotation(valueDeclaration?: Node): Node | undefined { if (valueDeclaration?.type !== "value_declaration") { return; } @@ -819,9 +811,7 @@ export class TreeUtils { } } - public static getValueDeclaration( - typeAnnotation?: SyntaxNode, - ): SyntaxNode | undefined { + public static getValueDeclaration(typeAnnotation?: Node): Node | undefined { if (typeAnnotation?.type !== "type_annotation") { return; } @@ -845,10 +835,7 @@ export class TreeUtils { * This gets a list of all ancestors of a type * in order from the closest declaration up to the top level declaration */ - public static getAllAncestorsOfType( - type: string, - node: SyntaxNode, - ): SyntaxNode[] { + public static getAllAncestorsOfType(type: string, node: Node): Node[] { const declarations = []; while (node.type !== "file") { @@ -869,7 +856,7 @@ export class TreeUtils { /** * @deprecated Should not be used due to performance. Use bindings instead */ - public static findAllImportClauseNodes(tree: Tree): SyntaxNode[] | undefined { + public static findAllImportClauseNodes(tree: Tree): Node[] | undefined { const result = tree.rootNode.children.filter( (a) => a.type === "import_clause", ); @@ -877,21 +864,21 @@ export class TreeUtils { return result.length === 0 ? undefined : result; } - public static isIdentifier(node: SyntaxNode): boolean { + public static isIdentifier(node: Node): boolean { return ( node.type === "lower_case_identifier" || node.type === "upper_case_identifier" ); } - public static isImport(node: SyntaxNode): boolean { + public static isImport(node: Node): boolean { return ( node.parent?.firstNamedChild?.type === "import" || node.parent?.parent?.firstNamedChild?.type === "import" ); } - public static nextNode(node: SyntaxNode): SyntaxNode | undefined { + public static nextNode(node: Node): Node | undefined { // Move up until we have a sibling while (!node.nextNamedSibling && node.parent) { node = node.parent; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 61b01713..878c3391 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1,5 +1,5 @@ import { ISourceFile } from "./forest"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { MultiMap } from "../common/util/multiMap"; import { NodeType, TreeUtils } from "../common/util/treeUtils"; import { Utils } from "../common/util/utils"; @@ -16,11 +16,11 @@ export type IExposing = Map; export interface ISymbol { name: string; - node: SyntaxNode; + node: Node; type: NodeType; constructors?: { name: string; - node: SyntaxNode; + node: Node; type: "UnionConstructor" | "TypeAlias"; }[]; } @@ -30,10 +30,10 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { return; } - const symbolLinks = new SyntaxNodeMap(); + const symbolLinks = new SyntaxNodeMap(); const nonShadowableNames = new Set(); let container: SymbolMap; - let parent: SyntaxNode; + let parent: Node; const treeCursor = sourceFile.tree.walk(); bind(); @@ -99,7 +99,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { } } - function bindContainer(node: SyntaxNode): void { + function bindContainer(node: Node): void { const savedContainer = container; const savedParent = parent; @@ -118,7 +118,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { parent = savedParent; } - function bindValueDeclaration(node: SyntaxNode): void { + function bindValueDeclaration(node: Node): void { // Bind the function name const functionDeclarationLeft = node.childForFieldName( "functionDeclarationLeft", @@ -155,7 +155,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { bindContainer(node); } - function bindFunctionDeclarationLeft(node: SyntaxNode): void { + function bindFunctionDeclarationLeft(node: Node): void { node.descendantsOfType("lower_pattern").forEach((lowerPattern) => { container.set(lowerPattern.text, { name: lowerPattern.text, @@ -165,7 +165,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { }); } - function bindTypeDeclaration(node: SyntaxNode): void { + function bindTypeDeclaration(node: Node): void { const unionVariants = TreeUtils.findAllNamedChildrenOfType("union_variant", node) ?.map((unionVariant) => { @@ -204,7 +204,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { bindContainer(node); } - function bindTypeAliasDeclaration(node: SyntaxNode): void { + function bindTypeAliasDeclaration(node: Node): void { const name = node.childForFieldName("name"); if (name) { @@ -226,11 +226,11 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { bindContainer(node); } - function bindLowerTypeName(node: SyntaxNode): void { + function bindLowerTypeName(node: Node): void { container.set(node.text, { name: node.text, node, type: "TypeVariable" }); } - function bindPortAnnotation(node: SyntaxNode): void { + function bindPortAnnotation(node: Node): void { // TODO: Use field const name = TreeUtils.findFirstNamedChildOfType( "lower_case_identifier", @@ -242,7 +242,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { } } - function bindInfixDeclaration(node: SyntaxNode): void { + function bindInfixDeclaration(node: Node): void { const operator = node.childForFieldName("operator"); const name = node.lastNamedChild; if (operator && name) { @@ -255,7 +255,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { } } - function bindPattern(node: SyntaxNode): void { + function bindPattern(node: Node): void { node.descendantsOfType("lower_pattern").forEach((lowerPattern) => { switch (parent.type) { case "anonymous_function_expr": @@ -280,7 +280,7 @@ export function bindTreeContainer(sourceFile: ISourceFile): void { Imports.getVirtualImports().forEach(bindImportClause); } - function bindImportClause(node: SyntaxNode): void { + function bindImportClause(node: Node): void { const asClause = node.childForFieldName("asClause"); let name; diff --git a/src/compiler/diagnostics.ts b/src/compiler/diagnostics.ts index 9b05e129..80f9e97b 100644 --- a/src/compiler/diagnostics.ts +++ b/src/compiler/diagnostics.ts @@ -4,7 +4,7 @@ import { DiagnosticTag, Range, } from "vscode-languageserver"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { PositionUtil } from "../common/positionUtil"; import { DiagnosticSource } from "../common/providers/diagnostics/diagnosticSource"; import { getSpaces } from "../common/util/refactorEditUtils"; @@ -24,9 +24,9 @@ function format(text: string, ...args: (string | number)[]): string { } export function errorWithEndNode( - node: SyntaxNode, + node: Node, diagnostic: IDiagnosticMessage, - endNode?: SyntaxNode, + endNode?: Node, ...args: (string | number)[] ): Diagnostic { return { @@ -45,7 +45,7 @@ export function errorWithEndNode( } export function error( - node: SyntaxNode, + node: Node, diagnostic: IDiagnosticMessage, ...args: (string | number)[] ): Diagnostic { diff --git a/src/compiler/forest.ts b/src/compiler/forest.ts index f24608db..54831e3c 100644 --- a/src/compiler/forest.ts +++ b/src/compiler/forest.ts @@ -1,4 +1,4 @@ -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { Imports } from "./imports"; import { TreeUtils } from "../common/util/treeUtils"; import { SyntaxNodeMap } from "./utils/syntaxNodeMap"; @@ -24,7 +24,7 @@ export interface ISourceFile { // Resolved during binding exposing?: IExposing; - symbolLinks?: SyntaxNodeMap; + symbolLinks?: SyntaxNodeMap; nonShadowableNames?: Set; // Top level function names // This is resolved while getting semantic diagnostics and defines whether we have loaded all import files diff --git a/src/compiler/imports.ts b/src/compiler/imports.ts index 904f0da5..7ffe5d1f 100644 --- a/src/compiler/imports.ts +++ b/src/compiler/imports.ts @@ -1,4 +1,4 @@ -import Parser, { SyntaxNode } from "web-tree-sitter"; +import Parser, { Node } from "web-tree-sitter"; import { ISourceFile } from "./forest"; import { TreeUtils } from "../common/util/treeUtils"; import { container } from "tsyringe"; @@ -22,7 +22,7 @@ type FromModule = { export interface IImport extends ISymbol { fromModule: FromModule; - importNode?: SyntaxNode; + importNode?: Node; } function importModuleEqual(a: IImport, b: IImport): boolean { @@ -87,7 +87,7 @@ export class Imports { return this.diagnostics; } - private static cachedVirtualImports: SyntaxNode[]; + private static cachedVirtualImports: Node[]; public static getImports( sourceFile: ISourceFile, @@ -389,7 +389,7 @@ export class Imports { return result; } - public static getVirtualImports(): SyntaxNode[] { + public static getVirtualImports(): Node[] { if (this.cachedVirtualImports) { return this.cachedVirtualImports; } @@ -416,9 +416,7 @@ export class Imports { return (this.cachedVirtualImports = importTree.rootNode.children); } - private static findImportAsClause( - importNode: SyntaxNode, - ): string | undefined { + private static findImportAsClause(importNode: Node): string | undefined { const asClause = TreeUtils.findFirstNamedChildOfType( "as_clause", importNode, diff --git a/src/compiler/patternMatches.ts b/src/compiler/patternMatches.ts index 5c8bda6c..97d5d609 100644 --- a/src/compiler/patternMatches.ts +++ b/src/compiler/patternMatches.ts @@ -1,4 +1,4 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { TreeUtils } from "../common/util/treeUtils"; import { Utils } from "../common/util/utils"; import { Diagnostic, Diagnostics, error } from "./diagnostics"; @@ -49,7 +49,7 @@ type CanCtor = { arity: number; }; -function nodeToCanCtor(node: SyntaxNode): CanCtor { +function nodeToCanCtor(node: Node): CanCtor { return { name: node.firstNamedChild!.text, arity: node.namedChildren @@ -84,8 +84,8 @@ export class PatternMatches { ) {} public static check( - region: SyntaxNode, - patterns: SyntaxNode[], + region: Node, + patterns: Node[], program: IProgram, ): Diagnostic[] { return new PatternMatches( @@ -94,14 +94,14 @@ export class PatternMatches { ).checkPatterns(region, patterns); } - public static missing(patterns: SyntaxNode[], program: IProgram): string[] { + public static missing(patterns: Node[], program: IProgram): string[] { return new PatternMatches( program, program.getSourceFile(patterns[0].tree.uri)!, ).getMissing(patterns); } - private getMissing(patterns: SyntaxNode[]): string[] { + private getMissing(patterns: Node[]): string[] { const result = this.toNonRedundantRows(patterns[0], patterns); if (!Array.isArray(result)) { @@ -113,10 +113,7 @@ export class PatternMatches { } } - private checkPatterns( - region: SyntaxNode, - patterns: SyntaxNode[], - ): Diagnostic[] { + private checkPatterns(region: Node, patterns: Node[]): Diagnostic[] { const result = this.toNonRedundantRows(region, patterns); if (!Array.isArray(result)) { @@ -193,16 +190,16 @@ export class PatternMatches { } private toNonRedundantRows( - region: SyntaxNode, - patterns: SyntaxNode[], + region: Node, + patterns: Node[], ): Pattern[][] | Diagnostic { return this.toSimplifiedUsefulRows(region, [], patterns); } private toSimplifiedUsefulRows( - overalRegion: SyntaxNode, + overalRegion: Node, checkedRows: Pattern[][], - uncheckedPatterns: SyntaxNode[], + uncheckedPatterns: Node[], ): Pattern[][] | Diagnostic { if (uncheckedPatterns.length === 0) { return checkedRows; @@ -370,11 +367,11 @@ export class PatternMatches { return ctors; } - private cons(head: SyntaxNode, tail: Pattern): Pattern { + private cons(head: Node, tail: Pattern): Pattern { return Ctor(list, consName, [this.simplify(head), tail]); } - private simplify(pattern: SyntaxNode): Pattern { + private simplify(pattern: Node): Pattern { const patternAs = pattern.childForFieldName("patternAs"); if (patternAs) { return this.simplify(pattern.childForFieldName("child") ?? patternAs); diff --git a/src/compiler/references.ts b/src/compiler/references.ts index 882aa9e4..80fbf67b 100644 --- a/src/compiler/references.ts +++ b/src/compiler/references.ts @@ -1,6 +1,6 @@ import { IProgram } from "./program"; import { ISourceFile } from "./forest"; -import { SyntaxNode, Tree } from "web-tree-sitter"; +import { Node, Tree } from "web-tree-sitter"; import { TreeUtils } from "../common/util/treeUtils"; import { Utils } from "../common/util/utils"; import { Imports } from "./imports"; @@ -10,8 +10,8 @@ export class References { public static find( definitionNode: ISymbol | undefined, program: IProgram, - ): { node: SyntaxNode; uri: string }[] { - const references: { node: SyntaxNode; uri: string }[] = []; + ): { node: Node; uri: string }[] { + const references: { node: Node; uri: string }[] = []; const checker = program.getTypeChecker(); @@ -684,7 +684,7 @@ export class References { true, ); - const typeVariableNodes: SyntaxNode[] = []; + const typeVariableNodes: Node[] = []; if (topLevelAnnotation) { const topLevelValueDeclaration = @@ -747,10 +747,7 @@ export class References { return references; } - public static findOperator( - node: SyntaxNode, - program: IProgram, - ): SyntaxNode | undefined { + public static findOperator(node: Node, program: IProgram): Node | undefined { const functionNameNode = TreeUtils.getFunctionNameNodeFromDefinition(node); if (functionNameNode) { @@ -767,9 +764,9 @@ export class References { } private static findFunctionCalls( - node: SyntaxNode, + node: Node, functionName: string, - ): SyntaxNode[] | undefined { + ): Node[] | undefined { const functions = [ ...this.findAllFunctionCallsAndParameters(node).concat(), ...node.descendantsOfType("record_base_identifier"), @@ -780,9 +777,7 @@ export class References { return result.length === 0 ? undefined : result; } - private static findAllFunctionCallsAndParameters( - node: SyntaxNode, - ): SyntaxNode[] { + private static findAllFunctionCallsAndParameters(node: Node): Node[] { let functions = TreeUtils.descendantsOfType(node, "value_expr"); if (functions.length > 0) { functions = functions @@ -794,10 +789,10 @@ export class References { } private static findParameterUsage( - node: SyntaxNode, + node: Node, functionName: string, - ): SyntaxNode[] | undefined { - const parameters: SyntaxNode[] = [ + ): Node[] | undefined { + const parameters: Node[] = [ ...this.findAllFunctionCallsAndParameters(node), ...this.findAllRecordBaseIdentifiers(node), ]; @@ -805,11 +800,11 @@ export class References { return result.length === 0 ? undefined : result; } - private static findAllRecordBaseIdentifiers(node: SyntaxNode): SyntaxNode[] { + private static findAllRecordBaseIdentifiers(node: Node): Node[] { return TreeUtils.descendantsOfType(node, "record_base_identifier"); } - private static findFieldUsages(tree: Tree, fieldName: string): SyntaxNode[] { + private static findFieldUsages(tree: Tree, fieldName: string): Node[] { return tree.rootNode .descendantsOfType([ "field", @@ -853,8 +848,8 @@ export class References { definition: ISymbol, sourceFile: ISourceFile, program: IProgram, - ): { node: SyntaxNode; uri: string }[] { - const references: { node: SyntaxNode; uri: string }[] = []; + ): { node: Node; uri: string }[] { + const references: { node: Node; uri: string }[] = []; const fieldUsages = References.findFieldUsages(sourceFile.tree, fieldName); diff --git a/src/compiler/typeCache.ts b/src/compiler/typeCache.ts index 76d1902f..89e9dbb9 100644 --- a/src/compiler/typeCache.ts +++ b/src/compiler/typeCache.ts @@ -1,4 +1,4 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { MultiMap } from "../common/util/multiMap"; import { TreeUtils } from "../common/util/treeUtils"; import { SyntaxNodeMap } from "./utils/syntaxNodeMap"; @@ -15,44 +15,26 @@ type CacheKey = | "PROJECT_UNION_VARIANT"; export class TypeCache { - private packageTypeAnnotation: SyntaxNodeMap; - private packageTypeAndTypeAlias: SyntaxNodeMap; - private packageValueDeclaration: SyntaxNodeMap; - private packageUnionVariant: SyntaxNodeMap; - private projectTypeAnnotation: SyntaxNodeMap; - private projectTypeAndTypeAlias: SyntaxNodeMap; - private projectValueDeclaration: SyntaxNodeMap; - private projectUnionVariant: SyntaxNodeMap; - private declarationAnnotations: MultiMap; - private typeUnionVariants: MultiMap; + private packageTypeAnnotation: SyntaxNodeMap; + private packageTypeAndTypeAlias: SyntaxNodeMap; + private packageValueDeclaration: SyntaxNodeMap; + private packageUnionVariant: SyntaxNodeMap; + private projectTypeAnnotation: SyntaxNodeMap; + private projectTypeAndTypeAlias: SyntaxNodeMap; + private projectValueDeclaration: SyntaxNodeMap; + private projectUnionVariant: SyntaxNodeMap; + private declarationAnnotations: MultiMap; + private typeUnionVariants: MultiMap; constructor() { - this.packageTypeAnnotation = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.packageTypeAndTypeAlias = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.packageValueDeclaration = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.packageUnionVariant = new SyntaxNodeMap(); - this.projectTypeAnnotation = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.projectTypeAndTypeAlias = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.projectValueDeclaration = new SyntaxNodeMap< - SyntaxNode, - InferenceResult - >(); - this.projectUnionVariant = new SyntaxNodeMap(); + this.packageTypeAnnotation = new SyntaxNodeMap(); + this.packageTypeAndTypeAlias = new SyntaxNodeMap(); + this.packageValueDeclaration = new SyntaxNodeMap(); + this.packageUnionVariant = new SyntaxNodeMap(); + this.projectTypeAnnotation = new SyntaxNodeMap(); + this.projectTypeAndTypeAlias = new SyntaxNodeMap(); + this.projectValueDeclaration = new SyntaxNodeMap(); + this.projectUnionVariant = new SyntaxNodeMap(); this.declarationAnnotations = new MultiMap(); this.typeUnionVariants = new MultiMap(); @@ -60,7 +42,7 @@ export class TypeCache { public getOrSet( key: CacheKey, - node: SyntaxNode, + node: Node, setter: () => InferenceResult, ): InferenceResult { switch (key) { @@ -90,18 +72,18 @@ export class TypeCache { this.projectUnionVariant.clear(); } - public invalidateValueDeclaration(node: SyntaxNode): void { + public invalidateValueDeclaration(node: Node): void { this.projectValueDeclaration.delete(node); this.declarationAnnotations .getAll(node.id) ?.forEach((annotation) => this.projectTypeAnnotation.delete(annotation)); } - public invalidateTypeAnnotation(node: SyntaxNode): void { + public invalidateTypeAnnotation(node: Node): void { this.projectTypeAnnotation.delete(node); } - public invalidateTypeOrTypeAlias(node: SyntaxNode): void { + public invalidateTypeOrTypeAlias(node: Node): void { this.projectTypeAndTypeAlias.delete(node); this.typeUnionVariants .getAll(node.id) @@ -114,7 +96,7 @@ export class TypeCache { * We associate type annotations with its top level declaration * so we can clear its cache when we invalidate that declaration */ - public trackTypeAnnotation(annotation: SyntaxNode): void { + public trackTypeAnnotation(annotation: Node): void { const declaration = annotation.parent?.type === "file" ? TreeUtils.getValueDeclaration(annotation) @@ -129,7 +111,7 @@ export class TypeCache { } } - public trackUnionVariant(unionVariant: SyntaxNode): void { + public trackUnionVariant(unionVariant: Node): void { const typeDeclaration = TreeUtils.findParentOfType( "type_declaration", unionVariant, diff --git a/src/compiler/typeChecker.ts b/src/compiler/typeChecker.ts index fdfbfa9d..f50a0576 100644 --- a/src/compiler/typeChecker.ts +++ b/src/compiler/typeChecker.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { TreeUtils } from "../common/util/treeUtils"; import { Expression, @@ -58,13 +58,10 @@ class DiagnosticsCollection extends Map { } export interface TypeChecker { - findType: (node: SyntaxNode) => Type; - findDefinition: ( - node: SyntaxNode, - sourceFile: ISourceFile, - ) => DefinitionResult; + findType: (node: Node) => Type; + findDefinition: (node: Node, sourceFile: ISourceFile) => DefinitionResult; findDefinitionShallow: ( - node: SyntaxNode, + node: Node, sourceFile: ISourceFile, ) => DefinitionResult; getAllImports: (sourceFile: ISourceFile) => Imports; @@ -94,8 +91,8 @@ export interface TypeChecker { findImportModuleNameNodes: ( moduleNameOrAlias: string, sourceFile: ISourceFile, - ) => SyntaxNode[]; - getSymbolsInScope(node: SyntaxNode, sourceFile: ISourceFile): ISymbol[]; + ) => Node[]; + getSymbolsInScope(node: Node, sourceFile: ISourceFile): ISymbol[]; } export function createTypeChecker(program: IProgram): TypeChecker { @@ -131,7 +128,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { return typeChecker; - function findType(node: SyntaxNode): Type { + function findType(node: Node): Type { try { const declaration = mapSyntaxNodeToExpression( TreeUtils.findParentOfType("value_declaration", node, true), @@ -140,7 +137,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { const uri = node.tree.uri; const findTypeOrParentType = ( - expr: SyntaxNode | undefined, + expr: Node | undefined, inferenceResult: InferenceResult, ): Type | undefined => { const found = expr @@ -419,7 +416,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { } function findDefinition( - nodeAtPosition: SyntaxNode, + nodeAtPosition: Node, sourceFile: ISourceFile, ): DefinitionResult { const definition = findDefinitionShallow(nodeAtPosition, sourceFile); @@ -442,7 +439,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { } function findDefinitionShallow( - nodeAtPosition: SyntaxNode, + nodeAtPosition: Node, sourceFile: ISourceFile, ): DefinitionResult { const nodeText = nodeAtPosition.text; @@ -848,12 +845,12 @@ export function createTypeChecker(program: IProgram): TypeChecker { parentType, ]; - const callback = (annotation: SyntaxNode | undefined): SyntaxNode[] => + const callback = (annotation: Node | undefined): Node[] => annotation ? TreeUtils.descendantsOfType(annotation, "type_variable") : []; - const allTypeVariables: SyntaxNode[] = allAnnotations.flatMap(callback); + const allTypeVariables: Node[] = allAnnotations.flatMap(callback); const firstMatching = allTypeVariables.find((t) => t.text === nodeText); @@ -932,7 +929,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { function findImportModuleNameNodes( moduleNameOrAlias: string, sourceFile: ISourceFile, - ): SyntaxNode[] { + ): Node[] { // This will find an import based on module name only, not alias const moduleImport = getAllImports(sourceFile) .getModule(moduleNameOrAlias) @@ -957,13 +954,10 @@ export function createTypeChecker(program: IProgram): TypeChecker { return moduleOrAliasImports; } - function getSymbolsInScope( - node: SyntaxNode, - sourceFile: ISourceFile, - ): ISymbol[] { + function getSymbolsInScope(node: Node, sourceFile: ISourceFile): ISymbol[] { const symbols: ISymbol[] = []; - let targetScope: SyntaxNode | null = node; + let targetScope: Node | null = node; while (targetScope != null) { sourceFile.symbolLinks ?.get(targetScope) @@ -974,7 +968,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { return symbols; } - function checkNode(node: SyntaxNode): void { + function checkNode(node: Node): void { if (checkedNodes.has(node.id)) { return; } @@ -1008,7 +1002,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { checkedNodes.add(node.id); } - function checkValueDeclaration(valueDeclaration: SyntaxNode): void { + function checkValueDeclaration(valueDeclaration: Node): void { const declaration = mapSyntaxNodeToExpression( valueDeclaration, ) as EValueDeclaration; @@ -1045,7 +1039,7 @@ export function createTypeChecker(program: IProgram): TypeChecker { } } - function checkImportClause(importClause: SyntaxNode): void { + function checkImportClause(importClause: Node): void { const moduleNameNode = importClause.childForFieldName("moduleName"); if (moduleNameNode) { @@ -1062,14 +1056,14 @@ export function createTypeChecker(program: IProgram): TypeChecker { } } - function checkTypeAliasDeclaration(typeAliasDeclaration: SyntaxNode): void { + function checkTypeAliasDeclaration(typeAliasDeclaration: Node): void { TypeExpression.typeAliasDeclarationInference( mapSyntaxNodeToExpression(typeAliasDeclaration) as ETypeAliasDeclaration, program, ).diagnostics.forEach((diagnostic) => diagnostics.add(diagnostic)); } - function checkTypeDeclaration(typeDeclaration: SyntaxNode): void { + function checkTypeDeclaration(typeDeclaration: Node): void { TypeExpression.typeDeclarationInference( mapSyntaxNodeToExpression(typeDeclaration) as ETypeDeclaration, program, @@ -1079,21 +1073,21 @@ export function createTypeChecker(program: IProgram): TypeChecker { typeDeclaration.children.forEach(checkNode); } - function checkUnionVariant(unionVariant: SyntaxNode): void { + function checkUnionVariant(unionVariant: Node): void { TypeExpression.unionVariantInference( mapSyntaxNodeToExpression(unionVariant) as EUnionVariant, program, ).diagnostics.forEach((diagnostic) => diagnostics.add(diagnostic)); } - function checkPortAnnotation(portAnnotation: SyntaxNode): void { + function checkPortAnnotation(portAnnotation: Node): void { TypeExpression.portAnnotationInference( mapSyntaxNodeToExpression(portAnnotation) as EPortAnnotation, program, ).diagnostics.forEach((diagnostic) => diagnostics.add(diagnostic)); } - function getSourceFileOfNode(node: SyntaxNode): ISourceFile { + function getSourceFileOfNode(node: Node): ISourceFile { const sourceFile = program.getSourceFile(node.tree.uri); if (!sourceFile) { diff --git a/src/compiler/typeInference.ts b/src/compiler/typeInference.ts index e8d2cdbc..528b413c 100644 --- a/src/compiler/typeInference.ts +++ b/src/compiler/typeInference.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { TreeUtils } from "../common/util/treeUtils"; import { References } from "./references"; import { @@ -377,10 +377,10 @@ export function nthVarName(n: number): string { function typeMismatchError( checker: TypeChecker, - node: SyntaxNode, + node: Node, found: Type, expected: Type, - endNode?: SyntaxNode, + endNode?: Node, patternBinding = false, recordDiff?: RecordDiff, ): Diagnostic { @@ -424,8 +424,8 @@ function typeMismatchError( } function parameterCountError( - node: SyntaxNode, - endNode: SyntaxNode, + node: Node, + endNode: Node, actual: number, expected: number, isType = false, @@ -443,8 +443,8 @@ function parameterCountError( } function argumentCountError( - node: SyntaxNode, - endNode: SyntaxNode, + node: Node, + endNode: Node, actual: number, expected: number, isType = false, @@ -495,10 +495,7 @@ export class InferenceScope { new SyntaxNodeMap(); private diagnostics: Diagnostic[] = []; - private bindings: SyntaxNodeMap = new SyntaxNodeMap< - SyntaxNode, - Type - >(); + private bindings: SyntaxNodeMap = new SyntaxNodeMap(); private replacements: DisjointSet; private annotationVars: TVar[] = []; diff --git a/src/compiler/utils/expressionTree.ts b/src/compiler/utils/expressionTree.ts index 881ca160..b9c7595e 100644 --- a/src/compiler/utils/expressionTree.ts +++ b/src/compiler/utils/expressionTree.ts @@ -1,4 +1,4 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { OperatorAssociativity } from "../operatorPrecedence"; import { TreeUtils } from "../../common/util/treeUtils"; import { Utils } from "../../common/util/utils"; @@ -63,205 +63,205 @@ export type Expression = | EValueDeclaration | EValueExpr; -export interface EValueDeclaration extends SyntaxNode { +export interface EValueDeclaration extends Node { nodeType: "ValueDeclaration"; params: string[]; - body?: SyntaxNode; - typeAnnotation?: SyntaxNode; - pattern?: SyntaxNode; + body?: Node; + typeAnnotation?: Node; + pattern?: Node; } -export interface EFunctionCallExpr extends SyntaxNode { +export interface EFunctionCallExpr extends Node { nodeType: "FunctionCallExpr"; target: Expression; args: Expression[]; } -export interface EIfElseExpr extends SyntaxNode { +export interface EIfElseExpr extends Node { nodeType: "IfElseExpr"; exprList: Expression[]; } -export interface ELetInExpr extends SyntaxNode { +export interface ELetInExpr extends Node { nodeType: "LetInExpr"; valueDeclarations: EValueDeclaration[]; body: Expression; } -export interface ECaseOfExpr extends SyntaxNode { +export interface ECaseOfExpr extends Node { nodeType: "CaseOfExpr"; expr: Expression; branches: ECaseOfBranch[]; } -export interface ECaseOfBranch extends SyntaxNode { +export interface ECaseOfBranch extends Node { nodeType: "CaseOfBranch"; pattern: EPattern; expr: Expression; } -export interface EAnonymousFunctionExpr extends SyntaxNode { +export interface EAnonymousFunctionExpr extends Node { nodeType: "AnonymousFunctionExpr"; params: EPattern[]; expr: Expression; } -export interface EUnionVariant extends SyntaxNode { +export interface EUnionVariant extends Node { nodeType: "UnionVariant"; name: string; params: Expression[]; } -export interface EUnionPattern extends SyntaxNode { +export interface EUnionPattern extends Node { nodeType: "UnionPattern"; - constructor: SyntaxNode; + constructor: Node; namedParams: Expression[]; argPatterns: Expression[]; } -export interface EValueExpr extends SyntaxNode { +export interface EValueExpr extends Node { nodeType: "ValueExpr"; name: string; } -export interface EBinOpExpr extends SyntaxNode { +export interface EBinOpExpr extends Node { nodeType: "BinOpExpr"; parts: Expression[]; } -export interface EOperator extends SyntaxNode { +export interface EOperator extends Node { nodeType: "Operator"; } -export interface EOperatorAsFunctionExpr extends SyntaxNode { +export interface EOperatorAsFunctionExpr extends Node { nodeType: "OperatorAsFunctionExpr"; operator: EOperator; } -export interface ENumberConstant extends SyntaxNode { +export interface ENumberConstant extends Node { nodeType: "NumberConstant"; isFloat: boolean; } -export interface EStringConstant extends SyntaxNode { +export interface EStringConstant extends Node { nodeType: "StringConstant"; } -export interface ETypeExpression extends SyntaxNode { +export interface ETypeExpression extends Node { nodeType: "TypeExpression"; segments: Expression[]; } -export interface ETypeRef extends SyntaxNode { +export interface ETypeRef extends Node { nodeType: "TypeRef"; } -export interface ETypeDeclaration extends SyntaxNode { +export interface ETypeDeclaration extends Node { nodeType: "TypeDeclaration"; name: string; typeNames: Expression[]; } -export interface ETypeVariable extends SyntaxNode { +export interface ETypeVariable extends Node { nodeType: "TypeVariable"; } -export interface ETypeAnnotation extends SyntaxNode { +export interface ETypeAnnotation extends Node { nodeType: "TypeAnnotation"; name: string; typeExpression?: ETypeExpression; } -export interface EInfixDeclaration extends SyntaxNode { +export interface EInfixDeclaration extends Node { nodeType: "InfixDeclaration"; precedence: number; associativity: OperatorAssociativity; } -export interface EFunctionDeclarationLeft extends SyntaxNode { +export interface EFunctionDeclarationLeft extends Node { nodeType: "FunctionDeclarationLeft"; params: Pattern[]; } type Pattern = EPattern | ELowerPattern; -export interface EPattern extends SyntaxNode { +export interface EPattern extends Node { nodeType: "Pattern"; patternAs?: ELowerPattern; } -export interface ELowerPattern extends SyntaxNode { +export interface ELowerPattern extends Node { nodeType: "LowerPattern"; } -export interface ELowerTypeName extends SyntaxNode { +export interface ELowerTypeName extends Node { nodeType: "LowerTypeName"; } -export interface EUnitExpr extends SyntaxNode { +export interface EUnitExpr extends Node { nodeType: "UnitExpr"; } -export interface ETupleExpr extends SyntaxNode { +export interface ETupleExpr extends Node { nodeType: "TupleExpr"; exprList: Expression[]; } -export interface EAnythingPattern extends SyntaxNode { +export interface EAnythingPattern extends Node { nodeType: "AnythingPattern"; } -export interface ETuplePattern extends SyntaxNode { +export interface ETuplePattern extends Node { nodeType: "TuplePattern"; patterns: EPattern[]; } -export interface ETupleType extends SyntaxNode { +export interface ETupleType extends Node { nodeType: "TupleType"; typeExpressions: ETypeExpression[]; unitExpr?: EUnitExpr; } -export interface EListExpr extends SyntaxNode { +export interface EListExpr extends Node { nodeType: "ListExpr"; exprList: Expression[]; } -export interface EListPattern extends SyntaxNode { +export interface EListPattern extends Node { nodeType: "ListPattern"; parts: Expression[]; } -export interface EConsPattern extends SyntaxNode { +export interface EConsPattern extends Node { nodeType: "ConsPattern"; parts: Expression[]; } -export interface EFieldType extends SyntaxNode { +export interface EFieldType extends Node { nodeType: "FieldType"; name: string; typeExpression: ETypeExpression; } -export interface ERecordType extends SyntaxNode { +export interface ERecordType extends Node { nodeType: "RecordType"; baseType: Expression; fieldTypes: EFieldType[]; } -export interface ETypeAliasDeclaration extends SyntaxNode { +export interface ETypeAliasDeclaration extends Node { nodeType: "TypeAliasDeclaration"; - name: SyntaxNode; + name: Node; typeVariables: Expression[]; typeExpression: ETypeExpression; } -export interface EField extends SyntaxNode { +export interface EField extends Node { nodeType: "Field"; name: Expression; expression: Expression; } -export interface EFieldAccessExpr extends SyntaxNode { +export interface EFieldAccessExpr extends Node { nodeType: "FieldAccessExpr"; target: Expression; } -export interface EFieldAccessorFunctionExpr extends SyntaxNode { +export interface EFieldAccessorFunctionExpr extends Node { nodeType: "FieldAccessorFunctionExpr"; } -export interface ERecordPattern extends SyntaxNode { +export interface ERecordPattern extends Node { nodeType: "RecordPattern"; patternList: ELowerPattern[]; } -export interface ERecordExpr extends SyntaxNode { +export interface ERecordExpr extends Node { nodeType: "RecordExpr"; - baseRecord: SyntaxNode; + baseRecord: Node; fields: EField[]; } -export interface EPortAnnotation extends SyntaxNode { +export interface EPortAnnotation extends Node { nodeType: "PortAnnotation"; name: string; typeExpression: ETypeExpression; } -export interface ECharConstantExpr extends SyntaxNode { +export interface ECharConstantExpr extends Node { nodeType: "CharConstantExpr"; } -export interface EGlslCodeExpr extends SyntaxNode { +export interface EGlslCodeExpr extends Node { nodeType: "GlslCodeExpr"; - content: SyntaxNode; + content: Node; } -export interface ENegateExpr extends SyntaxNode { +export interface ENegateExpr extends Node { nodeType: "NegateExpr"; expression: Expression; } -export interface ENullaryConstructorArgumentPattern extends SyntaxNode { +export interface ENullaryConstructorArgumentPattern extends Node { nodeType: "NullaryConstructorArgumentPattern"; } export function mapSyntaxNodeToExpression( - node: SyntaxNode | null | undefined, + node: Node | null | undefined, ): Expression | undefined { if (!node) return; @@ -571,7 +571,7 @@ export function mapSyntaxNodeToExpression( case "union_pattern": { const unionPattern = node as EUnionPattern; unionPattern.nodeType = "UnionPattern"; - unionPattern.constructor = node.firstNamedChild as SyntaxNode; + unionPattern.constructor = node.firstNamedChild as Node; unionPattern.namedParams = node .descendantsOfType("lower_pattern") .map(mapSyntaxNodeToExpression) @@ -673,9 +673,7 @@ export function mapSyntaxNodeToExpression( case "record_expr": { const recordExpr = node as ERecordExpr; recordExpr.nodeType = "RecordExpr"; - recordExpr.baseRecord = node.childForFieldName( - "baseRecord", - ) as SyntaxNode; + recordExpr.baseRecord = node.childForFieldName("baseRecord") as Node; recordExpr.fields = (TreeUtils.findAllNamedChildrenOfType("field", node) ?.map(mapSyntaxNodeToExpression) @@ -739,7 +737,7 @@ export function mapTypeAliasDeclaration( ): void { typeAliasDeclaration.name = typeAliasDeclaration.childForFieldName( "name", - ) as SyntaxNode; + ) as Node; typeAliasDeclaration.typeVariables = TreeUtils.findAllNamedChildrenOfType( "lower_type_name", @@ -769,7 +767,7 @@ export function mapTypeAnnotation(typeAnnotation: ETypeAnnotation): void { } export function findDefinition( - e: SyntaxNode | undefined | null, + e: Node | undefined | null, program: IProgram, ): { expr?: Expression; diagnostics: Diagnostic[] } { if (!e) { diff --git a/src/compiler/utils/recordFieldReferenceTable.ts b/src/compiler/utils/recordFieldReferenceTable.ts index e5637b44..9f637362 100644 --- a/src/compiler/utils/recordFieldReferenceTable.ts +++ b/src/compiler/utils/recordFieldReferenceTable.ts @@ -1,4 +1,4 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { EFieldType } from "./expressionTree"; import { SyntaxNodeSet } from "./syntaxNodeSet"; @@ -29,7 +29,7 @@ export class RecordFieldReferenceTable { return new RecordFieldReferenceTable(fieldRefs); } - public get(field: string): SyntaxNode[] { + public get(field: string): Node[] { return this.refsByField.get(field)?.toArray() ?? []; } diff --git a/src/compiler/utils/syntaxNodeMap.ts b/src/compiler/utils/syntaxNodeMap.ts index 1a2cfdce..15c47a2f 100644 --- a/src/compiler/utils/syntaxNodeMap.ts +++ b/src/compiler/utils/syntaxNodeMap.ts @@ -1,6 +1,6 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; -export class SyntaxNodeMap { +export class SyntaxNodeMap { private map: Map = new Map(); public set(key: K, value: V): void { diff --git a/src/compiler/utils/syntaxNodeSet.ts b/src/compiler/utils/syntaxNodeSet.ts index e83f65c9..3fd746d2 100644 --- a/src/compiler/utils/syntaxNodeSet.ts +++ b/src/compiler/utils/syntaxNodeSet.ts @@ -1,6 +1,6 @@ -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; -export class SyntaxNodeSet { +export class SyntaxNodeSet { private map = new Map(); constructor(...items: K[]) { diff --git a/src/typings/web-tree-sitter/index.d.ts b/src/typings/web-tree-sitter/index.d.ts deleted file mode 100644 index 2c808c38..00000000 --- a/src/typings/web-tree-sitter/index.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import "web-tree-sitter"; - -declare module "web-tree-sitter" { - export interface SyntaxNode { - id: number; - } - - export interface Tree { - uri: string; - } - - interface QueryResult { - pattern: number; - captures: { name: string; node: SyntaxNode }[]; - } - - interface PredicateResult { - operator: string; - operands: { name: string; type: string }[]; - } - - interface Query { - captureNames: string[]; - - delete(): void; - matches( - node: SyntaxNode, - startPosition?: Point, - endPosition?: Point, - ): QueryResult[]; - captures( - node: SyntaxNode, - startPosition?: Point, - endPosition?: Point, - ): QueryResult[]; - - predicatesForPattern(patternIndex: number): PredicateResult[]; - } - - interface Language { - query(source: string): Query; - } - - class Parser { - static init(): Promise; - delete(): void; - parse(input: string | Input, previousTree?: Tree, options?: Options): Tree; - getLanguage(): Language; - setLanguage(language: Language): void; - getLogger(): Logger; - setLogger(logFunc: Logger): void; - } -} diff --git a/test/diagnosticTests/elmDiagnostics.test.ts b/test/diagnosticTests/elmDiagnostics.test.ts index f162be34..6ae6aa8f 100644 --- a/test/diagnosticTests/elmDiagnostics.test.ts +++ b/test/diagnosticTests/elmDiagnostics.test.ts @@ -1,5 +1,5 @@ import { Utils as UriUtils } from "vscode-uri"; -import { SyntaxNode } from "web-tree-sitter"; +import { Node } from "web-tree-sitter"; import { convertFromCompilerDiagnostic } from "../../src/common/providers"; import { diagnosticsEquals } from "../../src/common/providers/diagnostics/fileDiagnostics"; import { TreeUtils } from "../../src/common/util/treeUtils"; @@ -78,7 +78,7 @@ describe("test elm diagnostics", () => { } }); - let nodeAtPosition: SyntaxNode = undefined!; + let nodeAtPosition: Node = undefined!; if ("range" in result) { const rootNode = program.getSourceFile(testUri)!.tree.rootNode; @@ -1545,11 +1545,11 @@ a = --@ Test.elm module Test exposing (..) -type alias A appendable = +type alias A appendable = { a : appendable } a : A Int -a = +a = { a = 0 } `; await testTypeInference(basicsSources + source3, []); @@ -1560,10 +1560,10 @@ a = --@ Test.elm module Test exposing (..) -type alias A appendable = +type alias A appendable = { a : appendable } -a = +a = A 0 --^ `; @@ -1575,7 +1575,7 @@ a = --@ Test.elm module Test exposing (..) -type B appendable = +type B appendable = With appendable | Without b : B Int @@ -1590,7 +1590,7 @@ b = With 0 --@ Test.elm module Test exposing (..) -type B appendable = +type B appendable = With appendable | Without b : B Int @@ -1718,7 +1718,7 @@ oneOrMore parser = ) parser - + --@ Test.elm module Test exposing (..) @@ -1727,7 +1727,7 @@ import Parser.Advanced as Parser exposing ((|.), (|=)) test : Parser.Parser Never () () test = Parser.succeed (\\_ -> ()) - |= Parser.getOffset + |= Parser.getOffset `; await testTypeInference( From 2acce94701cd4460372873a9903ab2244930e1cf Mon Sep 17 00:00:00 2001 From: Razze Date: Sun, 30 Mar 2025 20:17:47 +0200 Subject: [PATCH 4/4] WIP --- src/common/index.ts | 4 ++-- .../codeAction/extractFunctionCodeAction.ts | 1 + src/compiler/patternMatches.ts | 22 ++++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/common/index.ts b/src/common/index.ts index d1a64780..3168ebcf 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -7,7 +7,7 @@ import { InitializeResult, } from "vscode-languageserver"; -import Parser from "web-tree-sitter"; +import { Parser, Language } from "web-tree-sitter"; import { CapabilityCalculator } from "./capabilityCalculator"; import { ASTProvider } from "./providers"; import { @@ -64,7 +64,7 @@ export function startCommonServer( connection.console.info( `Loading Elm tree-sitter syntax from ${pathToWasm}`, ); - const language = await Parser.Language.load(pathToWasm); + const language = await Language.load(pathToWasm); const parser = container.resolve("Parser"); parser.setLanguage(language); diff --git a/src/common/providers/codeAction/extractFunctionCodeAction.ts b/src/common/providers/codeAction/extractFunctionCodeAction.ts index 5409d1bb..928b34f3 100644 --- a/src/common/providers/codeAction/extractFunctionCodeAction.ts +++ b/src/common/providers/codeAction/extractFunctionCodeAction.ts @@ -136,6 +136,7 @@ CodeActionProvider.registerRefactorAction(refactorName, { // Get the list of references that won't be visible node .descendantsOfType(["value_expr", "record_base_identifier"]) + .filter((val) => val !== null) .forEach((val) => { if (args.find((arg) => arg.text === val.text)) { return; diff --git a/src/compiler/patternMatches.ts b/src/compiler/patternMatches.ts index 97d5d609..8ef5cda9 100644 --- a/src/compiler/patternMatches.ts +++ b/src/compiler/patternMatches.ts @@ -388,6 +388,7 @@ export class PatternMatches { case "tuple_pattern": { const patterns = pattern.children + .filter((val) => val !== null) .filter((n) => n.type === "pattern") .map((n) => n.childForFieldName("child")!); @@ -417,7 +418,8 @@ export class PatternMatches { "type_declaration", definition.symbol.node, ) - ?.namedChildren.filter((n) => n.type === "union_variant") + ?.namedChildren.filter((val) => val !== null) + .filter((n) => n.type === "union_variant") .map(nodeToCanCtor) ?? [] : []; @@ -434,16 +436,20 @@ export class PatternMatches { return foldr( this.cons.bind(this), nil, - pattern.namedChildren.filter((n) => n.type === "pattern"), + pattern.namedChildren + .filter((val) => val !== null) + .filter((n) => n.type === "pattern"), ); case "cons_pattern": { - const patterns = pattern.namedChildren.filter( - (n) => - n.type.includes("pattern") || - n.type.includes("constant") || - n.type === "unit_expr", - ); + const patterns = pattern.namedChildren + .filter((val) => val !== null) + .filter( + (n) => + n.type.includes("pattern") || + n.type.includes("constant") || + n.type === "unit_expr", + ); return this.cons(patterns[0], this.simplify(patterns[1])); }