From dedcc51cccf7aac0b33cafdbe3ebe875bdc9f11d Mon Sep 17 00:00:00 2001 From: Ricardo Costa Date: Wed, 5 Aug 2026 17:10:33 +0100 Subject: [PATCH] Restore Baseline --- client/.vscodeignore | 3 + client/media/java-icon-white.svg | 44 - client/media/java-icon.svg | 62 - client/package-lock.json | 2545 ++++++++--------- client/package.json | 139 +- client/src/extension.ts | 112 +- client/src/lsp/client.ts | 96 +- client/src/lsp/server.ts | 55 +- client/src/services/autocomplete.ts | 252 -- client/src/services/codelens.ts | 44 - client/src/services/commands.ts | 54 - client/src/services/context.ts | 154 - client/src/services/decorators.ts | 37 - client/src/services/definition.ts | 26 - client/src/services/diagnostics.ts | 57 - client/src/services/editor.ts | 31 - client/src/services/events.ts | 73 - client/src/services/hover.ts | 124 - client/src/services/logger.ts | 81 - client/src/services/state-machine.ts | 16 - client/src/services/status-bar.ts | 47 - client/src/services/webview.ts | 48 - client/src/state.ts | 31 +- client/src/types/context.ts | 62 - client/src/types/diagnostics.ts | 125 - client/src/types/fsm.ts | 8 - client/src/types/vc-implications.ts | 12 - client/src/utils/constants.ts | 27 - client/src/utils/utils.ts | 25 +- client/src/webview/clipboard.ts | 22 - client/src/webview/diagnostic-reveal.ts | 31 - client/src/webview/diagram.ts | 243 -- client/src/webview/highlighting.ts | 103 - client/src/webview/html.ts | 49 - client/src/webview/icons.ts | 23 - client/src/webview/main.ts | 10 - client/src/webview/provider.ts | 68 - client/src/webview/script.ts | 400 --- client/src/webview/styles.ts | 886 ------ client/src/webview/utils.ts | 18 - client/src/webview/views/context/aliases.ts | 38 - client/src/webview/views/context/context.ts | 30 - client/src/webview/views/context/ghosts.ts | 30 - client/src/webview/views/context/variables.ts | 51 - .../views/diagnostics/counterexample.ts | 25 - .../webview/views/diagnostics/diagnostics.ts | 144 - .../src/webview/views/diagnostics/errors.ts | 76 - .../webview/views/diagnostics/vc-changes.ts | 215 -- .../views/diagnostics/vc-implications.ts | 111 - .../src/webview/views/diagnostics/warnings.ts | 39 - client/src/webview/views/fsm/fsm.ts | 53 - client/src/webview/views/loading.ts | 11 - client/src/webview/views/sections.ts | 111 - client/src/webview/views/stopped.ts | 23 - client/syntaxes/liquidjava.json | 131 - client/webpack.config.js | 122 +- server/pom.xml | 51 +- server/src/main/java/LJDiagnostics.java | 5 +- .../src/main/java/LJDiagnosticsHandler.java | 88 +- .../src/main/java/LJDiagnosticsService.java | 39 +- server/src/main/java/LJLanguageClient.java | 31 +- server/src/main/java/LJLanguageServer.java | 60 +- .../src/main/java/dtos/context/AliasDTO.java | 25 - .../java/dtos/context/ContextHistoryDTO.java | 26 - .../src/main/java/dtos/context/GhostDTO.java | 37 - .../src/main/java/dtos/context/MethodDTO.java | 46 - .../main/java/dtos/context/VariableDTO.java | 34 - .../dtos/diagnostics/LJDiagnosticDTO.java | 37 - .../dtos/diagnostics/PlacementInCodeDTO.java | 15 - .../java/dtos/diagnostics/RefinementDTO.java | 17 - .../dtos/diagnostics/SourcePositionDTO.java | 32 - .../dtos/diagnostics/TranslationTableDTO.java | 23 - .../java/dtos/diagnostics/VCBinderDTO.java | 20 - .../dtos/diagnostics/VCImplicationDTO.java | 28 - .../VCSimplificationResultDTO.java | 20 - .../dtos/errors/ArgumentMismatchErrorDTO.java | 17 - .../main/java/dtos/errors/CustomErrorDTO.java | 17 - .../IllegalConstructorTransitionErrorDTO.java | 17 - .../errors/InvalidRefinementErrorDTO.java | 20 - .../src/main/java/dtos/errors/LJErrorDTO.java | 34 - .../java/dtos/errors/NotFoundErrorDTO.java | 22 - .../java/dtos/errors/RefinementErrorDTO.java | 28 - .../dtos/errors/StateConflictErrorDTO.java | 20 - .../dtos/errors/StateRefinementErrorDTO.java | 26 - .../main/java/dtos/errors/SyntaxErrorDTO.java | 20 - server/src/main/java/dtos/uri/Uri.java | 3 - .../java/dtos/warnings/CustomWarningDTO.java | 17 - .../ExternalClassNotFoundWarningDTO.java | 20 - .../ExternalMethodNotFoundWarningDTO.java | 24 - .../main/java/dtos/warnings/LJWarningDTO.java | 22 - .../UnsatisfiableRefinementWarningDTO.java | 20 - server/src/main/java/fsm/StateMachine.java | 13 - .../fsm/StateMachineInitialTransition.java | 11 - .../src/main/java/fsm/StateMachineParser.java | 414 --- .../main/java/fsm/StateMachineTransition.java | 11 - .../java/utils/ContextHistoryConverter.java | 46 - .../main/java/utils/DiagnosticConverter.java | 83 - .../java/fsm/StateMachineParserTests.java | 194 -- .../resources/fsm/CombinedPostCondition.java | 14 - .../fsm/ConditionalPostCondition.java | 14 - .../fsm/ConditionalPrecondition.java | 14 - .../resources/fsm/ConditionalTransition.java | 18 - .../fsm/ConjunctionInitialTransition.java | 14 - .../fsm/ConjunctionPrecondition.java | 14 - .../fsm/DisjunctionPostCondition.java | 14 - .../fsm/DisjunctionPrecondition.java | 14 - .../resources/fsm/ExternalRefinements.java | 16 - .../test/resources/fsm/GuardedSelfLoop.java | 14 - .../resources/fsm/MultipleInitialStates.java | 17 - .../resources/fsm/NegationTransition.java | 15 - .../src/test/resources/fsm/OrTransition.java | 15 - .../resources/fsm/PostConditionFiltering.java | 14 - server/src/test/resources/fsm/SelfLoop.java | 23 - server/src/test/resources/fsm/Simple.java | 17 - .../test/resources/fsm/ToOnlyTransition.java | 15 - 115 files changed, 1295 insertions(+), 8153 deletions(-) delete mode 100644 client/media/java-icon-white.svg delete mode 100644 client/media/java-icon.svg delete mode 100644 client/src/services/autocomplete.ts delete mode 100644 client/src/services/codelens.ts delete mode 100644 client/src/services/commands.ts delete mode 100644 client/src/services/context.ts delete mode 100644 client/src/services/decorators.ts delete mode 100644 client/src/services/definition.ts delete mode 100644 client/src/services/diagnostics.ts delete mode 100644 client/src/services/editor.ts delete mode 100644 client/src/services/events.ts delete mode 100644 client/src/services/hover.ts delete mode 100644 client/src/services/logger.ts delete mode 100644 client/src/services/state-machine.ts delete mode 100644 client/src/services/status-bar.ts delete mode 100644 client/src/services/webview.ts delete mode 100644 client/src/types/context.ts delete mode 100644 client/src/types/diagnostics.ts delete mode 100644 client/src/types/fsm.ts delete mode 100644 client/src/types/vc-implications.ts delete mode 100644 client/src/webview/clipboard.ts delete mode 100644 client/src/webview/diagnostic-reveal.ts delete mode 100644 client/src/webview/diagram.ts delete mode 100644 client/src/webview/highlighting.ts delete mode 100644 client/src/webview/html.ts delete mode 100644 client/src/webview/icons.ts delete mode 100644 client/src/webview/main.ts delete mode 100644 client/src/webview/provider.ts delete mode 100644 client/src/webview/script.ts delete mode 100644 client/src/webview/styles.ts delete mode 100644 client/src/webview/utils.ts delete mode 100644 client/src/webview/views/context/aliases.ts delete mode 100644 client/src/webview/views/context/context.ts delete mode 100644 client/src/webview/views/context/ghosts.ts delete mode 100644 client/src/webview/views/context/variables.ts delete mode 100644 client/src/webview/views/diagnostics/counterexample.ts delete mode 100644 client/src/webview/views/diagnostics/diagnostics.ts delete mode 100644 client/src/webview/views/diagnostics/errors.ts delete mode 100644 client/src/webview/views/diagnostics/vc-changes.ts delete mode 100644 client/src/webview/views/diagnostics/vc-implications.ts delete mode 100644 client/src/webview/views/diagnostics/warnings.ts delete mode 100644 client/src/webview/views/fsm/fsm.ts delete mode 100644 client/src/webview/views/loading.ts delete mode 100644 client/src/webview/views/sections.ts delete mode 100644 client/src/webview/views/stopped.ts delete mode 100644 client/syntaxes/liquidjava.json delete mode 100644 server/src/main/java/dtos/context/AliasDTO.java delete mode 100644 server/src/main/java/dtos/context/ContextHistoryDTO.java delete mode 100644 server/src/main/java/dtos/context/GhostDTO.java delete mode 100644 server/src/main/java/dtos/context/MethodDTO.java delete mode 100644 server/src/main/java/dtos/context/VariableDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/LJDiagnosticDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/PlacementInCodeDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/RefinementDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/SourcePositionDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/TranslationTableDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/VCBinderDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/VCImplicationDTO.java delete mode 100644 server/src/main/java/dtos/diagnostics/VCSimplificationResultDTO.java delete mode 100644 server/src/main/java/dtos/errors/ArgumentMismatchErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/CustomErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/IllegalConstructorTransitionErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/InvalidRefinementErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/LJErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/NotFoundErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/RefinementErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/StateConflictErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/StateRefinementErrorDTO.java delete mode 100644 server/src/main/java/dtos/errors/SyntaxErrorDTO.java delete mode 100644 server/src/main/java/dtos/uri/Uri.java delete mode 100644 server/src/main/java/dtos/warnings/CustomWarningDTO.java delete mode 100644 server/src/main/java/dtos/warnings/ExternalClassNotFoundWarningDTO.java delete mode 100644 server/src/main/java/dtos/warnings/ExternalMethodNotFoundWarningDTO.java delete mode 100644 server/src/main/java/dtos/warnings/LJWarningDTO.java delete mode 100644 server/src/main/java/dtos/warnings/UnsatisfiableRefinementWarningDTO.java delete mode 100644 server/src/main/java/fsm/StateMachine.java delete mode 100644 server/src/main/java/fsm/StateMachineInitialTransition.java delete mode 100644 server/src/main/java/fsm/StateMachineParser.java delete mode 100644 server/src/main/java/fsm/StateMachineTransition.java delete mode 100644 server/src/main/java/utils/ContextHistoryConverter.java delete mode 100644 server/src/main/java/utils/DiagnosticConverter.java delete mode 100644 server/src/test/java/fsm/StateMachineParserTests.java delete mode 100644 server/src/test/resources/fsm/CombinedPostCondition.java delete mode 100644 server/src/test/resources/fsm/ConditionalPostCondition.java delete mode 100644 server/src/test/resources/fsm/ConditionalPrecondition.java delete mode 100644 server/src/test/resources/fsm/ConditionalTransition.java delete mode 100644 server/src/test/resources/fsm/ConjunctionInitialTransition.java delete mode 100644 server/src/test/resources/fsm/ConjunctionPrecondition.java delete mode 100644 server/src/test/resources/fsm/DisjunctionPostCondition.java delete mode 100644 server/src/test/resources/fsm/DisjunctionPrecondition.java delete mode 100644 server/src/test/resources/fsm/ExternalRefinements.java delete mode 100644 server/src/test/resources/fsm/GuardedSelfLoop.java delete mode 100644 server/src/test/resources/fsm/MultipleInitialStates.java delete mode 100644 server/src/test/resources/fsm/NegationTransition.java delete mode 100644 server/src/test/resources/fsm/OrTransition.java delete mode 100644 server/src/test/resources/fsm/PostConditionFiltering.java delete mode 100644 server/src/test/resources/fsm/SelfLoop.java delete mode 100644 server/src/test/resources/fsm/Simple.java delete mode 100644 server/src/test/resources/fsm/ToOnlyTransition.java diff --git a/client/.vscodeignore b/client/.vscodeignore index d10a434e..e6b6c1c5 100644 --- a/client/.vscodeignore +++ b/client/.vscodeignore @@ -18,6 +18,9 @@ node_modules/** *.vsix dist/**/*.map media/**/*.map +media/codicons/** +media/lj-logo.png +media/webview.js # Test files test/** diff --git a/client/media/java-icon-white.svg b/client/media/java-icon-white.svg deleted file mode 100644 index 2a022084..00000000 --- a/client/media/java-icon-white.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/client/media/java-icon.svg b/client/media/java-icon.svg deleted file mode 100644 index fceb7c17..00000000 --- a/client/media/java-icon.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 9be232b1..9cbb587f 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,34 +1,25 @@ { - "name": "liquid-java", - "version": "0.0.90", + "name": "liquid-java-baseline", + "version": "0.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "liquid-java", - "version": "0.0.90", + "name": "liquid-java-baseline", + "version": "0.0.1", "license": "MIT", "dependencies": { - "@vscode/codicons": "^0.0.45" + "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@types/mkdirp": "^0.5.2", "@types/node": "^24.7.2", - "@types/rimraf": "^2.0.2", "@types/vscode": "^1.82.0", - "@typescript-eslint/eslint-plugin": "^4.16.0", - "@typescript-eslint/parser": "^4.16.0", - "eslint": "^7.21.0", - "ftp": "^0.3.10", - "get-port": "^5.1.1", - "jsonc-parser": "^0.4.2", - "minimist": "^1.2.7", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.2", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", "ts-loader": "^9.5.4", "typescript": "~5.3.0", "vsce": "^2.15.0", - "vscode-languageclient": "^9.0.1", "webpack": "^5.102.1", "webpack-cli": "^5.1.4" }, @@ -36,76 +27,117 @@ "vscode": "^1.82.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/highlight": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", - "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==", + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "license": "MIT", + "engines": { + "node": ">=10.0.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -157,12 +189,13 @@ } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -170,21 +203,23 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -220,23 +255,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/events": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "dependencies": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -244,21 +262,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "node_modules/@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { "version": "24.10.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", @@ -269,15 +272,12 @@ "undici-types": "~7.16.0" } }, - "node_modules/@types/rimraf": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", - "integrity": "sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ==", + "node_modules/@types/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-1mAINjtQCXXeLkJ9ehXkwOcBpqtLxiVtKhpUf83DdRNdQKV0iXZpaHYqRr7nj+wvxuJzoAmAwXI+sCNMv1CzLQ==", "dev": true, - "dependencies": { - "@types/glob": "*", - "@types/node": "*" - } + "license": "MIT" }, "node_modules/@types/vscode": { "version": "1.105.0", @@ -287,123 +287,236 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.16.1.tgz", - "integrity": "sha512-SK777klBdlkUZpZLC1mPvyOWk9yAFCWmug13eAjVQ4/Q1LATE/NbcQL1xDHkptQkZOLnPmLUA1Y54m8dqYwnoQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/experimental-utils": "4.16.1", - "@typescript-eslint/scope-manager": "4.16.1", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.16.1.tgz", - "integrity": "sha512-0Hm3LSlMYFK17jO4iY3un1Ve9x1zLNn4EM50Lia+0EV99NdbK+cn0er7HC7IvBA23mBg3P+8dUkMXy4leL33UQ==", + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, + "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.16.1", - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/typescript-estree": "4.16.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/parser": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.16.1.tgz", - "integrity": "sha512-/c0LEZcDL5y8RyI1zLcmZMvJrsR6SM1uetskFkoh3dvqDKVXPsXI+wFB/CbVw7WkEyyTKobC1mUNp/5y6gRvXg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "4.16.1", - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/typescript-estree": "4.16.1", - "debug": "^4.1.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.16.1.tgz", - "integrity": "sha512-6IlZv9JaurqV0jkEg923cV49aAn8V6+1H1DRfhRcvZUrptQ+UtSKHb5kwTayzOYTJJ/RsYZdcvhOEKiBLyc0Cw==", + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/visitor-keys": "4.16.1" + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/types": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.16.1.tgz", - "integrity": "sha512-nnKqBwMgRlhzmJQF8tnFDZWfunXmJyuXj55xc8Kbfup4PbkzdoDXZvzN8//EiKR27J6vUSU8j4t37yUuYPiLqA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, + "license": "MIT", "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.16.1.tgz", - "integrity": "sha512-m8I/DKHa8YbeHt31T+UGd/l8Kwr0XCTCZL3H4HMvvLCT7HU9V7yYdinTOv1gf/zfqNeDcCgaFH2BMsS8x6NvJg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/visitor-keys": "4.16.1", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.16.1.tgz", - "integrity": "sha512-s/aIP1XcMkEqCNcPQtl60ogUYjSM8FU2mq1O7y5cFf3Xcob1z1iXWNB6cC43Op+NGRTFgGolri6s8z/efA9i1w==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { - "@typescript-eslint/types": "4.16.1", - "eslint-visitor-keys": "^2.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, "engines": { - "node": ">=10" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vscode/codicons": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.45.tgz", - "integrity": "sha512-1KAZ7XCMagp5Gdrlr4bbbcAqgcIL623iO1wW6rfcSVGAVUQvR0WP7bQx1SbJ11gmV3fdQTSEFIJQ/5C+HuVasw==", - "license": "CC-BY-4.0" + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "dev": true, + "license": "ISC" }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", @@ -628,10 +741,12 @@ "license": "Apache-2.0" }, "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -640,21 +755,30 @@ } }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-formats": { @@ -699,20 +823,12 @@ "dev": true, "license": "MIT" }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -730,28 +846,18 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -770,8 +876,7 @@ "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "node_modules/base64-js": { "version": "1.5.1", @@ -834,12 +939,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -958,6 +1064,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1203,12 +1310,21 @@ } }, "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decompress-response": { @@ -1238,10 +1354,11 @@ } }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" }, "node_modules/detect-libc": { "version": "2.1.2", @@ -1258,6 +1375,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -1358,12 +1476,6 @@ "dev": true, "license": "ISC" }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/encoding-sniffer": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", @@ -1402,18 +1514,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1500,54 +1600,61 @@ } }, "node_modules/eslint": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz", - "integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.20", - "minimatch": "^3.0.4", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-scope": { @@ -1564,98 +1671,148 @@ "node": ">=8.0.0" } }, - "node_modules/eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -1664,10 +1821,11 @@ } }, "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -1740,33 +1898,48 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.8" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", @@ -1796,10 +1969,11 @@ } }, "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -1827,10 +2001,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1906,55 +2081,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "node_modules/ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, - "dependencies": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ftp/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/ftp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/ftp/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ftp/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "node_modules/ftp/node_modules/xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1965,12 +2091,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1996,18 +2116,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-port": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -2047,15 +2155,16 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/glob-to-regexp": { @@ -2066,41 +2175,40 @@ "license": "BSD-2-Clause" }, "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { "node": ">=10" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { @@ -2123,6 +2231,13 @@ "dev": true, "license": "ISC" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2239,25 +2354,30 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local": { @@ -2342,26 +2462,19 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -2374,10 +2487,21 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -2448,20 +2572,24 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -2478,7 +2606,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -2486,21 +2615,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/jsonc-parser": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-0.4.2.tgz", - "integrity": "sha1-pLLK9n0acjlCgwZgYBMPcVBRMx0=", - "dev": true, - "dependencies": { - "vscode-nls": "^2.0.2" - } - }, - "node_modules/jsonc-parser/node_modules/vscode-nls": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz", - "integrity": "sha1-gIUiOAhEuK0VNJmvXDsDkhrqAto=", - "dev": true - }, "node_modules/keytar": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", @@ -2538,6 +2652,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -2583,11 +2698,12 @@ "node": ">=8" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -2619,13 +2735,6 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/markdown-it/node_modules/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -2665,21 +2774,23 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/mime": { @@ -2752,18 +2863,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -2772,10 +2871,11 @@ "license": "MIT" }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.8", @@ -2868,17 +2968,18 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -2928,6 +3029,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -3048,6 +3150,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3067,12 +3170,16 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkg-dir": { @@ -3121,19 +3228,11 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", @@ -3146,10 +3245,11 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3171,10 +3271,25 @@ } }, "node_modules/queue-microtask": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", - "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", - "dev": true + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", @@ -3253,15 +3368,6 @@ "node": ">= 10.13.0" } }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -3320,30 +3426,20 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, "node_modules/run-parallel": { @@ -3351,6 +3447,21 @@ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -3455,7 +3566,6 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -3636,54 +3746,11 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -3715,12 +3782,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -3731,27 +3792,14 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -3762,8 +3810,12 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -3791,39 +3843,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", - "dev": true, - "dependencies": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz", - "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -3922,19 +3941,6 @@ } } }, - "node_modules/terser/node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -3956,6 +3962,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -3963,6 +3970,19 @@ "node": ">=8.0" } }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-loader": { "version": "9.5.4", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", @@ -3984,24 +4004,6 @@ "webpack": "^5.0.0" } }, - "node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -4030,6 +4032,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -4038,12 +4041,16 @@ } }, "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typed-rest-client": { @@ -4140,6 +4147,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -4158,12 +4166,6 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, "node_modules/vsce": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.15.0.tgz", @@ -4239,7 +4241,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" @@ -4249,7 +4250,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz", "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==", - "dev": true, "license": "MIT", "dependencies": { "minimatch": "^5.1.0", @@ -4264,7 +4264,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -4274,7 +4273,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -4287,7 +4285,6 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", - "dev": true, "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", @@ -4298,7 +4295,6 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", - "dev": true, "license": "MIT" }, "node_modules/watchpack": { @@ -4447,20 +4443,6 @@ "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/webpack/node_modules/acorn-import-phases": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", @@ -4521,10 +4503,11 @@ "license": "MIT" }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4587,71 +4570,89 @@ "dependencies": { "buffer-crc32": "~0.2.3" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, - "@babel/highlight": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", - "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==", + "@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "eslint-visitor-keys": "^3.4.3" } }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true }, "@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, "@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -4695,28 +4696,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -4746,44 +4747,12 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true }, - "@types/events": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, "@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/node": { "version": "24.10.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", @@ -4793,15 +4762,11 @@ "undici-types": "~7.16.0" } }, - "@types/rimraf": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", - "integrity": "sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } + "@types/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-1mAINjtQCXXeLkJ9ehXkwOcBpqtLxiVtKhpUf83DdRNdQKV0iXZpaHYqRr7nj+wvxuJzoAmAwXI+sCNMv1CzLQ==", + "dev": true }, "@types/vscode": { "version": "1.105.0", @@ -4810,100 +4775,132 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.16.1.tgz", - "integrity": "sha512-SK777klBdlkUZpZLC1mPvyOWk9yAFCWmug13eAjVQ4/Q1LATE/NbcQL1xDHkptQkZOLnPmLUA1Y54m8dqYwnoQ==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.16.1", - "@typescript-eslint/scope-manager": "4.16.1", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" } }, - "@typescript-eslint/experimental-utils": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.16.1.tgz", - "integrity": "sha512-0Hm3LSlMYFK17jO4iY3un1Ve9x1zLNn4EM50Lia+0EV99NdbK+cn0er7HC7IvBA23mBg3P+8dUkMXy4leL33UQ==", + "@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, + "peer": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.16.1", - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/typescript-estree": "4.16.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" } }, - "@typescript-eslint/parser": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.16.1.tgz", - "integrity": "sha512-/c0LEZcDL5y8RyI1zLcmZMvJrsR6SM1uetskFkoh3dvqDKVXPsXI+wFB/CbVw7WkEyyTKobC1mUNp/5y6gRvXg==", + "@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.16.1", - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/typescript-estree": "4.16.1", - "debug": "^4.1.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, - "@typescript-eslint/scope-manager": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.16.1.tgz", - "integrity": "sha512-6IlZv9JaurqV0jkEg923cV49aAn8V6+1H1DRfhRcvZUrptQ+UtSKHb5kwTayzOYTJJ/RsYZdcvhOEKiBLyc0Cw==", + "@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "requires": { - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/visitor-keys": "4.16.1" + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.16.1.tgz", - "integrity": "sha512-nnKqBwMgRlhzmJQF8tnFDZWfunXmJyuXj55xc8Kbfup4PbkzdoDXZvzN8//EiKR27J6vUSU8j4t37yUuYPiLqA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.16.1.tgz", - "integrity": "sha512-m8I/DKHa8YbeHt31T+UGd/l8Kwr0XCTCZL3H4HMvvLCT7HU9V7yYdinTOv1gf/zfqNeDcCgaFH2BMsS8x6NvJg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.16.1", - "@typescript-eslint/visitor-keys": "4.16.1", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.16.1.tgz", - "integrity": "sha512-s/aIP1XcMkEqCNcPQtl60ogUYjSM8FU2mq1O7y5cFf3Xcob1z1iXWNB6cC43Op+NGRTFgGolri6s8z/efA9i1w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "4.16.1", - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true - } + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" } }, - "@vscode/codicons": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.45.tgz", - "integrity": "sha512-1KAZ7XCMagp5Gdrlr4bbbcAqgcIL623iO1wW6rfcSVGAVUQvR0WP7bQx1SbJ11gmV3fdQTSEFIJQ/5C+HuVasw==" + "@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "dev": true }, "@webassemblyjs/ast": { "version": "1.14.1", @@ -5085,21 +5082,23 @@ "dev": true }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "peer": true }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -5137,12 +5136,6 @@ } } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -5159,13 +5152,10 @@ } }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-union": { "version": "2.1.0", @@ -5173,12 +5163,6 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "azure-devops-node-api": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz", @@ -5192,8 +5176,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { "version": "1.5.1", @@ -5235,12 +5218,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -5482,12 +5465,12 @@ "dev": true }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "^2.1.3" } }, "decompress-response": { @@ -5506,9 +5489,9 @@ "dev": true }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "detect-libc": { @@ -5589,12 +5572,6 @@ "integrity": "sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==", "dev": true }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "encoding-sniffer": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", @@ -5624,15 +5601,6 @@ "tapable": "^2.2.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -5685,72 +5653,110 @@ "dev": true }, "eslint": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz", - "integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, + "peer": true, "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.20", - "minimatch": "^3.0.4", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } } } }, @@ -5764,59 +5770,36 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -5869,17 +5852,27 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.8" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "fast-json-stable-stringify": { @@ -5891,7 +5884,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-uri": { @@ -5907,9 +5900,9 @@ "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -5934,9 +5927,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -5997,66 +5990,12 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true - } - } - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -6075,12 +6014,6 @@ "math-intrinsics": "^1.1.0" } }, - "get-port": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true - }, "get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -6112,12 +6045,12 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "glob-to-regexp": { @@ -6127,34 +6060,26 @@ "dev": true }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" } }, "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } } }, "gopd": { @@ -6169,6 +6094,12 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -6235,15 +6166,15 @@ "dev": true }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -6306,19 +6237,13 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -6330,6 +6255,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -6379,20 +6310,13 @@ } } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "json-parse-even-better-errors": { @@ -6413,23 +6337,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "jsonc-parser": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-0.4.2.tgz", - "integrity": "sha1-pLLK9n0acjlCgwZgYBMPcVBRMx0=", - "dev": true, - "requires": { - "vscode-nls": "^2.0.2" - }, - "dependencies": { - "vscode-nls": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz", - "integrity": "sha1-gIUiOAhEuK0VNJmvXDsDkhrqAto=", - "dev": true - } - } - }, "keytar": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", @@ -6486,10 +6393,10 @@ "p-locate": "^4.1.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lru-cache": { @@ -6514,12 +6421,6 @@ "uc.micro": "^1.0.5" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -6553,13 +6454,13 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.3", + "picomatch": "^2.3.1" } }, "mime": { @@ -6604,15 +6505,6 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -6620,9 +6512,9 @@ "dev": true }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "mute-stream": { @@ -6695,9 +6587,9 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -6705,7 +6597,7 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" } }, "p-limit": { @@ -6837,9 +6729,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true }, "pkg-dir": { @@ -6877,12 +6769,6 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", @@ -6894,9 +6780,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -6909,9 +6795,9 @@ } }, "queue-microtask": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", - "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "randombytes": { @@ -6972,12 +6858,6 @@ "resolve": "^1.20.0" } }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -7019,20 +6899,11 @@ "dev": true }, "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7105,8 +6976,7 @@ "semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" }, "serialize-javascript": { "version": "6.0.2", @@ -7212,43 +7082,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, "source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", @@ -7273,12 +7106,6 @@ } } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -7288,24 +7115,13 @@ "safe-buffer": "~5.2.0" } }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { @@ -7329,38 +7145,6 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", - "dev": true, - "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ajv": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz", - "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, "tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -7402,14 +7186,6 @@ "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" - }, - "dependencies": { - "acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true - } } }, "terser-webpack-plugin": { @@ -7446,6 +7222,13 @@ "is-number": "^7.0.0" } }, + "ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "requires": {} + }, "ts-loader": { "version": "9.5.4", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", @@ -7459,21 +7242,6 @@ "source-map": "^0.7.4" } }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, "tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -7499,9 +7267,9 @@ } }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typed-rest-client": { @@ -7577,12 +7345,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, "vsce": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.15.0.tgz", @@ -7639,14 +7401,12 @@ "vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", - "dev": true + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==" }, "vscode-languageclient": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz", "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==", - "dev": true, "requires": { "minimatch": "^5.1.0", "semver": "^7.3.7", @@ -7657,7 +7417,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -7666,7 +7425,6 @@ "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -7677,7 +7435,6 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", - "dev": true, "requires": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" @@ -7686,8 +7443,7 @@ "vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", - "dev": true + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" }, "watchpack": { "version": "2.4.4", @@ -7733,13 +7489,6 @@ "webpack-sources": "^3.3.3" }, "dependencies": { - "acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "peer": true - }, "acorn-import-phases": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", @@ -7827,9 +7576,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wrappy": { @@ -7878,6 +7627,12 @@ "requires": { "buffer-crc32": "~0.2.3" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/client/package.json b/client/package.json index 3f9b7ce5..020c47de 100644 --- a/client/package.json +++ b/client/package.json @@ -1,8 +1,8 @@ { - "name": "liquid-java", + "name": "liquid-java-baseline", "displayName": "LiquidJava", "description": "Extending Java with Liquid Types", - "version": "0.0.90", + "version": "0.0.1", "publisher": "AlcidesFonseca", "repository": { "type": "git", @@ -39,151 +39,28 @@ "onLanguage:java" ], "main": "./dist/extension.js", - "contributes": { - "configuration": { - "type": "object", - "title": "Liquid Java configuration", - "properties": { - "liquidJavaServer.maxNumberOfProblems": { - "type": "number", - "default": 100, - "description": "Controls the maximum number of problems produced by the server." - }, - "liquidJavaServer.trace.server": { - "type": "string", - "enum": [ - "off", - "messages", - "verbose" - ], - "default": "off", - "description": "Traces the communication between VSCode and the liquidJavaServer service." - }, - "liquidjava.applyItalicOverlay": { - "type": "boolean", - "default": true, - "description": "Apply italic style to LiquidJava injected tokens on top of any active theme" - } - } - }, - "viewsContainers": { - "activitybar": [ - { - "id": "liquidJavaContainer", - "title": "LiquidJava", - "icon": "media/java-icon.svg" - } - ] - }, - "views": { - "liquidJavaContainer": [ - { - "id": "liquidJavaView", - "name": "LiquidJava", - "type": "webview", - "icon": "media/java-icon.svg" - } - ] - }, - "commands": [ - { - "command": "liquidjava.showCommands", - "title": "Show Commands", - "category": "LiquidJava" - }, - { - "command": "liquidjava.showLogs", - "title": "Show Logs", - "category": "LiquidJava" - }, - { - "command": "liquidjava.showView", - "title": "Show View", - "category": "LiquidJava", - "icon": { - "light": "media/java-icon.svg", - "dark": "media/java-icon-white.svg" - } - }, - { - "command": "liquidjava.start", - "title": "Start", - "category": "LiquidJava" - }, - { - "command": "liquidjava.stop", - "title": "Stop", - "category": "LiquidJava" - }, - { - "command": "liquidjava.restart", - "title": "Restart", - "category": "LiquidJava" - }, - { - "command": "liquidjava.verify", - "title": "Verify", - "category": "LiquidJava" - } - ], - "menus": { - "editor/title": [ - { - "command": "liquidjava.showView", - "group": "navigation", - "when": "editorLangId == java" - } - ] - }, - "grammars": [ - { - "path": "./syntaxes/liquidjava.json", - "scopeName": "source.liquidjava", - "injectTo": [ - "source.java" - ] - } - ], - "configurationDefaults": { - "[java]": { - "editor.autoClosingBrackets": "always" - } - } - }, + "contributes": {}, "scripts": { "vscode:prepublish": "npm run package", "compile": "webpack", "watch": "webpack --watch", "package": "webpack --mode production --devtool hidden-source-map", "build:server": "cd ../server && mvn clean package && mkdir -p ../client/server && cp target/language-server-liquidjava.jar ../client/server/", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "npm run compile-tests && npm run compile && npm run lint", "lint": "eslint src --ext ts", - "test": "node ./out/test/runTest.js" + "test": "npm run test:baseline" }, - "extensionDependencies": [], "dependencies": { - "@vscode/codicons": "^0.0.45" + "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@types/mkdirp": "^0.5.2", "@types/node": "^24.7.2", - "@types/rimraf": "^2.0.2", "@types/vscode": "^1.82.0", - "@typescript-eslint/eslint-plugin": "^4.16.0", - "@typescript-eslint/parser": "^4.16.0", - "eslint": "^7.21.0", - "ftp": "^0.3.10", - "get-port": "^5.1.1", - "jsonc-parser": "^0.4.2", - "minimist": "^1.2.7", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.2", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", "ts-loader": "^9.5.4", "typescript": "~5.3.0", "vsce": "^2.15.0", - "vscode-languageclient": "^9.0.1", "webpack": "^5.102.1", "webpack-cli": "^5.1.4" } diff --git a/client/src/extension.ts b/client/src/extension.ts index dce1496f..9b24f556 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -1,120 +1,30 @@ import * as vscode from "vscode"; -import { registerLogger } from "./services/logger"; -import { applyItalicOverlay } from "./services/decorators"; -import { findJavaExecutable } from "./utils/utils"; -import { extension } from "./state"; -import { registerCommands } from "./services/commands"; -import { registerStatusBar, updateStatusBar } from "./services/status-bar"; -import { registerWebview } from "./services/webview"; -import { registerHover } from "./services/hover"; -import { registerEvents } from "./services/events"; -import { registerAutocomplete } from "./services/autocomplete"; -import { refreshCodeLenses, registerCodeLens } from "./services/codelens"; -import { runLanguageServer, stopLanguageServer } from "./lsp/server"; import { runClient, stopClient } from "./lsp/client"; +import { runLanguageServer, stopLanguageServer } from "./lsp/server"; +import { findJavaExecutable } from "./utils/utils"; /** - * Activates the LiquidJava extension - * @param context The extension context + * Starts LiquidJava and reports verifier errors as standard VS Code diagnostics. */ export async function activate(context: vscode.ExtensionContext) { - registerLogger(context); - extension.logger!.client.info("Activating LiquidJava extension..."); - - registerStatusBar(context); - registerCommands(context); - registerEvents(context); - registerWebview(context); - registerAutocomplete(context); - registerCodeLens(context); - registerHover(); - await applyItalicOverlay(); - await startExtension(context); -} - -/** - * Deactivates the LiquidJava extension - */ -export async function deactivate() { - extension.logger?.client.info("Deactivating LiquidJava extension..."); - await stopClient("Extension was deactivated"); - await stopLanguageServer(); - resetExtension(); -} - -/** - * Starts the LiquidJava language server and client - * @param context The extension context - */ -export async function startExtension(context: vscode.ExtensionContext) { - // check if already running - if (extension.client || extension.serverProcess) { - extension.logger!.client.info("LiquidJava is already running"); - return; - } - extension.logger!.client.info("Starting LiquidJava..."); - updateStatusBar("loading"); - - // find java executable path const javaExecutablePath = findJavaExecutable(); if (!javaExecutablePath) { vscode.window.showErrorMessage("LiquidJava - Java Runtime Not Found in JAVA_HOME or PATH"); - extension.logger!.client.error("Java Runtime not found in JAVA_HOME or PATH"); - updateStatusBar("stopped"); return; } - extension.logger!.client.info("Using Java at: " + javaExecutablePath); - // start server - extension.logger!.client.info("Starting LiquidJava language server..."); const port = await runLanguageServer(context, javaExecutablePath); - - // start client - extension.logger!.client.info("Starting LiquidJava client..."); - await runClient(context, port); -} - -/** - * Stops the LiquidJava language server and client - */ -export async function stopExtension() { - if (!extension.client && !extension.serverProcess) { - extension.logger?.client.info("LiquidJava is not running"); - return; + try { + await runClient(context, port); + } catch { + await stopLanguageServer(); } - extension.logger?.client.info("Stopping LiquidJava..."); - resetExtension(); - await stopClient("Extension stop command"); - await stopLanguageServer(); } /** - * Restarts the LiquidJava language server and client - * @param context The extension context + * Stops the language client and server. */ -export async function restartExtension(context: vscode.ExtensionContext) { - extension.logger?.client.info("Restarting LiquidJava..."); - - // stop if running - if (extension.client || extension.serverProcess) { - await stopExtension(); - // ensure clean shutdown - await new Promise(resolve => setTimeout(resolve, 500)); - } - - // start again - await startExtension(context); -} - -export function isExtensionRunning(): boolean { - return extension.status !== "stopped" && Boolean(extension.client); -} - -export function resetExtension() { - extension.diagnostics = []; - extension.errorAtCursor = undefined; - refreshCodeLenses(); - extension.webview?.sendMessage({ type: "diagnostics", diagnostics: [] }); - if (extension.context) - extension.webview?.sendMessage({ type: "context", context: extension.context, errorAtCursor: extension.errorAtCursor }); +export async function deactivate() { + await stopClient(); + await stopLanguageServer(); } diff --git a/client/src/lsp/client.ts b/client/src/lsp/client.ts index 99aa0c9f..fe0c49d8 100644 --- a/client/src/lsp/client.ts +++ b/client/src/lsp/client.ts @@ -1,102 +1,46 @@ -import * as vscode from 'vscode'; -import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node'; -import { connectToPort } from '../utils/utils'; -import { extension } from '../state'; -import { updateStatusBar } from '../services/status-bar'; -import { handleLJDiagnostics, handleLJFailure } from '../services/diagnostics'; -import { onActiveFileChange } from '../services/events'; -import type { LJDiagnostic } from "../types/diagnostics"; -import { LJContext } from '../types/context'; -import { handleContext } from '../services/context'; +import * as vscode from "vscode"; +import { LanguageClient, LanguageClientOptions, ServerOptions } from "vscode-languageclient/node"; +import { extension } from "../state"; +import { connectToPort } from "../utils/utils"; /** - * Starts the client and connects it to the language server - * @param context The extension context - * @param port The port number the server is running on + * Connects the standard language client to the LiquidJava server. */ export async function runClient(context: vscode.ExtensionContext, port: number) { const serverOptions: ServerOptions = async () => { - try { - extension.socket = await connectToPort(port) - return { - writer: extension.socket, - reader: extension.socket, - } - } catch (error) { - await stopClient("Failed to connect to server") - throw error - } + extension.socket = await connectToPort(port); + return { + writer: extension.socket, + reader: extension.socket, + }; }; const clientOptions: LanguageClientOptions = { documentSelector: [{ language: "java" }], }; + extension.client = new LanguageClient("liquidJavaServer", "LiquidJava Server", serverOptions, clientOptions); - - context.subscriptions.push(extension.client); // disposed on deactivation + context.subscriptions.push(extension.client); try { await extension.client.start(); - extension.logger!.client.info("Extension is ready"); - - extension.client.onNotification("liquidjava/diagnostics", (diagnostics: LJDiagnostic[]) => { - handleLJDiagnostics(diagnostics); - }); - - extension.client.onNotification("liquidjava/failure", () => { - handleLJFailure(); - }); - - extension.client.onNotification("liquidjava/context", (context: LJContext) => { - handleContext(context); - }); - - const editor = vscode.window.activeTextEditor; - if (editor && editor.document.languageId === "java") { - await onActiveFileChange(editor); - } - } catch (e) { - vscode.window.showErrorMessage("LiquidJava failed to initialize: " + String(e)); - extension.logger!.client.error("Failed to initialize: " + String(e)); - await stopClient("Failed to initialize"); + } catch (error) { + vscode.window.showErrorMessage("LiquidJava failed to initialize: " + String(error)); + await stopClient(); + throw error; } - - // update status bar on file save - context.subscriptions.push( - vscode.workspace.onDidSaveTextDocument(() => { - if (extension.client) { - updateStatusBar("loading"); - } - }) - ); } /** - * Stops the LiquidJava client - * @param reason The reason for stopping the client + * Stops the standard language client connection. */ -export async function stopClient(reason: string) { - if (!extension.client && !extension.serverProcess && !extension.socket) { - extension.logger!.client.info("Extension already stopped"); - return; - } - extension.logger!.client.info("Stopping LiquidJava extension: " + reason); - updateStatusBar("stopped"); - - // stop client +export async function stopClient() { try { await extension.client?.stop(); - } catch (e) { - extension.logger!.client.error("Error stopping client: " + e); + } catch { + // the connection may already be closed } finally { extension.client = undefined; - } - - // close socket - try { extension.socket?.destroy(); - } catch (e) { - extension.logger!.client.error("Error closing socket: " + e); - } finally { extension.socket = undefined; } } diff --git a/client/src/lsp/server.ts b/client/src/lsp/server.ts index a6beaa6f..81b9ca7d 100644 --- a/client/src/lsp/server.ts +++ b/client/src/lsp/server.ts @@ -1,54 +1,35 @@ -import * as vscode from 'vscode'; -import * as child_process from 'child_process'; -import * as path from 'path'; -import { getAvailablePort, killProcess, normalizeFilePath } from '../utils/utils'; -import { extension } from '../state'; -import { DEBUG_MODE, DEBUG_PORT, SERVER_JAR } from '../utils/constants'; +import * as child_process from "child_process"; +import * as path from "path"; +import * as vscode from "vscode"; +import { extension } from "../state"; +import { DEBUG_MODE, DEBUG_PORT, SERVER_JAR } from "../utils/constants"; +import { getAvailablePort, killProcess, normalizeFilePath } from "../utils/utils"; /** - * Runs the LiquidJava language server - * @param context The extension context - * @param javaExecutablePath The path to the Java executable - * @returns A promise to the port number the server is running on + * Starts the LiquidJava language server. */ -export async function runLanguageServer(context: vscode.ExtensionContext, javaExecutablePath: string): Promise { +export async function runLanguageServer( + context: vscode.ExtensionContext, + javaExecutablePath: string +): Promise { const port = DEBUG_MODE ? DEBUG_PORT : await getAvailablePort(); - if (DEBUG_MODE) { - extension.logger!.client.info("DEBUG MODE: Using fixed port " + port); - return port; - } - extension.logger!.client.info("Running language server on port " + port); + if (DEBUG_MODE) return port; const jarPath = path.resolve(context.extensionPath, "dist", "server", SERVER_JAR); - const args = ["-jar", jarPath, port.toString()]; const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; - const options = { - cwd: workspaceFolder ? normalizeFilePath(workspaceFolder.uri.fsPath) : context.extensionPath, // root path - }; - extension.logger!.client.info("Creating language server process..."); - extension.serverProcess = child_process.spawn(javaExecutablePath, args, options); - - // listen to process events - extension.serverProcess.stdout?.on("data", (data) => { - const message = data.toString().trim(); - extension.logger!.server.info(message); - }); - extension.serverProcess.stderr?.on("data", (data) => { - extension.logger!.server.error(data.toString().trim()) - }); - extension.serverProcess.on("error", (err) => { - extension.logger!.server.error(`Failed to start: ${err}`) + const cwd = workspaceFolder ? normalizeFilePath(workspaceFolder.uri.fsPath) : context.extensionPath; + extension.serverProcess = child_process.spawn(javaExecutablePath, ["-jar", jarPath, port.toString()], { + cwd, + stdio: "ignore", }); - extension.serverProcess.on("close", (code) => { - extension.logger!.server.info(`Process exited with code ${code}`); + extension.serverProcess.on("close", () => { extension.serverProcess = undefined; }); return port; } /** - * Stops the LiquidJava language server - * @returns A promise that resolves when the server is stopped + * Stops the LiquidJava language server. */ export async function stopLanguageServer() { await killProcess(extension.serverProcess); diff --git a/client/src/services/autocomplete.ts b/client/src/services/autocomplete.ts deleted file mode 100644 index f63cb6ad..00000000 --- a/client/src/services/autocomplete.ts +++ /dev/null @@ -1,252 +0,0 @@ -import * as vscode from "vscode"; -import { extension } from "../state"; -import type { LJVariable, LJContext, LJGhost, LJAlias } from "../types/context"; -import { getSimpleName } from "../utils/utils"; -import { LIQUIDJAVA_ANNOTATION_START, LJAnnotation } from "../utils/constants"; -import { filterDuplicateVariables, filterInstanceVariables } from "./context"; -import { isExtensionRunning } from "../extension"; - -type CompletionItemOptions = { - name: string; - kind: vscode.CompletionItemKind; - description?: string; - labelDetail?: string; - detail: string; - documentationBlocks?: string[]; - codeBlocks?: string[]; - insertText?: string; - triggerParameterHints?: boolean; -} -type CompletionItemKind = "vars" | "ghosts" | "aliases" | "keywords" | "types" | "packages"; - -/** - * Registers a completion provider for LiquidJava annotations, providing context-aware suggestions based on the current context - */ -export function registerAutocomplete(context: vscode.ExtensionContext) { - context.subscriptions.push( - vscode.languages.registerCompletionItemProvider("java", { - provideCompletionItems(document, position, _token, completionContext) { - if (!isExtensionRunning()) return null; - - const annotation = getActiveLiquidJavaAnnotation(document, position); - if (!annotation || !extension.context) return null; - - const isDotTrigger = completionContext.triggerKind === vscode.CompletionTriggerKind.TriggerCharacter && completionContext.triggerCharacter === "."; - const receiver = isDotTrigger ? getReceiverBeforeDot(document, position) : null; - const file = document.uri.toString().replace("file://", ""); - const nextChar = document.getText(new vscode.Range(position, position.translate(0, 1))); - const items = getContextCompletionItems(extension.context, file, annotation, nextChar, isDotTrigger, receiver); - const uniqueItems = new Map(); - items.forEach(item => { - const label = typeof item.label === "string" ? item.label : item.label.label; - if (!uniqueItems.has(label)) uniqueItems.set(label, item); - }); - return Array.from(uniqueItems.values()); - }, - }, '.', '"') - ); -} - -function getContextCompletionItems(context: LJContext, file: string, annotation: LJAnnotation, nextChar: string, isDotTrigger: boolean, receiver: string | null): vscode.CompletionItem[] { - const triggerParameterHints = nextChar !== "("; - const ghosts = context.ghosts.filter(ghost => ghost.file === file); - if (isDotTrigger) { - if (receiver === "this" || receiver === "old(this)") { - return getGhostCompletionItems(ghosts, triggerParameterHints); - } - return []; - } - const inScope = context.visibleVars !== null; - const varsInScope = filterDuplicateVariables(filterInstanceVariables([...context.visibleVars || []])); - const itemsHandlers: Record vscode.CompletionItem[]> = { - vars: () => getVariableCompletionItems(varsInScope), - ghosts: () => getGhostCompletionItems(ghosts, triggerParameterHints), - aliases: () => getAliasCompletionItems(context.aliases, triggerParameterHints), - keywords: () => getKeywordsCompletionItems(triggerParameterHints, inScope), - types: () => getTypesCompletionItems(), - packages: () => [], // TODO - } - const varCompletions: CompletionItemKind[] = ["vars", "ghosts", "aliases", "keywords"]; - const typeCompletions: CompletionItemKind[] = ["types"]; - const itemsMap: Record = { - Refinement: varCompletions, - StateRefinement: varCompletions, - Ghost: typeCompletions, - RefinementAlias: typeCompletions, - RefinementPredicate: typeCompletions, - StateSet: [], - ExternalRefinementsFor: [], // TODO - }; - return itemsMap[annotation] - .map(key => itemsHandlers[key]) - .filter((handler): handler is () => vscode.CompletionItem[] => Boolean(handler)) - .flatMap(handler => handler()); -} - -function getVariableCompletionItems(variables: LJVariable[]): vscode.CompletionItem[] { - return variables.map(variable => { - const varSig = `${variable.type} ${variable.name}`; - const codeBlocks: string[] = []; - if (variable.mainRefinement !== "true") codeBlocks.push(`@Refinement("${variable.mainRefinement}")`); - codeBlocks.push(varSig); - return createCompletionItem({ - name: variable.name, - kind: vscode.CompletionItemKind.Variable, - description: variable.type, - detail: "variable", - codeBlocks, - }); - }); -} - -function getGhostCompletionItems(ghosts: LJGhost[], triggerParameterHints: boolean): vscode.CompletionItem[] { - return ghosts.map(ghost => { - const parameters = ghost.parameterTypes.map(getSimpleName).join(", "); - const ghostSig = `${ghost.returnType} ${ghost.name}(${parameters})`; - const description = ghost.isState ? "state" : "ghost"; - return createCompletionItem({ - name: ghost.name, - kind: vscode.CompletionItemKind.Function, - labelDetail: `(${parameters})`, - description, - detail: description, - codeBlocks: [ghostSig], - insertText: triggerParameterHints ? `${ghost.name}($1)` : ghost.name, - triggerParameterHints, - }); - }); -} - -function getAliasCompletionItems(aliases: LJAlias[], triggerParameterHints: boolean): vscode.CompletionItem[] { - return aliases.map(alias => { - const parameters = alias.parameters - .map((parameter, index) => { - const type = getSimpleName(alias.types[index]); - return `${type} ${parameter}`; - }).join(", "); - const aliasSig = `${alias.name}(${parameters}) { ${alias.predicate} }`; - const description = "alias"; - return createCompletionItem({ - name: alias.name, - kind: vscode.CompletionItemKind.Function, - labelDetail: `(${parameters}){ ${alias.predicate} }`, - description, - detail: description, - codeBlocks: [aliasSig], - insertText: triggerParameterHints ? `${alias.name}($1)` : alias.name, - triggerParameterHints, - }); - }); -} - -function getKeywordsCompletionItems(triggerParameterHints: boolean, inScope: boolean): vscode.CompletionItem[] { - const thisItem = createCompletionItem({ - name: "this", - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - documentationBlocks: ["Keyword referring to the **current instance**"], - }); - const oldItem = getOldKeywordCompletionItem(triggerParameterHints); - const trueItem = createCompletionItem({ - name: "true", - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - }); - - const falseItem = createCompletionItem({ - name: "false", - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - }); - const items: vscode.CompletionItem[] = [thisItem, oldItem, trueItem, falseItem]; - if (!inScope) { - const returnItem = createCompletionItem({ - name: "return", - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - documentationBlocks: ["Keyword referring to the **method return value**"], - }); - items.push(returnItem); - } - return items; -} - -function getOldKeywordCompletionItem(triggerParameterHints: boolean): vscode.CompletionItem { - return createCompletionItem({ - name: "old", - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - documentationBlocks: ["Keyword referring to the **previous state of the current instance**"], - insertText: triggerParameterHints ? "old($1)" : "old", - triggerParameterHints, - }); -} - -function getTypesCompletionItems(): vscode.CompletionItem[] { - const types = ["int", "double", "float", "boolean"]; - return types.map(type => createCompletionItem({ - name: type, - kind: vscode.CompletionItemKind.Keyword, - description: "", - detail: "keyword", - })); -} - -function createCompletionItem({ name, kind, labelDetail, description, detail, documentationBlocks, codeBlocks, insertText, triggerParameterHints }: CompletionItemOptions): vscode.CompletionItem { - const item = new vscode.CompletionItem(name, kind); - item.label = { label: name, detail: labelDetail, description }; - item.detail = detail; - if (insertText) item.insertText = new vscode.SnippetString(insertText); - if (triggerParameterHints) item.command = { command: "editor.action.triggerParameterHints", title: "Trigger Parameter Hints" }; - - const documentation = new vscode.MarkdownString(); - if (documentationBlocks) documentationBlocks.forEach(block => documentation.appendMarkdown(block)); - if (codeBlocks) codeBlocks.forEach(block => documentation.appendCodeblock(block)); - item.documentation = documentation; - - return item; -} - -function getActiveLiquidJavaAnnotation(document: vscode.TextDocument, position: vscode.Position): LJAnnotation | null { - const textUntilCursor = document.getText(new vscode.Range(new vscode.Position(0, 0), position)); - LIQUIDJAVA_ANNOTATION_START.lastIndex = 0; - let match: RegExpExecArray | null = null; - let lastAnnotationStart = -1; - let lastAnnotationName: LJAnnotation | null = null; - while ((match = LIQUIDJAVA_ANNOTATION_START.exec(textUntilCursor)) !== null) { - lastAnnotationStart = match.index; - lastAnnotationName = match[2] ? match[2] as LJAnnotation : null; - } - if (lastAnnotationStart === -1 || !lastAnnotationName) return null; - - const fromLastAnnotation = textUntilCursor.slice(lastAnnotationStart); - let parenthesisDepth = 0; - let isInsideString = false; - for (let i = 0; i < fromLastAnnotation.length; i++) { - const char = fromLastAnnotation[i]; - const previousChar = i > 0 ? fromLastAnnotation[i - 1] : ""; - if (char === '"' && previousChar !== "\\") { - isInsideString = !isInsideString; - continue; - } - if (isInsideString) continue; - if (char === "(") parenthesisDepth++; - if (char === ")") parenthesisDepth--; - } - return parenthesisDepth > 0 ? lastAnnotationName : null; -} - -function getReceiverBeforeDot(document: vscode.TextDocument, position: vscode.Position): string | null { - const prefix = document.lineAt(position.line).text.slice(0, position.character); - const match = prefix.match(/((?:old\s*\(\s*this\s*\))|(?:[A-Za-z_]\w*))\.\w*$/); - if (!match) return null; - const receiver = match[1]?.trim(); - if (!receiver) return null; - if (/^old\s*\(\s*this\s*\)$/.test(receiver)) return "old(this)"; - return receiver; -} diff --git a/client/src/services/codelens.ts b/client/src/services/codelens.ts deleted file mode 100644 index 2a8c8c56..00000000 --- a/client/src/services/codelens.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as vscode from "vscode"; -import { extension } from "../state"; -import type { LJDiagnostic } from "../types/diagnostics"; -import { getDiagnosticRevealTarget } from "../webview/diagnostic-reveal"; -import { normalizeFilePath } from "../utils/utils"; -import { isExtensionRunning } from "../extension"; - -const codeLensEmitter = new vscode.EventEmitter(); - -export function registerCodeLens(context: vscode.ExtensionContext) { - context.subscriptions.push( - vscode.languages.registerCodeLensProvider("java", { - onDidChangeCodeLenses: codeLensEmitter.event, - provideCodeLenses(document) { - if (!isExtensionRunning()) return []; - - const file = normalizeFilePath(document.uri.fsPath); - return (extension.diagnostics || []) - .map(diagnostic => createDiagnosticCodeLens(diagnostic, file)) - .filter((codeLens): codeLens is vscode.CodeLens => Boolean(codeLens)); - } - }) - ); -} - -export function refreshCodeLenses() { - codeLensEmitter.fire(); -} - -function createDiagnosticCodeLens(diagnostic: LJDiagnostic, file: string): vscode.CodeLens | undefined { - const targetDiagnostic = getDiagnosticRevealTarget(diagnostic); - if (!targetDiagnostic || targetDiagnostic.file !== file) return undefined; - - const position = targetDiagnostic.position; - const range = new vscode.Range( - new vscode.Position(position.lineStart, position.colStart), - new vscode.Position(position.lineStart, position.colStart) - ); - return new vscode.CodeLens(range, { - title: diagnostic.title, - command: "liquidjava.showView", - arguments: [targetDiagnostic] - }); -} diff --git a/client/src/services/commands.ts b/client/src/services/commands.ts deleted file mode 100644 index fd5df16d..00000000 --- a/client/src/services/commands.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as vscode from "vscode"; -import { startExtension, stopExtension, restartExtension } from "../extension"; -import { verify } from "./diagnostics"; - -const commandIcons: Record = { - "liquidjava.showLogs": "$(output)", - "liquidjava.showView": "$(window)", - "liquidjava.start": "$(play)", - "liquidjava.stop": "$(debug-stop)", - "liquidjava.restart": "$(debug-restart)", - "liquidjava.verify": "$(check)", -} - -const commandHandlers: Record Promise> = { - "liquidjava.start": async (context) => await startExtension(context), - "liquidjava.stop": async () => await stopExtension(), - "liquidjava.restart": async (context) => await restartExtension(context), - "liquidjava.verify": async () => await verify(), -} - -/** - * Registers all commands for the LiquidJava extension - * @param context The extension context - */ -export function registerCommands(context: vscode.ExtensionContext) { - const packageJson = context.extension.packageJSON; - const commands = (packageJson.contributes?.commands || []) as vscode.Command[]; - - // register commands - commands.forEach(cmd => { - const handler = commandHandlers[cmd.command]; - if (handler) { - context.subscriptions.push( - vscode.commands.registerCommand(cmd.command, () => handler(context)) - ); - } - }); - - // register command to show all commands - context.subscriptions.push( - vscode.commands.registerCommand("liquidjava.showCommands", async () => { - const quickPickItems = commands - .filter(cmd => cmd.command !== "liquidjava.showCommands") - .map(cmd => ({ - label: `${commandIcons[cmd.command] || "$(symbol-misc)"} ${cmd.title}`, - command: cmd.command, - })); - - const placeHolder = "Select a LiquidJava Command"; - const selected = await vscode.window.showQuickPick(quickPickItems, { placeHolder }); - if (selected) vscode.commands.executeCommand(selected.command); - }) - ); -} \ No newline at end of file diff --git a/client/src/services/context.ts b/client/src/services/context.ts deleted file mode 100644 index a006d233..00000000 --- a/client/src/services/context.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { extension } from "../state"; -import { LJContext, Range, LJVariable } from "../types/context"; -import { RefinementMismatchError, SourcePosition } from "../types/diagnostics"; -import { getOriginalVariableName } from "../utils/utils"; - -export function handleContext(context: LJContext) { - extension.context = context; - if (!extension.file || !extension.currentSelection) return; - - // update variables based on new context in current selection - const { allVars, visibleVars } = getSelectionContextVariables(extension.file, extension.currentSelection); - extension.context.visibleVars = visibleVars; - extension.context.allVars = allVars; - updateErrorAtCursor(); - extension.webview?.sendMessage({ type: "context", context: extension.context, errorAtCursor: extension.errorAtCursor }); -} - -export function getSelectionContextVariables(file: string, selection: Range): { visibleVars: LJVariable[]; allVars: LJVariable[] } { - const globalVars = extension.context?.globalVars || []; - const localVars = extension.context?.localVars || []; - const variablesInScope = getVariablesInScope(localVars, file, selection); - const visibleVarsByPosition = getVisibleVariables(variablesInScope, file, selection, false); - const visibleVarsByAnnotationPosition = getVisibleVariables(variablesInScope, file, selection, true); - const allVars = sortVariables(normalizeVariableRefinements([...globalVars, ...visibleVarsByPosition])); - return { visibleVars: visibleVarsByAnnotationPosition, allVars }; -} - -export function updateErrorAtCursor() { - if (!extension.file || !extension.currentSelection) return; - const file = extension.file; - const selection = extension.currentSelection; - const errors: RefinementMismatchError[] = extension.diagnostics?.filter(d => d.type === 'refinement-error' || d.type === 'state-refinement-error') as RefinementMismatchError[] || []; - const scopes = extension.context?.fileScopes[file] || []; - const errorAtCursor = errors.find(error => { - const position = error.position; - if (!position) return false; - const sameFile = position.file === file; - const beforeCursor = isPositionBefore(position, selection); - if (!sameFile || !beforeCursor) return false; - // check if error is within a scope that contains the cursor - const errorScope = scopes.find(scope => isRangeWithin(position, scope)); - return errorScope && isRangeWithin(selection, errorScope); - }); - extension.errorAtCursor = errorAtCursor; -} - -function getVariablesInScope(variables: LJVariable[], file: string, selection: Range): LJVariable[] { - const scopes = extension.context?.fileScopes[file] || []; - const enclosingScopes = scopes.filter(scope => isRangeWithin(selection, scope)); - return variables.filter(v => { - const position = v.position; - if (!position) return false - return position.file === file && - enclosingScopes.some(scope => isRangeWithin(position, scope)) - }); -} - -function getVisibleVariables(variables: LJVariable[], file: string, selection: Range, useAnnotationPosition: boolean): LJVariable[] { - const isCollapsedRange = selection.lineStart === selection.lineEnd && selection.colStart === selection.colEnd; - const fileScopes = isCollapsedRange ? (extension.context?.fileScopes[file] || []) : []; - return variables.filter((variable) => { - // variable must be declared in the same file - if (!variable.position || variable.position?.file !== file) return false; - - // single point cursor - if (isCollapsedRange) { - const position: SourcePosition = (useAnnotationPosition && variable.annotationPosition) || variable.position; - - // variable was declared before the cursor line or its in the same line but before the cursor column - const beforeCursor = isPositionBefore(position, selection); - if (!beforeCursor) return false; - - // exclude variables that in unreachable scopes - const isInUnreachableScope = fileScopes.some(scope => - isRangeWithin(variable.position!, scope) && !isRangeWithin(selection, scope) - ); - return !isInUnreachableScope; - } - // normal range, filter variables that intersect the selection - return rangesIntersect(variable.position, selection); - }); -} - -// Normalizes the range to ensure start is before end -export function normalizeRange(range: Range): Range { - if (isBefore(range.lineStart, range.colStart, range.lineEnd, range.colEnd)) return range; - return { lineStart: range.lineEnd, colStart: range.colEnd, lineEnd: range.lineStart, colEnd: range.colStart }; -} - -export function rangesIntersect(a: Range, b: Range): boolean { - return isBeforeOrEqual(a.lineStart, a.colStart, b.lineEnd, b.colEnd) && - isBeforeOrEqual(b.lineStart, b.colStart, a.lineEnd, a.colEnd); -} - -export function isRangeWithin(range: Range, another: Range): boolean { - return isBeforeOrEqual(another.lineStart, another.colStart, range.lineStart, range.colStart) && - isBeforeOrEqual(range.lineEnd, range.colEnd, another.lineEnd, another.colEnd); -} - -export function isPositionBefore(range: Range, another: Range): boolean { - return isBefore(range.lineStart, range.colStart, another.lineStart, another.colStart); -} - -function isBefore(line1: number, col1: number, line2: number, col2: number): boolean { - return line1 < line2 || (line1 === line2 && col1 < col2); -} - -function isBeforeOrEqual(line1: number, col1: number, line2: number, col2: number): boolean { - return line1 < line2 || (line1 === line2 && col1 <= col2); -} - -export function filterInstanceVariables(variables: LJVariable[]): LJVariable[] { - return variables.filter(v => !v.internalName.includes("#")); -} - -export function filterDuplicateVariables(variables: LJVariable[]): LJVariable[] { - const uniqueVariables: Map = new Map(); - for (const variable of variables) { - if (!uniqueVariables.has(variable.name)) { - uniqueVariables.set(variable.name, variable); - } - } - return Array.from(uniqueVariables.values()); -} - -// Sorts variables by their position or name -function sortVariables(variables: LJVariable[]): LJVariable[] { - return variables.sort((left, right) => { - if (!left.position && !right.position) return compareVariableNames(left.internalName, right.internalName); - if (!left.position) return 1; - if (!right.position) return -1; - if (left.position.lineStart !== right.position.lineStart) return left.position.lineStart - right.position.lineStart; - if (left.position.colStart !== right.position.colStart) return right.position.colStart - left.position.colStart; - return compareVariableNames(left.internalName, right.internalName); - }); -} - -function compareVariableNames(a: string, b: string): number { - if (a.startsWith("#") && b.startsWith("#")) return getOriginalVariableName(a).localeCompare(getOriginalVariableName(b)); - if (a.startsWith("#")) return 1; - if (b.startsWith("#")) return -1; - return a.localeCompare(b); -} - -function normalizeVariableRefinements(variables: LJVariable[]): LJVariable[] { - return Array.from(new Map(variables.map(v => [`${v.internalName}:${v.refinement}`, v])).values()).flatMap(v => { // remove duplicates - if (!v.refinement || v.refinement === "true") return []; // filter out trivial refinements - if (v.refinement.includes("==")) { - const [left, right] = v.refinement.split("==").map(s => s.trim()); - return left !== right ? [v] : []; // filter tautologies like x == x - } - return [v]; - }); -} diff --git a/client/src/services/decorators.ts b/client/src/services/decorators.ts deleted file mode 100644 index cda7f397..00000000 --- a/client/src/services/decorators.ts +++ /dev/null @@ -1,37 +0,0 @@ -import * as vscode from "vscode"; -import { LIQUIDJAVA_SCOPES } from "../utils/constants"; - -type TMRule = { - scope: string | string[]; - settings: { fontStyle?: string; foreground?: string } -}; - -/** - * Apply italic fontStyle to LiquidJava TextMate scopes - * This preserves the active theme's colors and only adds italic style to injected tokens - */ -export async function applyItalicOverlay() { - const config = vscode.workspace.getConfiguration(); - const enabled = config.get("liquidjava.applyItalicOverlay", true); - if (!enabled) return; - - const italicRule: TMRule = { scope: LIQUIDJAVA_SCOPES, settings: { fontStyle: "italic" } }; - const current = config.get("editor.tokenColorCustomizations") || {}; - const existingRules: TMRule[] = current.textMateRules || []; - - // remove previous overlay if present to avoid duplication - const filteredRules = existingRules.filter((rule) => { - if (!rule || !rule.settings || !rule.settings.fontStyle) return true; - const str = rule.scope; - const scopes = Array.isArray(str) ? str : [str]; - const hasLiquidJavaScope = scopes?.some((x) => typeof x === "string" && x.includes("liquidjava")); - return !hasLiquidJavaScope; - }); - - const next = { - ...current, - textMateRules: [...filteredRules, italicRule], - }; - - await config.update("editor.tokenColorCustomizations", next, vscode.ConfigurationTarget.Global); -} \ No newline at end of file diff --git a/client/src/services/definition.ts b/client/src/services/definition.ts deleted file mode 100644 index e20a3b6a..00000000 --- a/client/src/services/definition.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as vscode from 'vscode'; - -type Definition = { - uri: vscode.Uri; -} - -export async function getDefinitions(document: vscode.TextDocument, position: vscode.Position): Promise { - try { - const definitions = await vscode.commands.executeCommand<(vscode.Location | vscode.LocationLink)[]>( - 'vscode.executeDefinitionProvider', - document.uri, - position - ) || []; - return definitions.map(definition => definition instanceof vscode.Location - ? { uri: definition.uri } - : { uri: definition.targetUri } - ); - } catch { - return []; - } -} - -export function definitionMatchesClass(definition: Definition, targetClass: string): boolean { - const uri = definition.uri.toString(); - return !!targetClass && (uri.includes(targetClass) || uri.includes(targetClass.replace(/\./g, '/'))); -} diff --git a/client/src/services/diagnostics.ts b/client/src/services/diagnostics.ts deleted file mode 100644 index 57422227..00000000 --- a/client/src/services/diagnostics.ts +++ /dev/null @@ -1,57 +0,0 @@ -import * as vscode from "vscode"; -import { extension, ExtensionStatus } from "../state"; -import { LJDiagnostic } from "../types/diagnostics"; -import { updateStatusBar } from "./status-bar"; -import { updateErrorAtCursor } from "./context"; -import { refreshCodeLenses } from "./codelens"; - -/** - * Handles LiquidJava diagnostics received from the language server - * @param diagnostics The array of diagnostics received - */ -export function handleLJDiagnostics(diagnostics: LJDiagnostic[]) { - const containsError = diagnostics.some(d => d.category === "error"); - const statusBarState: ExtensionStatus = containsError ? "failed" : "passed"; - updateStatusBar(statusBarState); - extension.diagnostics = diagnostics; - refreshCodeLenses(); - updateErrorAtCursor(); - extension.webview?.sendMessage({ type: "diagnostics", diagnostics }); - if (extension.context) - extension.webview?.sendMessage({ type: "context", context: extension.context, errorAtCursor: extension.errorAtCursor }); -} - -/** - * Handles LiquidJava verifier crashes received from the language server - */ -export function handleLJFailure() { - extension.diagnostics = []; - extension.errorAtCursor = undefined; - refreshCodeLenses(); - extension.webview?.sendMessage({ type: "diagnostics", diagnostics: [] }); - if (extension.context) - extension.webview?.sendMessage({ type: "context", context: extension.context, errorAtCursor: extension.errorAtCursor }); - updateStatusBar("crashed"); -} - -/** - * Triggers the LiquidJava verification manually - */ -export async function verify() { - const editor = vscode.window.activeTextEditor; - if (!editor || editor.document.languageId !== "java") { - vscode.window.showWarningMessage("LiquidJava: No Java file is currently open"); - return; - } - - if (!extension.client) { - vscode.window.showWarningMessage("LiquidJava: Extension is not running. Use 'LiquidJava: Start' first."); - return; - } - - const uri = editor.document.uri.toString(); - extension.logger?.client.info("Verify command — checking diagnostics"); - updateStatusBar("loading"); - - extension.client.sendNotification("liquidjava/verify", { uri }); -} diff --git a/client/src/services/editor.ts b/client/src/services/editor.ts deleted file mode 100644 index 7a1ecded..00000000 --- a/client/src/services/editor.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as vscode from 'vscode' -import { Range } from '../types/context'; - -const highlight = vscode.window.createTextEditorDecorationType({ - backgroundColor: 'rgba(255, 255, 0, 0.3)' -}) - -export async function openFile(filePath: string, line: number, character: number, rangeToHighlight?: Range) { - const uri = vscode.Uri.file(filePath); - const doc = await vscode.workspace.openTextDocument(uri); - const editor = await vscode.window.showTextDocument(doc); - const position = new vscode.Position(line, character); - const range = new vscode.Range(position, position); - editor.selection = new vscode.Selection(position, position); - editor.revealRange(range, vscode.TextEditorRevealType.InCenter); - if (rangeToHighlight) highlightRange(editor, rangeToHighlight); -} - -export function highlightRange(editor: vscode.TextEditor | undefined, range: Range | null) { - if (!editor) return; - if (!range) { - editor.setDecorations(highlight, []) - return; - } - const nativeRange = new vscode.Range( - new vscode.Position(range.lineStart, range.colStart), - new vscode.Position(range.lineEnd, range.colEnd) - ) - editor.setDecorations(highlight, [{ range: nativeRange }]) - editor.revealRange(nativeRange, vscode.TextEditorRevealType.InCenter) -} diff --git a/client/src/services/events.ts b/client/src/services/events.ts deleted file mode 100644 index 3596a10f..00000000 --- a/client/src/services/events.ts +++ /dev/null @@ -1,73 +0,0 @@ -import * as vscode from 'vscode'; -import { extension } from '../state'; -import { updateStateMachine } from './state-machine'; -import { SELECTION_DEBOUNCE_MS } from '../utils/constants'; -import { getSelectionContextVariables, normalizeRange, updateErrorAtCursor } from './context'; -import { normalizeFilePath, toRange } from '../utils/utils'; - -let selectionTimeout: NodeJS.Timeout | null = null; - -/** - * Initializes file system event listeners - * @param context The extension context - */ -export function registerEvents(context: vscode.ExtensionContext) { - // listen for active text editor changes - context.subscriptions.push( - vscode.window.onDidChangeActiveTextEditor(async editor => { - if (!editor || editor.document.languageId !== "java") return; - await onActiveFileChange(editor); - }), - vscode.workspace.onDidSaveTextDocument(async document => { - if (document.uri.scheme !== 'file' || document.languageId !== "java") return; - await updateStateMachine(document) - }), - vscode.window.onDidChangeTextEditorSelection(event => { - if (event.textEditor.document.uri.scheme !== 'file' || event.textEditor.document.languageId !== "java") return; - if (event.selections.length === 0) return; - onSelectionChange(event); - }) - ); -} - -/** - * Handles active file change events - * @param editor The active text editor - */ -export async function onActiveFileChange(editor: vscode.TextEditor) { - extension.file = normalizeFilePath(editor.document.uri.fsPath); - extension.webview?.sendMessage({ type: "file", file: extension.file }); - await updateStateMachine(editor.document); - handleContextUpdate(editor.selection); -} - -/** - * Handles selection change events - * @param event The selection change event - */ -export async function onSelectionChange(event: vscode.TextEditorSelectionChangeEvent) { - // debounce selection changes - if (selectionTimeout) clearTimeout(selectionTimeout); - selectionTimeout = setTimeout(() => { - handleContextUpdate(event.selections[0]); - }, SELECTION_DEBOUNCE_MS); -} - -/** - * Updates the current selection and context - * @param selection The new selection - */ -function handleContextUpdate(selection: vscode.Selection) { - if (!extension.file) return; - - const normalizedRange = normalizeRange(toRange(selection)); - extension.currentSelection = normalizedRange; - - if (!extension.context) return; - - const { allVars, visibleVars } = getSelectionContextVariables(extension.file, normalizedRange); - extension.context.visibleVars = visibleVars; - extension.context.allVars = allVars; - updateErrorAtCursor(); - extension.webview?.sendMessage({ type: "context", context: extension.context, errorAtCursor: extension.errorAtCursor }); -} \ No newline at end of file diff --git a/client/src/services/hover.ts b/client/src/services/hover.ts deleted file mode 100644 index e9f6fd08..00000000 --- a/client/src/services/hover.ts +++ /dev/null @@ -1,124 +0,0 @@ -import * as vscode from 'vscode'; -import { extension } from '../state'; -import type { LJMethod, LJVariable } from '../types/context'; -import { getSelectionContextVariables } from './context'; -import { getOriginalVariableName, normalizeFilePath } from '../utils/utils'; -import { definitionMatchesClass, getDefinitions } from './definition'; -import { isExtensionRunning } from '../extension'; - -/** - * Initializes hover provider for LiquidJava diagnostics - */ -export function registerHover() { - vscode.languages.registerHoverProvider('java', { - async provideHover(document, position) { - if (!isExtensionRunning()) return null; - - const hoverContent = new vscode.MarkdownString(); - hoverContent.isTrusted = true; - - const variable = getHoveredVariable(document, position); - if (variable && variable.mainRefinement && variable.mainRefinement !== 'true') - hoverContent.appendCodeblock(formatRefinement(variable.mainRefinement), 'java'); - else { - const method = await getHoveredMethod(document, position); - if (method) { - hoverContent.appendCodeblock(formatMethodHover(method), 'java'); - const link = formatMethodLocationLink(method); - if (link) hoverContent.appendMarkdown(`\n\n${link}`); - } - } - - if (hoverContent.value.length === 0) return null; - return new vscode.Hover(hoverContent); - } - }); -} - -function getHoveredVariable(document: vscode.TextDocument, position: vscode.Position): LJVariable | null { - if (!extension.context) return null; - - const wordRange = document.getWordRangeAtPosition(position, /[#]?[A-Za-z_][A-Za-z0-9_#]*/); - if (!wordRange) return null; - - const hoveredWord = document.getText(wordRange); - const file = normalizeFilePath(document.uri.fsPath); - - // we need to use single point cursor position after variable to get all variables until that point - const positionAfterVariable = { - lineStart: wordRange.end.line, - colStart: wordRange.end.character, - lineEnd: wordRange.end.line, - colEnd: wordRange.end.character - }; - const { allVars } = getSelectionContextVariables(file, positionAfterVariable); - return allVars.find(variable => getOriginalVariableName(variable.name) === hoveredWord) || null; -} - -async function getHoveredMethod(document: vscode.TextDocument, position: vscode.Position): Promise { - if (!extension.context) return null; - - const wordRange = document.getWordRangeAtPosition(position, /[A-Za-z_][A-Za-z0-9_]*/); - if (!wordRange) return null; - - const hoveredWord = document.getText(wordRange); - const file = normalizeFilePath(document.uri.fsPath); - const methods = extension.context.methods.filter(method => methodNameMatches(method, hoveredWord)); - - const definitions = await getDefinitions(document, position); - const resolvedMethod = methods.find(method => definitions.some(definition => definitionMatchesClass(definition, method.targetClass))); - if (resolvedMethod) return resolvedMethod; - - const receiver = document.lineAt(wordRange.start.line).text - .slice(0, wordRange.start.character) - .match(/([A-Za-z_][A-Za-z0-9_]*)\s*\.\s*$/)?.[1]; - if (!receiver) return null; - const receiverVariable = [...(extension.context?.globalVars || []), ...(extension.context?.localVars || [])] - .find(variable => - getOriginalVariableName(variable.name) === receiver && - (!variable.position || variable.position.file === file && isBefore(variable.position, wordRange.start)) - ); - if (!receiverVariable) return null; - - return methods.find(method => typeMatchesTargetClass(receiverVariable.type, method.targetClass)) || null; -} - -function methodNameMatches(method: LJMethod, hoveredWord: string): boolean { - return method.name === hoveredWord || method.name.endsWith(`.${hoveredWord}`); -} - -function typeMatchesTargetClass(type: string, targetClass: string): boolean { - return type === targetClass || targetClass.endsWith(`.${type}`) || type.endsWith(`.${targetClass}`); -} - -function isBefore(range: { lineStart: number; colStart: number }, position: vscode.Position): boolean { - return range.lineStart < position.line || range.lineStart === position.line && range.colStart < position.character; -} - -function formatRefinement(refinement: string): string { - return `@Refinement("${refinement}")`; -} - -function formatStateRefinement(from: string | null, to: string | null): string { - return `@StateRefinement(${[from && `from="${from}"`, to && `to="${to}"`].filter(Boolean).join(', ')})`; -} - -function formatMethodHover(method: LJMethod): string { - return [ - method.returnRefinement && method.returnRefinement !== 'true' && formatRefinement(method.returnRefinement), - ...method.parameters - .filter(p => p.mainRefinement && p.mainRefinement !== 'true') - .map(p => `${formatRefinement(p.mainRefinement)} ${p.type} ${p.name}`), - ...method.stateRefinements - .filter(s => s.from || s.to) - .map(s => formatStateRefinement(s.from, s.to)) - ].filter(Boolean).join('\n'); -} - -function formatMethodLocationLink(method: LJMethod): string | null { - if (!method.position?.file) return null; - const uri = vscode.Uri.file(method.position.file).with({ - fragment: `L${method.position.lineStart + 1},${method.position.colStart + 1}` - }); - return `[Go to Refinements Definition](${uri.toString()})`; -} diff --git a/client/src/services/logger.ts b/client/src/services/logger.ts deleted file mode 100644 index 1e6995cb..00000000 --- a/client/src/services/logger.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as vscode from "vscode"; -import { OutputChannel } from "vscode"; -import { extension } from "../state"; - -enum LogLevel { - INFO = "INFO", - ERROR = "ERROR", -} - -enum LogSource { - CLIENT = "CLIENT", - SERVER = "SERVER", -} - -/** - * Logs a message to the specified output channel - * @param channel The output channel to log to - * @param msg The message to log - * @param level The log level - * @param source The log source - * @returns - */ -function logMessage(channel: OutputChannel, msg: string, level: LogLevel, source: LogSource) { - if (!channel) return; - const timestamp = new Date().toISOString().split("T")[1].split(".")[0]; - channel.appendLine(`${timestamp} [${source}] [${level}] ${msg}`); -} - -export type LiquidJavaLogger = { - client: { - info: (msg: string) => void; - error: (msg: string) => void; - }; - server: { - info: (msg: string) => void; - error: (msg: string) => void; - }; - dispose: () => void; -}; - -/** - * Creates a logger for the LiquidJava extension - * @param channel The output channel to log to - * @returns A LiquidJavaLogger instance with client and server log methods - */ -export function createLogger(channel: OutputChannel): LiquidJavaLogger { - let disposed = false; - - const log = (channel: OutputChannel, msg: string, level: LogLevel, source: LogSource) => { - if (disposed) { - // channel was disposed, fallback to console.log - console.log(msg); - return; - } - logMessage(channel, msg, level, source); - } - - return { - client: { - info: msg => log(channel, msg, LogLevel.INFO, LogSource.CLIENT), - error: msg => log(channel, msg, LogLevel.ERROR, LogSource.CLIENT), - }, - server: { - info: msg => log(channel, msg, LogLevel.INFO, LogSource.SERVER), - error: msg => log(channel, msg, LogLevel.ERROR, LogSource.SERVER), - }, - dispose: () => disposed = true, - }; -} - -/** - * Initializes logging for the extension with an output channel - * @param context The extension context - */ -export function registerLogger(context: vscode.ExtensionContext) { - const outputChannel = vscode.window.createOutputChannel("LiquidJava"); - extension.logger = createLogger(outputChannel); - context.subscriptions.push(outputChannel); - context.subscriptions.push(extension.logger); - context.subscriptions.push(vscode.commands.registerCommand("liquidjava.showLogs", () => outputChannel.show(true))); -} \ No newline at end of file diff --git a/client/src/services/state-machine.ts b/client/src/services/state-machine.ts deleted file mode 100644 index 9969f2e0..00000000 --- a/client/src/services/state-machine.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as vscode from "vscode"; -import { extension } from "../state"; -import { LJStateMachine } from "../types/fsm"; - -/** - * Requests the state machine for the given document from the language server - * @param document The text document - */ -export async function updateStateMachine(document: vscode.TextDocument) { - const sm = await extension.client?.sendRequest("liquidjava/fsm", { uri: document.uri.toString() }); - - // dont update diagram if it hasnt changed to a new one - if (!sm || JSON.stringify(sm) === JSON.stringify(extension.stateMachine)) return; - extension.stateMachine = sm; - extension.webview?.sendMessage({ type: "fsm", sm }); -} diff --git a/client/src/services/status-bar.ts b/client/src/services/status-bar.ts deleted file mode 100644 index 5b19d51d..00000000 --- a/client/src/services/status-bar.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as vscode from "vscode"; -import { ExtensionStatus, extension } from "../state"; - -const icons = { - loading: "$(sync~spin)", - stopped: "$(circle-slash)", - passed: "$(check)", - failed: "$(x)", - crashed: "$(x)", -}; - -const statusText = { - loading: "Loading", - stopped: "Stopped", - passed: "Verification passed", - failed: "Verification failed", - crashed: "Crashed", -}; - -/** - * Initializes the status bar for the extension - * @param context The extension context - */ -export function registerStatusBar(context: vscode.ExtensionContext) { - extension.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); - extension.statusBar.command = "liquidjava.showCommands"; - updateStatusBar("loading", true); - extension.statusBar.show(); - context.subscriptions.push(extension.statusBar); -} - -/** - * Updates the status bar with the current state - * @param status The current status ("loading", "stopped", "passed", "failed", "crashed") - * @param notifyWebview Whether the webview should reflect this status update. - */ -export function updateStatusBar(status: ExtensionStatus, notifyWebview = status !== "loading") { - if (notifyWebview) { - extension.status = status; - extension.webview?.sendMessage({ type: "status", status }); - } - const color = status === "stopped" || status === "crashed" ? "errorForeground" : "statusBar.foreground"; - if (!extension.statusBar) return; - extension.statusBar.color = new vscode.ThemeColor(color); - extension.statusBar.text = icons[status] + " LiquidJava"; - extension.statusBar.tooltip = statusText[status]; -} diff --git a/client/src/services/webview.ts b/client/src/services/webview.ts deleted file mode 100644 index 787f6567..00000000 --- a/client/src/services/webview.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as vscode from "vscode"; -import { LiquidJavaWebviewProvider } from "../webview/provider"; -import { extension } from "../state"; -import type { DiagnosticRevealTarget } from "../types/diagnostics"; - -/** - * Initializes the webview panel for the extension - * @param context The extension context - */ -export function registerWebview(context: vscode.ExtensionContext) { - extension.webview = new LiquidJavaWebviewProvider(context.extensionUri); - let pendingDiagnosticReveal: DiagnosticRevealTarget | undefined; - - // webview provider - context.subscriptions.push( - vscode.window.registerWebviewViewProvider(LiquidJavaWebviewProvider.viewType, extension.webview) - ); - // show view command - context.subscriptions.push( - vscode.commands.registerCommand("liquidjava.showView", async (diagnostic?: DiagnosticRevealTarget) => { - const isVisible = extension.webview?.isVisible(); - await vscode.commands.executeCommand("liquidJavaView.focus"); - if (!diagnostic) return; - - if (isVisible) { - extension.webview?.sendMessage({ type: "revealDiagnostic", diagnostic }); - } else { - pendingDiagnosticReveal = diagnostic; - } - }) - ); - // listen for messages from the webview - context.subscriptions.push( - extension.webview.onDidReceiveMessage(message => { - if (message.type === "ready") { - if (extension.file) extension.webview?.sendMessage({ type: "file", file: extension.file }); - if (extension.diagnostics) extension.webview?.sendMessage({ type: "diagnostics", diagnostics: extension.diagnostics }); - if (extension.context) extension.webview?.sendMessage({ type: "context", context: extension.context , errorAtCursor: extension.errorAtCursor }); - if (extension.stateMachine) extension.webview?.sendMessage({ type: "fsm", sm: extension.stateMachine }); - if (extension.status) extension.webview?.sendMessage({ type: "status", status: extension.status }); - if (pendingDiagnosticReveal) { - extension.webview?.sendMessage({ type: "revealDiagnostic", diagnostic: pendingDiagnosticReveal }); - pendingDiagnosticReveal = undefined; - } - } - }) - ); -} diff --git a/client/src/state.ts b/client/src/state.ts index f47d5103..f973fae9 100644 --- a/client/src/state.ts +++ b/client/src/state.ts @@ -1,34 +1,11 @@ -import * as vscode from "vscode"; -import * as net from "net"; import * as child_process from "child_process"; +import * as net from "net"; import { LanguageClient } from "vscode-languageclient/node"; -import { LiquidJavaLogger } from "./services/logger"; -import { LiquidJavaWebviewProvider } from "./webview/provider"; -import type { LJDiagnostic, RefinementMismatchError } from "./types/diagnostics"; -import type { LJStateMachine } from "./types/fsm"; -import { LJContext, Range } from "./types/context"; - -export type ExtensionStatus = "loading" | "stopped" | "passed" | "failed" | "crashed"; -export class ExtensionState { - // server/client state +export type ExtensionState = { serverProcess?: child_process.ChildProcess; client?: LanguageClient; socket?: net.Socket; - - // ui state - logger?: LiquidJavaLogger; - statusBar?: vscode.StatusBarItem; - webview?: LiquidJavaWebviewProvider; - status?: ExtensionStatus; - - // application state - file?: string; - diagnostics?: LJDiagnostic[]; - stateMachine?: LJStateMachine; - context?: LJContext; - currentSelection?: Range; - errorAtCursor?: RefinementMismatchError; -} +}; -export const extension = new ExtensionState(); +export const extension: ExtensionState = {}; diff --git a/client/src/types/context.ts b/client/src/types/context.ts deleted file mode 100644 index 3c5d4d23..00000000 --- a/client/src/types/context.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { SourcePosition } from "./diagnostics"; - -// Type definitions used for LiquidJava context information - -export type LJVariable = { - name: string; - internalName: string; - type: string; - refinement: string; - mainRefinement: string; - position: SourcePosition| null; - annotationPosition: SourcePosition | null; -} - -export type LJGhost = { - name: string; - qualifiedName: string; - returnType: string; - parameterTypes: string[]; - refinement: string; - isState: boolean; - file: string; -} - -export type LJAlias = { - name: string; - parameters: string[]; - types: string[]; - predicate: string; -} - -export type LJMethodStateRefinement = { - from: string | null; - to: string | null; -} - -export type LJMethod = { - name: string; - targetClass: string; - returnRefinement: string; - parameters: LJVariable[]; - stateRefinements: LJMethodStateRefinement[]; - position: SourcePosition | null; -} - -export type LJContext = { - localVars: LJVariable[]; - globalVars: LJVariable[]; - ghosts: LJGhost[]; - aliases: LJAlias[]; - methods: LJMethod[]; - visibleVars: LJVariable[]; // variables visible in the current selection - allVars: LJVariable[]; // instance vars + global vars + vars in scope - fileScopes: Record; // file -> scopes -} - -export type Range = { - lineStart: number; - colStart: number; - lineEnd: number; - colEnd: number; -} diff --git a/client/src/types/diagnostics.ts b/client/src/types/diagnostics.ts deleted file mode 100644 index 1ed3f32f..00000000 --- a/client/src/types/diagnostics.ts +++ /dev/null @@ -1,125 +0,0 @@ -import type { Range } from './context'; -import type { VCSimplificationResult } from './vc-implications'; - -// Type definitions used for LiquidJava diagnostics - -export type SourcePosition = Range & { - file: string | null; -} - -export type PlacementInCode = { - text: string; - position: SourcePosition | null; -} - -export type TranslationTable = Record; - -export type LJDiagnostic = LJError | LJWarning; - -export type LJError = CustomError | IllegalConstructorTransitionError | - InvalidRefinementError | NotFoundError | RefinementError | StateConflictError | - StateRefinementError | SyntaxError | ArgumentMismatchError; - -export type LJWarning = CustomWarning | ExternalClassNotFoundWarning | ExternalMethodNotFoundWarning | UnsatisfiableRefinementWarning; - -type BaseDiagnostic = { - title: string; - message: string; - details: string; - file: string; - position: SourcePosition | null; -} - -export type CustomError = BaseDiagnostic & { - category: 'error'; - type: 'custom-error'; -} - -export type IllegalConstructorTransitionError = BaseDiagnostic & { - category: 'error'; - type: 'illegal-constructor-transition-error'; -} - -export type InvalidRefinementError = BaseDiagnostic & { - category: 'error'; - type: 'invalid-refinement-error'; - refinement: string; -} - -export type NotFoundError = BaseDiagnostic & { - category: 'error'; - type: 'not-found-error'; - translationTable: TranslationTable; - name: string; - kind: string; -} - -export type RefinementError = BaseDiagnostic & { - category: 'error'; - type: 'refinement-error'; - translationTable: TranslationTable; - expected: string; - found: VCSimplificationResult; - customMessage: string; - counterexample: string; -} - -export type StateConflictError = BaseDiagnostic & { - category: 'error'; - type: 'state-conflict-error'; - translationTable: TranslationTable; - state: string; -} - -export type StateRefinementError = BaseDiagnostic & { - category: 'error'; - type: 'state-refinement-error'; - translationTable: TranslationTable; - expected: string; - found: VCSimplificationResult; - customMessage: string; -} - -export type ArgumentMismatchError = BaseDiagnostic & { - category: 'error'; - type: 'argument-mismatch-error'; - refinement: string; -} - -export type SyntaxError = BaseDiagnostic & { - category: 'error'; - type: 'syntax-error'; - refinement: string; -} - -export type CustomWarning = BaseDiagnostic & { - category: 'warning'; - type: 'custom-warning'; -} - -export type ExternalClassNotFoundWarning = BaseDiagnostic & { - category: 'warning'; - type: 'external-class-not-found-warning'; - className: string; -} - -export type ExternalMethodNotFoundWarning = BaseDiagnostic & { - category: 'warning'; - type: 'external-method-not-found-warning'; - signature: string; - className: string; - overloads: string[]; -} - -export type UnsatisfiableRefinementWarning = BaseDiagnostic & { - category: 'warning'; - type: 'unsatisfiable-refinement-warning'; - refinement: string; -} - -export type RefinementMismatchError = RefinementError | StateRefinementError; - -export type DiagnosticRevealTarget = { - file: string; - position: SourcePosition; -} diff --git a/client/src/types/fsm.ts b/client/src/types/fsm.ts deleted file mode 100644 index 1385fe69..00000000 --- a/client/src/types/fsm.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Type definitions used for representing finite state machines - -export type LJStateMachine = { - className: string; - initialTransitions: { to: string; postCond?: string | null }[]; - states: string[]; - transitions: { from: string; to: string; label: string; preCond?: string | null; postCond?: string | null }[]; -}; diff --git a/client/src/types/vc-implications.ts b/client/src/types/vc-implications.ts deleted file mode 100644 index a6750edb..00000000 --- a/client/src/types/vc-implications.ts +++ /dev/null @@ -1,12 +0,0 @@ -export type VCImplication = { - name: string | null; - type: string | null; - predicate: string; - next: VCImplication | null; -} - -export type VCSimplificationResult = { - implication: VCImplication; - origin: VCSimplificationResult | null; - simplification: string | null; -} diff --git a/client/src/utils/constants.ts b/client/src/utils/constants.ts index 60a53b09..faf92f05 100644 --- a/client/src/utils/constants.ts +++ b/client/src/utils/constants.ts @@ -2,30 +2,3 @@ export const SERVER_JAR = "language-server-liquidjava.jar"; export const JAVA_BINARY = "java"; export const DEBUG_MODE = false; export const DEBUG_PORT = 50000; -export const SELECTION_DEBOUNCE_MS = 250; -export const LIQUIDJAVA_SCOPES = [ - "source.liquidjava keyword.other.liquidjava", - "source.liquidjava entity.name.function.liquidjava", - "source.liquidjava storage.type.primitive.liquidjava", - "source.liquidjava entity.name.type.liquidjava", - "source.liquidjava entity.name.type.class.liquidjava", - "source.liquidjava entity.name.type.externalref.liquidjava", - "source.liquidjava variable.other.liquidjava", - "source.liquidjava keyword.operator.liquidjava", - "source.liquidjava constant.language.boolean.liquidjava", - "source.liquidjava constant.numeric.liquidjava", - "keyword.operator.liquidjava", - "constant.language.boolean.liquidjava", - "constant.numeric.liquidjava", -]; -export const LIQUIDJAVA_ANNOTATIONS = [ - "Refinement", - "RefinementAlias", - "RefinementPredicate", - "StateSet", - "Ghost", - "StateRefinement", - "ExternalRefinementsFor", -] -export const LIQUIDJAVA_ANNOTATION_START = new RegExp(`@(liquidjava\\.specification\\.)?(${LIQUIDJAVA_ANNOTATIONS.join("|")})\\s*\\(`, "g"); -export type LJAnnotation = "Refinement" | "RefinementAlias" | "RefinementPredicate" | "StateSet" | "Ghost" | "StateRefinement" | "ExternalRefinementsFor"; \ No newline at end of file diff --git a/client/src/utils/utils.ts b/client/src/utils/utils.ts index 13a0c6d1..8d403fb1 100644 --- a/client/src/utils/utils.ts +++ b/client/src/utils/utils.ts @@ -2,9 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as net from "net"; import * as child_process from "child_process"; -import * as vscode from "vscode"; import { JAVA_BINARY } from "./constants"; -import { Range } from "../types/context"; /** * Finds the Java executable in the system, either in JAVA_HOME or in PATH @@ -100,7 +98,7 @@ export async function connectToPort( */ export async function killProcess(proc?: child_process.ChildProcess) { return new Promise((resolve, reject) => { - if (!proc || proc.killed || proc.pid === undefined) { + if (!proc || proc.killed || proc.exitCode !== null || proc.pid === undefined) { // already killed resolve(); return; @@ -126,28 +124,7 @@ export async function killProcess(proc?: child_process.ChildProcess) { }); } -export function getSimpleName(qualifiedName: string): string { - const parts = qualifiedName.split("."); - return parts[parts.length - 1] || qualifiedName; -} - -export function getOriginalVariableName(name: string): string { - if (name.startsWith("this#")) return name.replace(/^this#/, ''); - if (name.startsWith("#")) return name.split("_")[0].replace(/^#/, ''); - return name; - -} - export function normalizeFilePath(fsPath: string): string { // uppercase windows drive letter (c:\ -> C:\) return path.normalize(fsPath).replace(/^([a-z]):\\/, (_, drive) => drive.toUpperCase() + ':\\'); } - -export function toRange(selection: vscode.Selection | vscode.Range): Range { - return { - lineStart: selection.start.line, - colStart: selection.start.character, - lineEnd: selection.end.line, - colEnd: selection.end.character - }; -} diff --git a/client/src/webview/clipboard.ts b/client/src/webview/clipboard.ts deleted file mode 100644 index 8a400254..00000000 --- a/client/src/webview/clipboard.ts +++ /dev/null @@ -1,22 +0,0 @@ -const COPY_BUTTON_RESET_MS = 2000; - -export async function copyToClipboard(button: HTMLButtonElement, text: string) { - const originalTitle = button.getAttribute('title'); - - try { - button.disabled = true; - await navigator.clipboard.writeText(text); - button.setAttribute('title', 'Copied!'); - } catch (e) { - button.setAttribute('title', 'Copy failed'); - } finally { - setTimeout(() => { - if (originalTitle !== null) { - button.setAttribute('title', originalTitle); - } else { - button.removeAttribute('title'); - } - button.disabled = false; - }, COPY_BUTTON_RESET_MS); - } -} diff --git a/client/src/webview/diagnostic-reveal.ts b/client/src/webview/diagnostic-reveal.ts deleted file mode 100644 index 2a95ef6e..00000000 --- a/client/src/webview/diagnostic-reveal.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { DiagnosticRevealTarget, LJDiagnostic } from "../types/diagnostics"; - -export function getDiagnosticRevealTargetKey(target: DiagnosticRevealTarget): string { - const { lineStart, colStart, lineEnd, colEnd } = target.position; - return `${target.file}:${lineStart}:${colStart}-${lineEnd}:${colEnd}`; -} - -export function getDiagnosticRevealTarget(diagnostic: LJDiagnostic): DiagnosticRevealTarget | undefined { - if (!diagnostic.position) return undefined; - return { - file: diagnostic.position.file || diagnostic.file, - position: diagnostic.position - }; -} - -export function getDiagnosticRevealTargetFromKey(value?: string | null): DiagnosticRevealTarget | undefined { - const match = value?.match(/^(.*):(\d+):(\d+)-(\d+):(\d+)$/); - if (!match) return undefined; - - const [, file, lineStart, colStart, lineEnd, colEnd] = match; - return { - file, - position: { - file, - lineStart: parseInt(lineStart, 10), - colStart: parseInt(colStart, 10), - lineEnd: parseInt(lineEnd, 10), - colEnd: parseInt(colEnd, 10) - } - }; -} diff --git a/client/src/webview/diagram.ts b/client/src/webview/diagram.ts deleted file mode 100644 index 5683c02f..00000000 --- a/client/src/webview/diagram.ts +++ /dev/null @@ -1,243 +0,0 @@ -import type { LJStateMachine } from "../types/fsm"; -import { copyToClipboard } from "./clipboard"; - -// constants -const MIN_ZOOM = 0.2; -const MAX_ZOOM = 5; -const ZOOM_BUTTON_FACTOR = 1.5; -const SCROLL_ZOOM_IN_FACTOR = 1.05; -const SCROLL_ZOOM_OUT_FACTOR = 0.95; - -// state variables -let zoomLevel = 1; -let panX = 0; -let panY = 0; -let isPanning = false; -let startX = 0; -let startY = 0; - -/** - * Converts a StateMachine object to a Mermaid state diagram string - * @param sm - * @returns Mermaid diagram string - */ -export function createMermaidDiagram(sm: LJStateMachine | undefined, orientation: "LR" | "TB", showConditions = false): string { - if (!sm) return ''; - - const lines: string[] = []; - - // header - lines.push('---'); - lines.push(`title: ${sm.className}`); - lines.push('---'); - lines.push('stateDiagram-v2'); - lines.push(` direction ${orientation}`); - - // initial transitions - sm.initialTransitions.forEach(transition => { - const label = getInitialTransitionLabel(transition.postCond, showConditions); - lines.push(` [*] --> ${transition.to}${label ? ` : ${label}` : ''}`); - }); - - // group transitions by from/to states and merge labels - const transitionMap = new Map(); - sm.transitions.forEach(transition => { - const label = getTransitionLabel(transition.label, transition.preCond, transition.postCond, showConditions); - const key = `${transition.from}|${transition.to}`; - if (!transitionMap.has(key)) transitionMap.set(key, []); - transitionMap.get(key)?.push(label); - }); - - // add transitions - transitionMap.forEach((labels, key) => { - const [from, to] = key.split('|'); - const mergedLabel = labels.join('
'); - lines.push(` ${from} --> ${to} : ${mergedLabel}`); - }); - - return lines.join('\n'); -} - -function getTransitionLabel(label: string, preCond?: string | null, postCond?: string | null, showConditions = false): string { - if (!showConditions) return escapeMermaidLabel(label); - return [ - getConditionLabel('pre', preCond), - escapeMermaidLabel(label), - getConditionLabel('post', postCond) - ].filter(Boolean).join('
'); -} - -function getInitialTransitionLabel(postCond?: string | null, showConditions = false): string { - return showConditions ? getConditionLabel('post', postCond) : ''; -} - -function getConditionLabel(kind: 'pre' | 'post', cond?: string | null): string { - if (!cond) return ''; - - return `${escapeMermaidLabel(cond)}`; -} - -function escapeMermaidLabel(label: string): string { - return label.replace(/&/g, '&').replace(/"/g, '\\"').replace(//g, '>'); -} - -/** - * Renders Mermaid diagrams in the document - * @param document The document object - * @param window The window object - */ -export async function renderMermaidDiagram(document: any, window: any) { - const mermaid = (window as any).mermaid; - if (!mermaid) return; - - const mermaidElements = document.querySelectorAll('.mermaid'); - if (mermaidElements.length === 0) return; - - try { - await mermaid.run({ nodes: mermaidElements }); - applyTransform(document); - registerPanListeners(document); - const diagramContainer = document.querySelector('.diagram-container') as HTMLElement | null; - if (diagramContainer) diagramContainer.style.minHeight = ''; - } catch (e) { - console.error('Failed to render Mermaid diagram:', e); - } -} - -/** - * Resets zoom and pan to default values - * @param document The document object - */ -export function zoomIn(document: any) { - const container = document.querySelector('.diagram-container') as any; - if (!container) return; - - // get positions - const rect = container.getBoundingClientRect(); - const centerX = rect.width / 2; - const centerY = rect.height / 2; - const beforeX = (centerX - panX) / zoomLevel; - const beforeY = (centerY - panY) / zoomLevel; - - // apply zoom - const newZoom = Math.min(zoomLevel * ZOOM_BUTTON_FACTOR, MAX_ZOOM); - panX = centerX - beforeX * newZoom; - panY = centerY - beforeY * newZoom; - zoomLevel = newZoom; - applyTransform(document); -} - -/** - * Zooms out the diagram - * @param document The document object - */ -export function zoomOut(document: any) { - const container = document.querySelector('.diagram-container') as any; - if (!container) return; - - // get positions - const rect = container.getBoundingClientRect(); - const centerX = rect.width / 2; - const centerY = rect.height / 2; - const beforeX = (centerX - panX) / zoomLevel; - const beforeY = (centerY - panY) / zoomLevel; - - // apply zoom - const newZoom = Math.max(zoomLevel / ZOOM_BUTTON_FACTOR, MIN_ZOOM); - panX = centerX - beforeX * newZoom; - panY = centerY - beforeY * newZoom; - zoomLevel = newZoom; - applyTransform(document); -} - -/** - * Resets zoom and pan to default values - * @param document The document object - */ -export function resetZoom(document: any) { - zoomLevel = 1; - panX = 0; - panY = 0; - applyTransform(document); -} - -/** - * Applies the current zoom and pan transform to the diagram - * @param document The document object - */ -export function applyTransform(document: any) { - const wrapper = document.getElementById('diagram-wrapper'); - if (!wrapper) return; - wrapper.style.transform = `matrix(${zoomLevel}, 0, 0, ${zoomLevel}, ${panX}, ${panY})`; - -} - -/** - * Sets up pan event listeners to move in the diagram - * @param document The document object - */ -export function registerPanListeners(document: any) { - const container = document.querySelector('.diagram-container') as any; - if (!container) return; - - const onMouseDown = (e: any) => { - const target = e.target as any; - if (target.tagName === 'A' || target.tagName === 'BUTTON') return; - - e.preventDefault(); - isPanning = true; - startX = e.clientX - panX; - startY = e.clientY - panY; - container.style.cursor = 'grabbing'; - }; - - const onMouseMove = (e: any) => { - if (!isPanning) return; - e.preventDefault(); - panX = e.clientX - startX; - panY = e.clientY - startY; - applyTransform(document); - }; - - const onMouseUp = () => { - if (!isPanning) return; - isPanning = false; - container.style.cursor = 'grab'; - }; - - const onMouseLeave = () => { - if (!isPanning) return; - isPanning = false; - container.style.cursor = 'grab'; - }; - - const onWheel = (e: any) => { - e.preventDefault(); - - // get positions - const rect = container.getBoundingClientRect(); - const mouseX = e.clientX - rect.left; - const mouseY = e.clientY - rect.top; - const beforeX = (mouseX - panX) / zoomLevel; - const beforeY = (mouseY - panY) / zoomLevel; - - // apply zoom - const delta = e.deltaY > 0 ? SCROLL_ZOOM_OUT_FACTOR : SCROLL_ZOOM_IN_FACTOR; - const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoomLevel * delta)); - panX = mouseX - beforeX * newZoom; - panY = mouseY - beforeY * newZoom; - zoomLevel = newZoom; - applyTransform(document); - }; - - // add event listeners - container.addEventListener('mousedown', onMouseDown); - container.addEventListener('mouseleave', onMouseLeave); - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - container.addEventListener('wheel', onWheel, { passive: false }); -} - -export async function copyDiagramToClipboard(target: any, diagram: string) { - await copyToClipboard(target, diagram); -} diff --git a/client/src/webview/highlighting.ts b/client/src/webview/highlighting.ts deleted file mode 100644 index 03102879..00000000 --- a/client/src/webview/highlighting.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as liquidJavaGrammar from "../../syntaxes/liquidjava.json"; -import { escapeHtml } from "./utils"; - -type GrammarPattern = { - match?: string; - name?: string; -}; - -type GrammarRepository = Record; - -type HighlightRule = { - regex: RegExp; - scope: string; -}; - -type ScopeColorRule = { - scopes: string[]; - color: string; -}; - -const repository = liquidJavaGrammar.repository as GrammarRepository; -const patterns = (name: string): GrammarPattern[] => repository[name]?.patterns || []; - -const expressionPatterns: GrammarPattern[] = [ - { match: "\\b(return|break|continue|if|else|switch|case|default|for|while|do|try|catch|finally|throw|throws|new)\\b", name: "keyword.control.liquidjava.webview" }, - ...patterns("keywords"), - ...patterns("functions"), - ...patterns("operators"), - { match: "\\b[a-zA-Z_][a-zA-Z0-9_#⁰¹²³⁴⁵⁶⁷⁸⁹]*(?=\\s*\\()", name: "entity.name.function.liquidjava.webview" }, - { match: "\\b[A-Z][a-zA-Z0-9_]*(?=\\s*\\()", name: "entity.name.function.constructor.liquidjava.webview" }, - ...patterns("qualified-names"), - { match: "\\b(byte|short|long|char|void)\\b", name: "storage.type.primitive.liquidjava.webview" }, - ...patterns("types"), - { match: "\\bnull\\b", name: "constant.language.null.liquidjava.webview" }, - ...patterns("literals"), - { match: "[(){}.,;\\[\\]]", name: "punctuation.separator.liquidjava" }, - { match: "#*[a-zA-Z_][a-zA-Z0-9_#⁰¹²³⁴⁵⁶⁷⁸⁹]*", name: "variable.other.liquidjava" } -]; - -const highlightRules: HighlightRule[] = expressionPatterns - .filter((pattern): pattern is Required => Boolean(pattern.match && pattern.name)) - .map(pattern => ({ - regex: new RegExp(pattern.match, "y"), - scope: pattern.name - })); - -const scopeColorRules: ScopeColorRule[] = [ - { scopes: ["keyword.other", "variable.language.this"], color: "var(--lj-token-keyword)" }, - { scopes: ["keyword.control"], color: "var(--lj-token-control)" }, - { scopes: ["entity.name.function"], color: "var(--lj-token-function)" }, - { scopes: ["keyword.operator"], color: "var(--lj-token-operator)" }, - { scopes: ["punctuation.separator"], color: "var(--lj-token-punctuation)" }, - { scopes: ["storage.type.primitive", "entity.name.type"], color: "var(--lj-token-type)" }, - { scopes: ["constant.numeric"], color: "var(--lj-token-number)" }, - { scopes: ["constant.language.boolean", "constant.language.null"], color: "var(--lj-token-boolean)" }, - { scopes: ["variable.other"], color: "var(--lj-token-identifier)" } -]; - -function colorForScope(scope: string): string { - return scopeColorRules.find(rule => rule.scopes.some(token => scope.includes(token)))?.color - ?? "var(--vscode-editor-foreground)"; -} - -function renderHighlightedContent(expression: string): string { - let html = ""; - let index = 0; - - while (index < expression.length) { - const matchingRule = highlightRules.find(rule => { - rule.regex.lastIndex = index; - return rule.regex.test(expression); - }); - if (!matchingRule) { - html += escapeHtml(expression[index] || ""); - index += 1; - continue; - } - matchingRule.regex.lastIndex = index; - const match = matchingRule.regex.exec(expression); - const content = match?.[0] || expression[index] || ""; - - html += `${escapeHtml(content)}`; - index += content.length; - } - return html; -} - -function renderExpression(expression: string, wrap: boolean): string { - if (!expression) return ""; - - const content = renderHighlightedContent(expression); - return wrap - ? `
${content}
` - : content; -} - -export function renderHighlightedExpression(expression: string): string { - return renderExpression(expression, true); -} - -export function renderHighlightedInlineExpression(expression: string): string { - return renderExpression(expression, false); -} diff --git a/client/src/webview/html.ts b/client/src/webview/html.ts deleted file mode 100644 index 12e6a298..00000000 --- a/client/src/webview/html.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as vscode from "vscode"; -import { getStyles } from "./styles"; - -const MERMAID_CDN = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"; - -/** - * Generates the HTML content for the webview - * @param webview - * @param extensionUri - * @returns HTML string - */ -export function getHtml(webview: vscode.Webview, extensionUri: vscode.Uri): string { - const nonce = Date.now().toString(); - const cspSource = webview.cspSource; - const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, "media", "webview.js")); - const codiconsUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, "media", "codicons", "codicon.css")); - return /*html*/ ` - - - - - - - - - - -
- - - - - `; -} diff --git a/client/src/webview/icons.ts b/client/src/webview/icons.ts deleted file mode 100644 index 367047bd..00000000 --- a/client/src/webview/icons.ts +++ /dev/null @@ -1,23 +0,0 @@ -export function renderCodicon(name: string, className = ""): string { - const classes = ["codicon", `codicon-${name}`, className].filter(Boolean).join(" "); - return ``; -} - -type CodiconButtonOptions = { - id?: string; - className?: string; - title: string; - ariaLabel?: string; - attributes?: string; - disabled?: boolean; -}; - -export function renderCodiconButton(iconName: string, options: CodiconButtonOptions): string { - const classes = ["icon-button", options.className].filter(Boolean).join(" "); - const id = options.id ? ` id="${options.id}"` : ""; - const ariaLabel = ` aria-label="${options.ariaLabel ?? options.title}"`; - const attributes = options.attributes ? ` ${options.attributes}` : ""; - const disabled = options.disabled ? " disabled" : ""; - - return `${renderCodicon(iconName)}`; -} diff --git a/client/src/webview/main.ts b/client/src/webview/main.ts deleted file mode 100644 index 005149de..00000000 --- a/client/src/webview/main.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { getScript } from "./script"; - -// webview entry point - -declare function acquireVsCodeApi(): any; -declare const document: any; -declare const window: any; - -const vscode = acquireVsCodeApi(); -getScript(vscode, document, window); diff --git a/client/src/webview/provider.ts b/client/src/webview/provider.ts deleted file mode 100644 index 1cacfe93..00000000 --- a/client/src/webview/provider.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as vscode from 'vscode'; -import { getHtml } from './html'; -import { highlightRange, openFile } from '../services/editor'; - -/** - * Webview provider for the LiquidJava extension - * Provides an interactive user interface for the LiquidJava diagnostics - */ -export class LiquidJavaWebviewProvider implements vscode.WebviewViewProvider { - public static readonly viewType = "liquidJavaView"; - private view?: vscode.WebviewView; - private messageEmitter = new vscode.EventEmitter(); - public readonly onDidReceiveMessage = this.messageEmitter.event; - - constructor(private readonly extensionUri: vscode.Uri) {} - - resolveWebviewView( - webviewView: vscode.WebviewView, - _context: vscode.WebviewViewResolveContext, - _token: vscode.CancellationToken - ) { - this.view = webviewView; - webviewView.webview.options = { - enableScripts: true, - localResourceRoots: [this.extensionUri] - }; - webviewView.webview.html = this.getHtml(webviewView.webview); - - // listen for messages coming from webview - webviewView.webview.onDidReceiveMessage(message => { - // emit the message to any external listeners - this.messageEmitter.fire(message); - - // handle message - if (message.type === "openFile") { - openFile(message.filePath, message.line, message.character, message.highlightRange); - } else if (message.type === "highlight") { - // highlight the specified range in the current editor - highlightRange(vscode.window.activeTextEditor, message.range); - } - }); - } - - /** - * Sends a message from the client to the webview - * @param message - */ - public sendMessage(message: any) { - this.view?.webview.postMessage(message); - } - - /** - * Checks if the webview is currently visible - * @returns true if the webview is visible, false otherwise - */ - public isVisible(): boolean { - return this.view?.visible ?? false; - } - - /** - * Generates the HTML content for the webview - * @param webview - * @returns HTML string - */ - private getHtml(webview: vscode.Webview): string { - return getHtml(webview, this.extensionUri); - } -} diff --git a/client/src/webview/script.ts b/client/src/webview/script.ts deleted file mode 100644 index afc428ca..00000000 --- a/client/src/webview/script.ts +++ /dev/null @@ -1,400 +0,0 @@ -import { handleVCImplicationStepClick } from "./views/diagnostics/vc-implications"; -import { renderLoading } from "./views/loading"; -import { renderStopped } from "./views/stopped"; -import { renderStateMachineView } from "./views/fsm/fsm"; -import { createMermaidDiagram, renderMermaidDiagram, resetZoom, zoomIn, zoomOut, copyDiagramToClipboard } from "./diagram"; -import type { LJDiagnostic, RefinementMismatchError } from "../types/diagnostics"; -import type { Range } from "../types/context"; -import type { LJStateMachine } from "../types/fsm"; -import type { ExtensionStatus } from "../state"; -import type { NavTab } from "./views/sections"; -import { copyDiagnosticToClipboard, getDisplayDiagnostics, renderDiagnosticsView } from "./views/diagnostics/diagnostics"; -import type { LJContext } from "../types/context"; -import { ContextSectionState, renderContextView } from "./views/context/context"; -import type { DiagnosticRevealTarget } from "../types/diagnostics"; -import { getDiagnosticRevealTargetFromKey, getDiagnosticRevealTargetKey } from "./diagnostic-reveal"; - -type VSCodeApi = { - postMessage(message: unknown): void; -}; - -/** - * Initializes the webview script - * @param vscode - * @param document - * @param window - */ -export function getScript(vscode: VSCodeApi, document: Document, window: Window) { - const root = document.getElementById('root')!; - if (!root) return; - let diagnostics: LJDiagnostic[] | undefined; - let showAllDiagnostics = false; - let currentFile: string; - let stateMachine: LJStateMachine; - let context: LJContext; - let errorAtCursor: RefinementMismatchError; - let selectedTab: NavTab = 'diagnostics'; - let status: ExtensionStatus = 'loading'; - let diagramOrientation: "LR" | "TB" = "TB"; - let showDiagramConditions = false; - let currentDiagram: string = ''; - let revealTimeout: ReturnType | undefined; - const contextSectionState: ContextSectionState = { - aliases: false, - ghosts: false, - vars: true, - }; - - // initial state - root.innerHTML = renderLoading(); - vscode.postMessage({ type: 'ready' }); - - // on click - root.addEventListener('click', (e: MouseEvent) => { - const target = e.target instanceof Element ? e.target : null; - if (!target) return; - const iconButton = target.closest?.('.icon-button'); - if (iconButton && !(iconButton as HTMLButtonElement).disabled) { - iconButton.classList.remove('icon-button-pop'); - void (iconButton as HTMLElement).offsetWidth; - iconButton.classList.add('icon-button-pop'); - } - - // context section toggle - const contextToggleButton = target.closest?.('.context-toggle-btn'); - if (contextToggleButton) { - e.preventDefault(); - e.stopPropagation(); - - const sectionId = contextToggleButton.getAttribute('data-context-toggle'); - if (!sectionId) return; - - const content = document.getElementById(sectionId); - if (!content) return; - - const isExpanded = contextToggleButton.getAttribute('aria-expanded') !== 'false'; - const nextExpanded = !isExpanded; - if (sectionId === 'context-vars') contextSectionState.vars = nextExpanded; - if (sectionId === 'context-ghosts') contextSectionState.ghosts = nextExpanded; - if (sectionId === 'context-aliases') contextSectionState.aliases = nextExpanded; - contextToggleButton.setAttribute('aria-expanded', nextExpanded ? 'true' : 'false'); - content.classList.toggle('collapsed', !nextExpanded); - - const icon = contextToggleButton.querySelector('.context-toggle-icon'); - if (icon) { - icon.classList.toggle('codicon-triangle-down', nextExpanded); - icon.classList.toggle('codicon-triangle-right', !nextExpanded); - } - - return; - } - - // location link click - const locationTarget = target.closest?.('.location-link'); - if (locationTarget) { - e.preventDefault(); - e.stopPropagation(); - - const filePath = locationTarget.getAttribute('data-file'); - const lineAttr = locationTarget.getAttribute('data-line'); - const columnAttr = locationTarget.getAttribute('data-column'); - if (filePath && lineAttr !== null && columnAttr !== null) { - vscode.postMessage({ - type: 'openFile', - filePath, - line: parseInt(lineAttr, 10), - character: parseInt(columnAttr, 10) - }); - } - return; - } - - // reveal failing refinement diagnostic - if (target.classList.contains('diagnostic-reveal-btn')) { - e.preventDefault(); - e.stopPropagation(); - - const revealTarget = getDiagnosticRevealTargetFromKey(target.getAttribute('data-diagnostic-target')); - if (!revealTarget) return; - revealDiagnostic(revealTarget); - return; - } - - const diagnosticContextButton = target.closest?.('.diagnostic-context-btn'); - if (diagnosticContextButton) { - e.preventDefault(); - e.stopPropagation(); - - const revealTarget = getDiagnosticRevealTargetFromKey(diagnosticContextButton.getAttribute('data-diagnostic-target')); - if (!revealTarget) return; - revealContextForDiagnostic(revealTarget); - return; - } - - // VC implication simplification step buttons - const vcImplicationStepButton = target.closest?.('.vc-step-btn'); - if (vcImplicationStepButton) { - e.stopPropagation(); - handleVCImplicationStepClick(vcImplicationStepButton); - return; - } - - // toggle show all diagnostics - if (target.id === 'show-all-button') { - e.stopPropagation(); - showAllDiagnostics = !showAllDiagnostics; - updateView(); - return; - } - - // toggle diagram orientation - if (target.closest?.('#diagram-orientation-btn')) { - e.stopPropagation(); - diagramOrientation = diagramOrientation === "TB" ? "LR" : "TB"; - resetZoom(document); - updateView(); - return; - } - - // toggle diagram conditions - const diagramConditionsButton = target.closest?.('#diagram-conditions-btn'); - if (diagramConditionsButton) { - e.stopPropagation(); - if ((diagramConditionsButton as HTMLButtonElement).disabled) return; - showDiagramConditions = !showDiagramConditions; - updateView(); - return; - } - - // zoom in - if (target.closest?.('#zoom-in-btn')) { - e.stopPropagation(); - zoomIn(document); - return; - } - - // zoom out - if (target.closest?.('#zoom-out-btn')) { - e.stopPropagation(); - zoomOut(document); - return; - } - - // reset zoom - if (target.closest?.('#zoom-reset-btn')) { - e.stopPropagation(); - resetZoom(document); - return; - } - - // copy diagram source - const copyDiagramButton = target.closest?.('#copy-diagram-btn'); - if (copyDiagramButton) { - e.stopPropagation(); - if (!currentDiagram) return - copyDiagramToClipboard(copyDiagramButton, currentDiagram); - return; - } - - // highlight variable - const highlightButton = target.closest?.('.highlight-var-btn'); - if (highlightButton) { - e.stopPropagation(); - - const previousSelected = root.querySelector('.highlight-var-btn.selected'); - if (previousSelected) { - // unselect previous - previousSelected.classList.remove('selected'); - if (previousSelected === highlightButton) { - // remove highlight - vscode.postMessage({ type: 'highlight', range: null }); - return; - } - } - highlightButton.classList.add('selected'); - (highlightButton as HTMLElement).focus(); - highlightButton.scrollIntoView({ block: 'nearest' }); - - const file = highlightButton.getAttribute('data-file'); - const lineStart = parseInt(highlightButton.getAttribute('data-start-line') || '', 10); - const colStart = parseInt(highlightButton.getAttribute('data-start-column') || '', 10); - const lineEnd = parseInt(highlightButton.getAttribute('data-end-line') || '', 10); - const colEnd = parseInt(highlightButton.getAttribute('data-end-column') || '', 10); - if (!file || [lineStart, colStart, lineEnd, colEnd].some(Number.isNaN)) return; - - const range: Range = { lineStart, colStart, lineEnd, colEnd }; - if (file !== currentFile) { - vscode.postMessage({ type: 'openFile', filePath: file, line: lineStart, character: colStart, highlightRange: range }); - } else { - vscode.postMessage({ type: 'highlight', range }) - } - return; - } - - // nav tab click - if (target.classList.contains('nav-tab')) { - e.stopPropagation(); - const tab = target.getAttribute('data-tab') as NavTab; - if (tab && tab !== selectedTab) { - vscode.postMessage({ type: 'highlight', range: null }); - selectedTab = tab; - updateView(); - } - return; - } - - // copy diagnostic - const diagnosticCopyBtn = target.closest?.('.copy-diagnostic-btn'); - if (diagnosticCopyBtn) { - e.preventDefault(); - e.stopPropagation(); - copyDiagnosticToClipboard(diagnosticCopyBtn, getDisplayDiagnostics(diagnostics || [], showAllDiagnostics, currentFile)); - return; - } - }); - - // navigate context variables with the keyboard - window.addEventListener('keydown', (e: KeyboardEvent) => { - if (selectedTab !== 'context' || (e.key !== 'ArrowUp' && e.key !== 'ArrowDown')) return; - - const buttons = Array.from(root.querySelectorAll('#context-vars:not(.collapsed) .highlight-var-btn')); - if (buttons.length === 0) return; - - const selected = root.querySelector('.highlight-var-btn.selected'); - const active = document.activeElement instanceof HTMLElement ? document.activeElement.closest('.highlight-var-btn') : null; - const current = selected || active; - const currentIndex = current ? buttons.indexOf(current) : -1; - const fallbackIndex = e.key === 'ArrowDown' ? 0 : buttons.length - 1; - const nextIndex = currentIndex === -1 - ? fallbackIndex - : Math.max(0, Math.min(buttons.length - 1, currentIndex + (e.key === 'ArrowDown' ? 1 : -1))); - - e.preventDefault(); - e.stopPropagation(); - const highlightButton = buttons[nextIndex]; - const previousSelected = root.querySelector('.highlight-var-btn.selected'); - if (previousSelected) previousSelected.classList.remove('selected'); - - highlightButton.classList.add('selected'); - highlightButton.focus(); - highlightButton.scrollIntoView({ block: 'nearest' }); - - const file = highlightButton.getAttribute('data-file'); - const lineStart = parseInt(highlightButton.getAttribute('data-start-line') || '', 10); - const colStart = parseInt(highlightButton.getAttribute('data-start-column') || '', 10); - const lineEnd = parseInt(highlightButton.getAttribute('data-end-line') || '', 10); - const colEnd = parseInt(highlightButton.getAttribute('data-end-column') || '', 10); - if (!file || [lineStart, colStart, lineEnd, colEnd].some(Number.isNaN)) return; - - const range: Range = { lineStart, colStart, lineEnd, colEnd }; - if (file !== currentFile) { - vscode.postMessage({ type: 'openFile', filePath: file, line: lineStart, character: colStart, highlightRange: range }); - } else { - vscode.postMessage({ type: 'highlight', range }) - } - }); - - // message event listener from extension - window.addEventListener('message', event => { - const msg = event.data; - switch (msg.type) { - case 'status': - status = msg.status as ExtensionStatus; - updateView(); - break; - case 'diagnostics': - diagnostics = msg.diagnostics as LJDiagnostic[]; - if (selectedTab === 'diagnostics') updateView(); - break; - case 'file': - currentFile = msg.file; - if (diagnostics && !showAllDiagnostics && selectedTab === 'diagnostics') updateView(); - break; - case 'fsm': - stateMachine = msg.sm as LJStateMachine; - showDiagramConditions = false; - if (selectedTab === 'fsm') updateView(); - break; - case 'context': - context = msg.context as LJContext; - errorAtCursor = msg.errorAtCursor as RefinementMismatchError; - if (selectedTab === 'context') updateView(); - break; - case 'revealDiagnostic': - revealDiagnostic(msg.diagnostic as DiagnosticRevealTarget); - break; - } - }); - - /** - * Updates the webview content based on the current state - */ - function updateView() { - if (status === 'stopped' || status === 'crashed') { - currentDiagram = ''; - root.innerHTML = renderStopped(status); - return; - } - if (status === 'loading') { - currentDiagram = ''; - root.innerHTML = renderLoading(); - return; - } - - switch (selectedTab) { - case 'diagnostics': - root.innerHTML = diagnostics - ? renderDiagnosticsView(diagnostics, showAllDiagnostics, currentFile) - : renderLoading(); - break; - case 'fsm': { - const diagram = createMermaidDiagram(stateMachine, diagramOrientation, showDiagramConditions); - currentDiagram = diagram; - renderStateMachineView(root, stateMachine, diagram, diagramOrientation, showDiagramConditions); - if (stateMachine) renderMermaidDiagram(document, window); - break; - } - case 'context': - root.innerHTML = renderContextView(context, currentFile, contextSectionState, errorAtCursor); - break; - } - } - - function revealDiagnostic(target: DiagnosticRevealTarget) { - selectedTab = 'diagnostics'; - - const isVisibleInCurrentFile = showAllDiagnostics || !target.file || target.file.toLowerCase() === currentFile?.toLowerCase(); - if (!isVisibleInCurrentFile) { - showAllDiagnostics = true; - } - - updateView(); - const element = Array.from(root.querySelectorAll('.diagnostic-item')).find(item => - item.getAttribute('data-diagnostic-target') === getDiagnosticRevealTargetKey(target) - ); - if (!element) return; - - const previousRevealed = root.querySelector('.diagnostic-item.revealed'); - if (previousRevealed) previousRevealed.classList.remove('revealed'); - if (revealTimeout) clearTimeout(revealTimeout); - - element.classList.add('revealed'); - element.scrollIntoView({ block: 'center', behavior: 'smooth' }); - revealTimeout = setTimeout(() => { - element.classList.remove('revealed'); - revealTimeout = undefined; - }, 1800); - } - - function revealContextForDiagnostic(target: DiagnosticRevealTarget) { - selectedTab = 'context'; - vscode.postMessage({ - type: 'openFile', - filePath: target.file, - line: target.position.lineEnd, - character: target.position.colEnd, - }); - updateView(); - } - -} diff --git a/client/src/webview/styles.ts b/client/src/webview/styles.ts deleted file mode 100644 index 769ab1f9..00000000 --- a/client/src/webview/styles.ts +++ /dev/null @@ -1,886 +0,0 @@ - -/** - * Generates the CSS styles for the webview - * @returns CSS string - */ -export function getStyles(): string { - return /*css*/` - html, - body { - width: 100%; - height: 100%; - margin: 0; - box-sizing: border-box; - scrollbar-gutter: stable both-edges; - } - #root { - width: 100%; - min-height: 100%; - margin: 0; - box-sizing: border-box; - } - *, - *::before, - *::after { - box-sizing: inherit; - } - body { - height: 100%; - padding: 1rem; - font-family: var(--vscode-font-family); - overflow-x: hidden; - overflow-y: auto; - --lj-token-keyword: var(--vscode-symbolIcon-keywordForeground, var(--vscode-editor-foreground)); - --lj-token-control: var(--vscode-debugTokenExpression-name, var(--vscode-symbolIcon-keywordForeground, var(--vscode-editor-foreground))); - --lj-token-function: var(--vscode-symbolIcon-functionForeground, var(--vscode-editor-foreground)); - --lj-token-operator: var(--vscode-editor-foreground); - --lj-token-type: var(--vscode-symbolIcon-classForeground, var(--vscode-editor-foreground)); - --lj-token-string: var(--vscode-debugTokenExpression-string, var(--vscode-editor-foreground)); - --lj-token-number: var(--vscode-debugTokenExpression-number, var(--vscode-editor-foreground)); - --lj-token-boolean: var(--vscode-debugTokenExpression-boolean, var(--vscode-symbolIcon-booleanForeground, var(--vscode-editor-foreground))); - --lj-token-identifier: var(--vscode-debugTokenExpression-name, var(--vscode-editor-foreground)); - --lj-token-punctuation: var(--vscode-editor-foreground); - --lj-state-cond-pre: var(--lj-token-identifier); - --lj-state-cond-post: var(--lj-token-type); - } - body.vscode-light { - --lj-token-keyword: #0000FF; - --lj-token-function: #795E26; - --lj-token-operator: #000000; - --lj-token-type: #267F99; - --lj-token-string: #A31515; - --lj-token-number: #098658; - --lj-token-boolean: #0000FF; - --lj-token-identifier: #001080; - --lj-token-punctuation: #000000; - } - body.vscode-dark { - --lj-token-keyword: #569CD6; - --lj-token-function: #DCDCAA; - --lj-token-operator: #D4D4D4; - --lj-token-type: #4EC9B0; - --lj-token-string: #CE9178; - --lj-token-number: #B5CEA8; - --lj-token-boolean: #569CD6; - --lj-token-identifier: #9CDCFE; - --lj-token-punctuation: #D4D4D4; - } - body.vscode-high-contrast, - body.vscode-high-contrast-light { - --lj-token-keyword: var(--vscode-editor-foreground); - --lj-token-function: var(--vscode-textLink-foreground); - --lj-token-operator: var(--vscode-editor-foreground); - --lj-token-type: var(--vscode-textLink-foreground); - --lj-token-string: var(--vscode-editor-foreground); - --lj-token-number: var(--vscode-editor-foreground); - --lj-token-boolean: var(--vscode-editor-foreground); - --lj-token-identifier: var(--vscode-editor-foreground); - --lj-token-punctuation: var(--vscode-editor-foreground); - } - h2 { - font-weight: bold; - margin: 0; - } - p { - word-wrap: break-word; - overflow-wrap: break-word; - margin: 0.5rem 0; - } - pre { - word-wrap: break-word; - overflow-wrap: break-word; - white-space: pre-wrap; - margin: 0.5rem 0; - padding: 0.5rem; - background-color: var(--vscode-editor-background); - border-radius: 4px; - overflow-x: auto; - } - strong { - display: inline; - margin-bottom: 0.5rem; - } - nav ul { - display: flex; - gap: 1rem; - padding: 0; - margin: 0; - justify-content: center; - } - nav ul li { - padding-right: 1rem; - border-right: 1px solid var(--vscode-panel-border); - } - nav ul li:last-child { - border-right: none; - } - nav { - padding-bottom: 1.5rem; - } - nav button { - color: var(--vscode-foreground); - background: none; - border: none; - text-decoration: none; - cursor: pointer; - padding: 0; - opacity: 0.8; - text-transform: uppercase; - font-size: 11px; - } - nav .selected { - opacity: 1; - text-decoration: underline; - text-decoration-color: var(--vscode-activityBar-activeBorder); - text-underline-offset: 6px; - text-decoration-thickness: 1px; - } - nav button:hover { - opacity: 1; - background: none; - } - .container { - margin: 0; - padding: 0.5rem; - background-color: var(--vscode-editor-background); - border-radius: 4px; - overflow-x: auto; - font-family: var(--vscode-editor-font-family); - font-size: var(--vscode-editor-font-size); - max-width: 100%; - line-height: 1.6; - position: relative; - } - ul { - list-style-type: none; - padding: 0; - margin: 0; - } - .diagnostic-header { - margin: 1rem 0; - } - .diagnostic-item { - background-color: var(--vscode-textCodeBlock-background); - padding: 0.5rem 1rem; - margin-bottom: 1rem; - border-radius: 4px; - position: relative; - } - .codicon { - display: inline-flex; - align-items: center; - justify-content: center; - width: 1em; - height: 1em; - font-size: 1rem; - line-height: 1; - pointer-events: none; - } - .copy-diagnostic-btn, - .diagnostic-context-btn { - position: absolute; - top: 0.5rem; - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.75rem; - height: 1.75rem; - padding: 0; - color: var(--vscode-foreground); - background: transparent; - border: 1px solid transparent; - border-radius: 4px; - opacity: 0.65; - transition: background-color 0.16s ease, border-color 0.16s ease, opacity 0.16s ease, transform 0.16s ease; - } - .copy-diagnostic-btn { - right: 0.5rem; - } - .diagnostic-context-btn { - right: 2.5rem; - } - .copy-diagnostic-btn:hover, - .diagnostic-context-btn:hover { - background: var(--vscode-editor-background); - border-color: var(--vscode-widget-border); - opacity: 1; - } - .copy-diagnostic-btn:disabled, - .diagnostic-context-btn:disabled { - opacity: 0.8; - cursor: default; - } - .icon-button-pop { - animation: icon-button-pop 0.28s ease-out; - } - @keyframes icon-button-pop { - 0% { - transform: scale(0.96); - } - 55% { - transform: scale(1.05); - } - 100% { - transform: scale(1); - } - } - .diagnostic-item.revealed { - outline: 2px solid var(--vscode-focusBorder); - animation: diagnostic-reveal-flash 1.8s ease-out; - } - @keyframes diagnostic-reveal-flash { - 0% { - box-shadow: 0 0 0 0 var(--vscode-focusBorder); - transform: translateX(0); - } - 12% { - box-shadow: 0 0 0 3px var(--vscode-focusBorder); - transform: translateX(3px); - } - 24% { - transform: translateX(0); - } - 55% { - box-shadow: 0 0 0 2px var(--vscode-focusBorder); - } - 100% { - box-shadow: 0 0 0 0 transparent; - transform: translateX(0); - } - } - .error-item { - border-left: 4px solid var(--vscode-editorError-foreground); - } - .warning-item { - border-left: 4px solid var(--vscode-editorWarning-foreground); - } - .section { - margin-bottom: 1rem; - } - .section:last-child { - margin-bottom: 0; - } - .link { - color: var(--vscode-textLink-foreground); - text-decoration: none; - cursor: pointer; - word-break: break-word; - display: inline-block; - max-width: 100%; - } - .link:hover { - text-decoration: underline; - } - .lj-expression, - .lj-expression-code { - font-family: var(--vscode-editor-font-family); - font-size: var(--vscode-editor-font-size); - white-space: pre-wrap; - } - .lj-expression-block { - font-family: var(--vscode-editor-font-family); - font-size: var(--vscode-editor-font-size); - } - .lj-expression-block code, - code.lj-expression-code { - background: transparent !important; - background-color: transparent !important; - } - .lj-token-keyword { - color: var(--lj-token-keyword); - } - .lj-token-function { - color: var(--lj-token-function); - } - .lj-token-operator { - color: var(--lj-token-operator); - } - .lj-token-type { - color: var(--lj-token-type); - } - .lj-token-string { - color: var(--lj-token-string); - } - .lj-token-number { - color: var(--lj-token-number); - } - .lj-token-boolean { - color: var(--lj-token-boolean); - } - .lj-token-identifier { - color: var(--lj-token-identifier); - } - .lj-token-punctuation { - color: var(--lj-token-punctuation); - opacity: 0.8; - } - .clickable { - cursor: pointer; - text-decoration: underline; - text-decoration-style: dotted; - } - .clickable:hover { - font-weight: bold; - } - .vc-container { - display: flex; - flex-direction: column; - gap: 0.375rem; - margin: 0.5rem 0; - } - .vc-step-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - min-width: 0; - padding-bottom: 0.25rem; - border-bottom: 1px solid var(--vscode-widget-border, var(--vscode-panel-border)); - font-family: var(--vscode-font-family); - font-size: 0.8rem; - line-height: 1.25rem; - } - .vc-step-name { - min-width: 0; - overflow: hidden; - color: var(--vscode-descriptionForeground); - font-weight: 600; - text-overflow: ellipsis; - white-space: nowrap; - } - .vc-step-navigation { - display: inline-flex; - align-items: center; - gap: 0.25rem; - flex-shrink: 0; - } - .vc-step-position { - min-width: 2.5rem; - color: var(--vscode-descriptionForeground); - font-variant-numeric: tabular-nums; - text-align: right; - } - .vc-chain { - display: grid; - grid-template-columns: fit-content(40%) minmax(0, 1fr); - row-gap: 0.25rem; - width: 100%; - min-width: 0; - } - .counterexample-container .vc-chain { - display: flex; - flex-direction: column; - gap: 0.25rem; - } - .counterexample-line { - overflow-wrap: anywhere; - } - .vc-line { - display: contents; - } - .vc-binder-cell, - .vc-predicate-cell { - min-width: 0; - padding: 0.0625rem 0.25rem; - overflow-wrap: anywhere; - } - .vc-binder-cell { - min-height: 1.2em; - padding-right: 0.75rem; - color: var(--vscode-descriptionForeground); - white-space: normal; - } - .vc-predicate-cell { - color: var(--vscode-editor-foreground); - } - .vc-predicate-cell:only-child { - grid-column: 1 / -1; - } - .vc-node { - display: inline; - padding: 0; - border: none; - background: none; - color: var(--vscode-editor-foreground); - font: inherit; - text-align: left; - } - .vc-node:hover { - background: none; - } - .vc-change-line .vc-node { - border-radius: 2px; - animation: vc-change-line-fade 1.4s ease-out; - } - .vc-change-fragment { - border-radius: 2px; - animation: vc-change-fragment-fade 1.4s ease-out; - } - @keyframes vc-change-line-fade { - 0% { - background-color: rgba(255, 255, 96, 0.68); - box-shadow: 0 0 0 1px rgba(255, 255, 0, 0.38); - } - 18% { - background-color: rgba(255, 255, 0, 0.4); - box-shadow: 0 0 0 1px rgba(255, 255, 0, 0.2); - } - 100% { - background-color: transparent; - box-shadow: none; - } - } - @keyframes vc-change-fragment-fade { - 0% { - background-color: rgba(255, 255, 96, 0.68); - box-shadow: 0 0 0 1px rgba(255, 255, 0, 0.38); - } - 18% { - background-color: rgba(255, 255, 0, 0.4); - box-shadow: 0 0 0 1px rgba(255, 255, 0, 0.2); - } - 100% { - background-color: transparent; - box-shadow: none; - } - } - @media (prefers-reduced-motion: reduce) { - .vc-change-line .vc-node { - background-color: rgba(255, 255, 0, 0.3); - animation: none; - } - .vc-change-fragment { - background-color: rgba(255, 255, 0, 0.3); - animation: none; - } - } - .vc-binder { - color: var(--vscode-descriptionForeground); - } - .vc-step-controls { - display: inline-flex; - align-items: center; - gap: 0.125rem; - flex-shrink: 0; - } - .vc-step-btn { - margin: 0; - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.5rem; - height: 1.25rem; - padding: 0; - background-color: transparent; - color: var(--vscode-button-foreground); - border: none; - border-radius: 4px; - cursor: pointer; - font-family: var(--vscode-font-family); - flex-shrink: 0; - opacity: 0.7; - } - .vc-step-btn .codicon { - font-size: 1.5rem; - } - .vc-step-btn:hover { - font-weight: bold; - opacity: 1; - background-color: transparent; - } - .vc-step-btn:disabled { - cursor: default; - opacity: 0.35; - } - button { - padding: 0.2rem 0.6rem; - background-color: var(--vscode-button-background); - color: var(--vscode-button-foreground); - border: 1px solid var(--vscode-button-border); - border-radius: 4px; - cursor: pointer; - font-family: var(--vscode-font-family); - font-size: 0.9rem; - transition: background-color 0.2s; - } - button:hover { - background-color: var(--vscode-button-hoverBackground); - } - .underline-button { - color: var(--vscode-foreground); - text-align: center; - font-size: 0.8rem; - opacity: 0.6; - margin-bottom: 1rem; - padding: 0; - background: none; - display: flex; - justify-content: center; - border: none; - text-decoration: underline; - } - .underline-button:hover { - background: none; - } - .tooltip:hover::after { - content: attr(data-tooltip); - position: absolute; - bottom: 100%; - left: 50%; - transform: translateX(-50%); - padding: 0.5rem; - background-color: var(--vscode-editorHoverWidget-background); - border: 1px solid var(--vscode-editorHoverWidget-border); - color: var(--vscode-editorHoverWidget-foreground); - border-radius: 4px; - white-space: nowrap; - z-index: 1000; - margin-bottom: 0.25rem; - box-shadow: 0 2px 8px var(--vscode-widget-shadow); - pointer-events: none; - } - .tooltip:hover::before { - content: ''; - position: absolute; - bottom: 100%; - left: 50%; - transform: translateX(-50%); - border: 5px solid transparent; - border-top-color: var(--vscode-editorHoverWidget-border); - margin-bottom: -0.25rem; - z-index: 1000; - pointer-events: none; - } - .info { - margin: 1rem 0; - } - .stopped-view { - display: flex; - position: relative; - min-height: calc(100vh - 2rem); - flex-direction: column; - align-items: center; - justify-content: flex-start; - gap: 0.75rem; - padding-top: 2rem; - text-align: center; - color: var(--vscode-foreground); - } - .stopped-view h2 { - margin: 0; - } - .stopped-view .info { - max-width: 28rem; - color: var(--vscode-descriptionForeground); - } - .stopped-status-icon { - display: inline-flex; - align-items: center; - justify-content: center; - width: 2.25rem; - height: 2.25rem; - border: 1px solid var(--vscode-errorForeground); - border-radius: 50%; - color: var(--vscode-errorForeground); - font-weight: 700; - font-size: 1.35rem; - line-height: 1; - } - .more-indicator { - text-align: center; - font-size: 0.8rem; - opacity: 0.6; - margin-bottom: 1rem; - } - table { - width: 100%; - border-collapse: collapse; - margin: 0rem 0; - background-color: var(--vscode-editor-background); - border-radius: 4px; - overflow: visible; - } - th { - text-align: left; - padding: 0.75rem; - font-weight: bold; - border-bottom: 1px solid var(--vscode-panel-border); - color: var(--vscode-foreground); - } - td { - padding: 0.75rem; - border-bottom: 1px solid var(--vscode-panel-border); - color: var(--vscode-foreground); - } - tbody tr:last-child td { - border-bottom: none; - } - td code { - background-color: transparent; - padding: 0; - border-radius: 3px; - font-family: var(--vscode-editor-font-family); - font-size: 0.9em; - } - .context-section table { - width: 100%; - table-layout: fixed; - margin-bottom: 1rem; - } - - .context-variables-table .context-variables-column { - width: 33.33%; - } - - .context-variables-table .context-refinement-column { - width: 66.67%; - } - - .context-aliases-table td:first-child, - .context-ghosts-table td:first-child { - width: 80%; - } - - .context-aliases-table td:last-child, - .context-ghosts-table td:last-child { - width: 20%; - } - - .context-variables-table th:first-child, - .context-section table td:first-child { - text-align: left; - } - - .context-variables-table td:first-child { - overflow: hidden; - } - - .context-variables-table td:first-child .highlight-var-btn { - max-width: 100%; - overflow: hidden; - } - - .context-variables-table td:first-child .highlight-var-btn code { - display: block; - overflow: hidden; - white-space: normal; - overflow-wrap: normal; - word-break: normal; - } - - .context-variable-relevant td:first-child { - border-left: 2px solid var(--vscode-errorForeground); - } - .context-variables-table th:first-child { - padding-left: calc(0.75rem + 0.8rem); - } - .context-aliases-table td:last-child, - .context-ghosts-table td:last-child { - text-align: right; - } - .context-variables-table td.failing-refinement { - text-align: center; - } - .failing-refinement .highlight-var-btn, - .failing-refinement .diagnostic-reveal-btn { - display: flex; - justify-content: center; - width: 100%; - } - .context-toggle-btn { - display: flex; - align-items: center; - gap: 0.5rem; - width: 100%; - padding: 0; - margin: 0 0 0.5rem 0; - background: none; - border: none; - color: var(--vscode-foreground); - cursor: pointer; - font-size: 1rem; - font-weight: bold; - text-align: left; - } - .context-toggle-btn:hover { - background: none; - } - .context-toggle-icon { - width: 1rem; - text-align: center; - flex-shrink: 0; - } - .context-section-content.collapsed { - display: none; - } - .highlight-var-btn, - .diagnostic-reveal-btn { - background-color: transparent; - border: none; - transition: background-color 0.1s; - text-align: left; - padding: 0.2rem 0.8rem; - } - .highlight-var-btn code, - .diagnostic-reveal-btn code { - pointer-events: none; - } - .highlight-var-btn.selected { - background-color: var(--vscode-button-background); - } - .highlight-var-btn.error, - .diagnostic-reveal-btn.error { - background-color: color-mix(in srgb, var(--vscode-errorForeground) 80%, transparent); - color: var(--vscode-editor-foreground); - } - .highlight-var-btn.error.selected, - .diagnostic-reveal-btn.error.selected { - background-color: color-mix(in srgb, var(--vscode-errorForeground) 90%, transparent); - } - .highlight-var-btn.error:hover, - .diagnostic-reveal-btn.error:hover { - background-color: var(--vscode-errorForeground); - } - .diagram-section { - margin-bottom: 1.5rem; - padding-bottom: 1rem; - border-bottom: 1px solid var(--vscode-panel-border); - } - .diagram-section h2 { - margin-bottom: 0.5rem; - } - .diagram-container { - background-color: var(--vscode-editor-background); - border-radius: 4px; - padding: 1rem; - overflow: hidden; - position: relative; - cursor: grab; - user-select: none; - } - .diagram-container:active { - cursor: grabbing; - } - .diagram-wrapper { - transition: transform 0.1s ease-out; - transform-origin: 0 0; - display: inline-block; - min-width: 100%; - pointer-events: none; - } - .diagram-wrapper * { - pointer-events: auto; - } - .diagram-container .mermaid { - display: flex; - justify-content: center; - } - .diagram-container .mermaid svg { - max-width: 100%; - height: auto; - } - .diagram-controls { - position: absolute; - top: 1rem; - right: 1rem; - display: flex; - gap: 0.5rem; - z-index: 10; - } - .diagram-condition-legend { - position: absolute; - bottom: 1rem; - right: 1rem; - display: flex; - flex-direction: column; - gap: 0.25rem; - font-size: 0.8rem; - z-index: 10; - pointer-events: none; - font-weight: 500; - } - .diagram-condition-legend-pre { - color: var(--lj-state-cond-pre); - } - .diagram-condition-legend-post { - color: var(--lj-state-cond-post); - } - .diagram-control-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.75rem; - height: 1.75rem; - padding: 0; - color: var(--vscode-foreground); - background: none; - border: none; - opacity: 0.7; - } - .diagram-control-btn:hover { - background: none; - opacity: 1; - } - .diagram-control-btn.active { - opacity: 1; - } - .diagram-control-btn:disabled { - cursor: default; - opacity: 0.35; - } - .mermaid .statediagramTitleText { - font-size: 30px!important; - } - .diagram-container .mermaid svg, - .diagram-container .mermaid svg * { - color: var(--vscode-foreground) !important; - } - .diagram-container .mermaid svg text, - .diagram-container .mermaid svg tspan, - .diagram-container .mermaid svg .label, - .diagram-container .mermaid svg .label text, - .diagram-container .mermaid svg .edgeLabel text { - fill: var(--vscode-foreground) !important; - } - .diagram-container .mermaid svg .edgeLabel rect, - .diagram-container .mermaid svg .labelBkg { - fill: var(--vscode-editor-background) !important; - stroke: var(--vscode-panel-border) !important; - } - .diagram-container .mermaid .edgeLabel, - .diagram-container .mermaid .edgeLabel *, - .diagram-container .mermaid .edgeLabel p, - .diagram-container .mermaid .edgeLabel span, - .diagram-container .mermaid .edgeLabel div { - color: var(--vscode-foreground) !important; - background: var(--vscode-editor-background) !important; - } - .diagram-container .mermaid .edgeLabel .state-cond { - color: var(--vscode-descriptionForeground) !important; - display: inline-block !important; - font-size: 0.76em !important; - line-height: 1.2 !important; - } - .diagram-container .mermaid .edgeLabel .state-cond-pre { - color: var(--lj-state-cond-pre) !important; - } - .diagram-container .mermaid .edgeLabel .state-cond-post { - color: var(--lj-state-cond-post) !important; - } - .diagram-container .mermaid svg rect, - .diagram-container .mermaid svg circle, - .diagram-container .mermaid svg ellipse, - .diagram-container .mermaid svg polygon { - fill: var(--vscode-editor-background) !important; - stroke: var(--vscode-foreground) !important; - } - .diagram-container .mermaid svg path, - .diagram-container .mermaid svg line { - stroke: var(--vscode-foreground) !important; - } - .diagram-container .mermaid svg marker path { - fill: var(--vscode-foreground) !important; - stroke: var(--vscode-foreground) !important; - } - `; -} diff --git a/client/src/webview/utils.ts b/client/src/webview/utils.ts deleted file mode 100644 index f20bd891..00000000 --- a/client/src/webview/utils.ts +++ /dev/null @@ -1,18 +0,0 @@ - -export function getSimpleName(qualifiedName: string): string { - const parts = qualifiedName.split('.'); - return parts[parts.length - 1]; -} - -export function getOriginalVariableName(name: string): string { - return name.split("_")[0].replace(/^#/, ''); -} - -export function escapeHtml(html: string): string { - return html - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); -} \ No newline at end of file diff --git a/client/src/webview/views/context/aliases.ts b/client/src/webview/views/context/aliases.ts deleted file mode 100644 index ef7e8c11..00000000 --- a/client/src/webview/views/context/aliases.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { LJAlias } from "../../../types/context"; -import { getSimpleName } from "../../utils"; -import { renderHighlightedInlineExpression } from "../../highlighting"; -import { renderToggleSection } from "../sections"; - -export function renderContextAliases(aliases: LJAlias[], isExpanded: boolean): string { - return /*html*/` -
- ${renderToggleSection('Aliases', 'context-aliases', isExpanded)} -
- ${aliases.length > 0 ? /*html*/` - - - ${aliases.map(alias => /*html*/` - - - - - `).join('')} - -
- - ${renderHighlightedInlineExpression(renderAlias(alias))} - - alias
- ` : '

No aliases declared in the project

'} -
-
- `; -} - -function renderAlias(alias: LJAlias): string { - const parameters = alias.parameters - .map((parameter, index) => `${getSimpleName(alias.types[index])} ${parameter}`) - .join(", "); - - return `${alias.name}(${parameters}) { ${alias.predicate} }`; -} diff --git a/client/src/webview/views/context/context.ts b/client/src/webview/views/context/context.ts deleted file mode 100644 index de78cb76..00000000 --- a/client/src/webview/views/context/context.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { LJContext } from "../../../types/context"; -import type { RefinementMismatchError } from "../../../types/diagnostics"; -import { renderMainHeader } from "../sections"; -import { renderContextAliases } from "./aliases"; -import { renderContextGhosts } from "./ghosts"; -import { renderContextVariables } from "./variables"; - -export type ContextSectionState = { - aliases: boolean; - ghosts: boolean; - vars: boolean; -} - -export function renderContextView(context: LJContext | undefined, currentFile: string | undefined, sectionState: ContextSectionState, errorAtCursor?: RefinementMismatchError): string { - const allVars = context?.allVars || []; - const ghosts = context?.ghosts?.filter(ghost => ghost.file === currentFile) || []; - const aliases = context?.aliases || []; - const total = allVars.length + ghosts.length + aliases.length; - return /*html*/` -
- ${renderMainHeader("", 'context')} - ${total === 0 - ? '

No context information available at the cursor position

' - : `${renderContextAliases(aliases, sectionState.aliases)} - ${renderContextGhosts(ghosts, sectionState.ghosts)} - ${renderContextVariables(allVars, sectionState.vars, errorAtCursor)} - `} -
- `; -} diff --git a/client/src/webview/views/context/ghosts.ts b/client/src/webview/views/context/ghosts.ts deleted file mode 100644 index 6b758ac2..00000000 --- a/client/src/webview/views/context/ghosts.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { LJGhost } from "../../../types/context"; -import { getSimpleName } from "../../utils"; -import { renderHighlightedInlineExpression } from "../../highlighting"; -import { renderToggleSection } from "../sections"; - -export function renderContextGhosts(ghosts: LJGhost[], isExpanded: boolean): string { - return /*html*/` -
- ${renderToggleSection('Ghosts', 'context-ghosts', isExpanded)} -
- ${ghosts.length > 0 ? /*html*/` - - - ${ghosts.map(ghost => /*html*/` - - - - - `).join('')} - -
${renderHighlightedInlineExpression(renderGhost(ghost))}${ghost.isState ? 'state' : 'ghost'}
- ` : '

No ghosts or states declared in the current file

'} -
-
- `; -} - -function renderGhost(ghost: LJGhost): string { - return `${ghost.returnType} ${ghost.name}(${ghost.parameterTypes.map(getSimpleName).join(', ')})`; -} diff --git a/client/src/webview/views/context/variables.ts b/client/src/webview/views/context/variables.ts deleted file mode 100644 index 89324e5d..00000000 --- a/client/src/webview/views/context/variables.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { LJVariable } from "../../../types/context"; -import { RefinementMismatchError } from "../../../types/diagnostics"; -import { renderHighlightedInlineExpression } from "../../highlighting"; -import { escapeHtml, getSimpleName } from "../../utils"; -import { renderToggleSection, renderVariableHighlightButton, renderDiagnosticRevealButton } from "../sections"; - -export function renderContextVariables(variables: LJVariable[], isExpanded: boolean, errorAtCursor?: RefinementMismatchError): string { - const relevantNames = new Set(Object.keys(errorAtCursor?.translationTable || {})); - return /*html*/` -
- ${renderToggleSection('Variables', 'context-vars', isExpanded)} -
- ${variables.length > 0 ? /*html*/` - - - - - - - - - - - - - ${variables.map(variable => { - const isRelevant = relevantNames.has(variable.name); - return /*html*/` - - - - - `}).join('')} - ${errorAtCursor ? renderFailingRefinement(errorAtCursor) : ''} - -
NameRefinement
${renderVariableHighlightButton(variable)}${renderHighlightedInlineExpression(variable.refinement)}
- `: '

No variables declared at the cursor position

'} -
-
- `; -} - -function renderFailingRefinement(errorAtCursor: RefinementMismatchError): string { - return /*html*/` - - - ${renderDiagnosticRevealButton(errorAtCursor.position!, '⊢ ' + errorAtCursor.expected)} - - - `; -} diff --git a/client/src/webview/views/diagnostics/counterexample.ts b/client/src/webview/views/diagnostics/counterexample.ts deleted file mode 100644 index 6d80f766..00000000 --- a/client/src/webview/views/diagnostics/counterexample.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { renderHighlightedInlineExpression } from "../../highlighting"; - -function getCounterexampleLines(counterexample: string): string[] { - return counterexample - .split("&&") - .map(assignment => assignment.trim()) - .filter(Boolean); -} - -export function renderCounterexample(counterexample: string): string { - const lines = getCounterexampleLines(counterexample); - if (lines.length === 0) return ""; - - return /*html*/` -
-
- ${lines.map(line => /*html*/` -
- ${renderHighlightedInlineExpression(line)} -
- `).join("")} -
-
- `; -} diff --git a/client/src/webview/views/diagnostics/diagnostics.ts b/client/src/webview/views/diagnostics/diagnostics.ts deleted file mode 100644 index 5035bafd..00000000 --- a/client/src/webview/views/diagnostics/diagnostics.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { LJDiagnostic, LJError, LJWarning } from "../../../types/diagnostics"; -import type { VCImplication, VCSimplificationResult } from "../../../types/vc-implications"; -import { copyToClipboard } from "../../clipboard"; -import { renderCodiconButton } from "../../icons"; -import { renderErrors } from "./errors"; -import { renderMainHeader } from "../sections"; -import { renderWarnings } from "./warnings"; - -export function renderDiagnosticsView( - diagnostics: LJDiagnostic[], - showAll: boolean, - currentFile: string | undefined, -): string { - const fileDiagnostics = diagnostics.filter(diagnostic => diagnostic.file?.toLowerCase() === currentFile?.toLowerCase() || !diagnostic.file); - const displayDiagnostics = showAll ? diagnostics : fileDiagnostics; - const errors = displayDiagnostics.filter(d => d.category === 'error') as LJError[]; - const warnings = displayDiagnostics.filter(d => d.category === 'warning') as LJWarning[]; - const totalErrors = diagnostics.filter(d => d.category === 'error').length; - const hasErrors = totalErrors > 0; - const hiddenErrors = totalErrors - errors.length; - const titleMessage = hasErrors ? "Failed Verification" : "Passed Verification"; - const infoMessage = hasErrors ? - `${totalErrors} error${totalErrors !== 1 ? 's were' : ' was'} found by the LiquidJava verifier` : - "No errors were found by the LiquidJava verifier."; - - return /*html*/` -
- ${renderMainHeader(titleMessage, 'diagnostics')} -

${infoMessage}

- ${ - diagnostics.length === 0 ? '' : /*html*/` - - ` - } -
- ${renderErrors(errors)} - ${renderWarnings(warnings)} - ${displayDiagnostics.length > 0 && hiddenErrors > 0 ? /*html*/` -

(+${hiddenErrors} error${hiddenErrors !== 1 ? 's' : ''})

- ` : ''} -
-
- `; -} - -export function getDisplayDiagnostics(diagnostics: LJDiagnostic[], showAll: boolean, currentFile: string | undefined): LJDiagnostic[] { - if (showAll) return diagnostics; - return diagnostics.filter(diagnostic => diagnostic.file?.toLowerCase() === currentFile?.toLowerCase() || !diagnostic.file); -} - -export function renderCopyDiagnosticButton(indexType: 'error' | 'warning', index: number): string { - return renderCodiconButton("copy", { - className: "copy-diagnostic-btn", - title: "Copy diagnostic", - attributes: `data-${indexType}-index="${index}"`, - }); -} - -export async function copyDiagnosticToClipboard(button: any, displayDiagnostics: LJDiagnostic[]) { - const errorIndex = parseInt(button.getAttribute('data-error-index') || '-1', 10); - const warningIndex = parseInt(button.getAttribute('data-warning-index') || '-1', 10); - const diagnostic = errorIndex >= 0 - ? displayDiagnostics.filter(d => d.category === 'error')[errorIndex] - : displayDiagnostics.filter(d => d.category === 'warning')[warningIndex]; - if (!diagnostic) return; - - const diagnosticText = formatDiagnosticForClipboard(diagnostic); - await copyToClipboard(button, diagnosticText); -} - -export function formatDiagnosticForClipboard(diagnostic: LJDiagnostic): string { - const skippedFields = new Set(['category', 'type', 'translationTable', 'position', 'file']); - const lines: string[] = []; - - Object.entries(diagnostic).forEach(([key, value]) => { - if (skippedFields.has(key)) return; - - const formattedValue = formatClipboardValue(value); - if (!formattedValue) return; - - lines.push(`${formatClipboardLabel(key)}: ${formattedValue}`); - }); - - const location = formatDiagnosticLocation(diagnostic); - if (location) lines.push(`Location: ${location}`); - - return lines.join('\n'); -} - -function formatClipboardLabel(key: string): string { - return key - .replace(/([a-z0-9])([A-Z])/g, '$1 $2') - .replace(/^./, char => char.toUpperCase()); -} - -function formatClipboardValue(value: unknown): string { - if (value === null || value === undefined) return ''; - - if (typeof value === 'string') return value.trim(); - if (typeof value === 'number' || typeof value === 'boolean') return String(value); - - if (Array.isArray(value)) { - const values = value.map(formatClipboardValue).filter(Boolean); - if (values.length === 0) return ''; - return values.some(v => v.includes('\n')) ? `\n${values.join('\n')}` : values.join(', '); - } - - if (isVCSimplificationResult(value)) return formatVCImplication(value.implication); - if (isVCImplication(value)) return formatVCImplication(value); - - return JSON.stringify(value); -} - -function isVCSimplificationResult(value: unknown): value is VCSimplificationResult { - return typeof value === 'object' - && value !== null - && 'implication' in value - && 'origin' in value; -} - -function isVCImplication(value: unknown): value is VCImplication { - return typeof value === 'object' - && value !== null - && 'predicate' in value - && 'next' in value; -} - -function formatVCImplication(node: VCImplication | null): string { - if (!node) return ''; - - const binder = node.name !== null && node.type !== null ? `∀${node.name}:${node.type}, ` : ''; - const current = `${binder}${node.predicate}`; - const next = formatVCImplication(node.next); - return next ? `${current}\n=> ${next}` : current; -} - -function formatDiagnosticLocation(diagnostic: LJDiagnostic): string { - if (!diagnostic.file || !diagnostic.position) return ''; - - const filename = diagnostic.file.split('/').pop()?.trim() || diagnostic.file; - return `${filename}:${diagnostic.position.lineStart + 1}`; -} diff --git a/client/src/webview/views/diagnostics/errors.ts b/client/src/webview/views/diagnostics/errors.ts deleted file mode 100644 index ac48c74d..00000000 --- a/client/src/webview/views/diagnostics/errors.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { renderDiagnosticDataAttributes, renderExpressionSection, renderDiagnosticHeader, renderCustomSection, renderLocation, renderDiagnosticContextButton } from "../sections"; -import { renderCounterexample } from "./counterexample"; -import { renderVCImplication } from "./vc-implications"; -import type { - ArgumentMismatchError, - CustomError, - IllegalConstructorTransitionError, - InvalidRefinementError, - LJError, - NotFoundError, - RefinementError, - StateConflictError, - StateRefinementError, - SyntaxError, -} from "../../../types/diagnostics"; -import { renderCopyDiagnosticButton } from "./diagnostics"; - -export function renderErrors(errors: LJError[]): string { - return /*html*/` -
    - ${errors.map((error, index) => { - return /*html*/` -
  • - ${renderDiagnosticContextAction(error)} - ${renderCopyDiagnosticButton('error', index)} - ${renderError(error)} -
  • - `; - }).join("")} -
- `; -} - -type ErrorRendererMap = { [E in LJError as E['type']]: (error: E) => string }; - -const errorContentRenderers: ErrorRendererMap = { - 'refinement-error': (e: RefinementError) => /*html*/ ` - ${renderExpressionSection('Expected', e.expected)} - ${renderCustomSection('Found', renderVCImplication(e, e.found))} - ${e.counterexample ? renderCustomSection('Counterexample', renderCounterexample(e.counterexample)) : ''} - `, - 'state-refinement-error': (e: StateRefinementError) => /*html*/ ` - ${renderExpressionSection('Expected', e.expected)} - ${renderCustomSection('Found', renderVCImplication(e, e.found))} - `, - 'invalid-refinement-error': (e: InvalidRefinementError) => /*html*/ ` - ${renderExpressionSection('Refinement', e.refinement)} - `, - 'not-found-error': (e: NotFoundError) => /*html*/ ` - ${renderExpressionSection(e.kind, e.name)} - `, - 'state-conflict-error': (e: StateConflictError) => /*html*/ ` - ${renderExpressionSection('State', e.state)} - `, - 'syntax-error': (e: SyntaxError) => /*html*/ ` - ${renderExpressionSection('Refinement', e.refinement)} - `, - 'argument-mismatch-error': (e: ArgumentMismatchError) => /*html*/ ` - ${renderExpressionSection('Refinement', e.refinement)} - `, - 'illegal-constructor-transition-error': (_: IllegalConstructorTransitionError) => "null", - 'custom-error': (_: CustomError) => "", -}; - -export function renderError(error: LJError): string { - const message = error.type === 'refinement-error' || error.type === 'state-refinement-error' ? error.customMessage : error.message; - const header = renderDiagnosticHeader(error.title, message || ''); - const content = (errorContentRenderers[error.type] as (error: LJError) => string)?.(error) || ''; - const location = renderLocation(error); - return /*html*/`${header}${content}${location}`; -} - -function renderDiagnosticContextAction(error: LJError): string { - if (error.type !== 'refinement-error' && error.type !== 'state-refinement-error') return ""; - return renderDiagnosticContextButton(error.position); -} diff --git a/client/src/webview/views/diagnostics/vc-changes.ts b/client/src/webview/views/diagnostics/vc-changes.ts deleted file mode 100644 index 67fa0ab1..00000000 --- a/client/src/webview/views/diagnostics/vc-changes.ts +++ /dev/null @@ -1,215 +0,0 @@ -import type { VCImplication } from "../../../types/vc-implications"; -import { renderHighlightedInlineExpression } from "../../highlighting"; -import { escapeHtml } from "../../utils"; - -type ChangeKind = "unchanged" | "removed" | "added"; -type DiffOperation = { kind: ChangeKind; value: T }; - -const MIN_LINE_SIMILARITY = 0.3; -const TOKEN_PATTERN = /\s+|-->|&&|\|\||==|!=|<=|>=|[a-zA-Z_#][a-zA-Z0-9_#⁰¹²³⁴⁵⁶⁷⁸⁹]*|\d+(?:\.\d+)?|[^\s]/gu; -const WHITESPACE_PATTERN = /^\s+$/u; -const VC_LINE_SEPARATOR = "\t"; - -function hasBinder(node: VCImplication): boolean { - return typeof node.name === "string" && node.name.length > 0; -} - -function formatImplicationLine(node: VCImplication): string { - const binder = hasBinder(node) ? `∀${node.name}` : ""; - const type = typeof node.type === "string" ? node.type : ""; - return [binder, type, node.predicate].join(VC_LINE_SEPARATOR); -} - -function parseImplicationLine(line: string): { binder: string; type: string; predicate: string } { - const [binder = "", type = "", predicate = ""] = line.split(VC_LINE_SEPARATOR); - return { binder, type, predicate }; -} - -function getImplicationLines(node: VCImplication): string[] { - const lines: string[] = []; - for (let current: VCImplication | null = node; current; current = current.next) { - if (current.next && !hasBinder(current)) continue; - lines.push(formatImplicationLine(current)); - } - return lines; -} - -export function renderVCLine(line: string, className = "", predicateContent?: string): string { - const { binder, type, predicate } = parseImplicationLine(line); - return /*html*/` -
- ${binder ? /*html*/`
${escapeHtml(binder)}
` : ""} -
${predicateContent ?? renderHighlightedInlineExpression(predicate)}
-
- `; -} - -function createMatrix(rows: number, columns: number): number[][] { - return Array.from({ length: rows + 1 }, () => new Array(columns + 1).fill(0)); -} - -function diffSequence(before: T[], after: T[]): DiffOperation[] { - const lengths = createMatrix(before.length, after.length); - - for (let beforeIndex = before.length - 1; beforeIndex >= 0; beforeIndex -= 1) { - for (let afterIndex = after.length - 1; afterIndex >= 0; afterIndex -= 1) { - lengths[beforeIndex][afterIndex] = before[beforeIndex] === after[afterIndex] - ? lengths[beforeIndex + 1][afterIndex + 1] + 1 - : Math.max(lengths[beforeIndex + 1][afterIndex], lengths[beforeIndex][afterIndex + 1]); - } - } - - const operations: DiffOperation[] = []; - let beforeIndex = 0; - let afterIndex = 0; - while (beforeIndex < before.length && afterIndex < after.length) { - if (before[beforeIndex] === after[afterIndex]) { - operations.push({ kind: "unchanged", value: before[beforeIndex] }); - beforeIndex++; - afterIndex++; - } else if (lengths[beforeIndex + 1][afterIndex] >= lengths[beforeIndex][afterIndex + 1]) { - operations.push({ kind: "removed", value: before[beforeIndex++] }); - } else { - operations.push({ kind: "added", value: after[afterIndex++] }); - } - } - operations.push( - ...before.slice(beforeIndex).map(value => ({ kind: "removed" as const, value })), - ...after.slice(afterIndex).map(value => ({ kind: "added" as const, value })), - ); - return operations; -} - -function tokenizeExpression(expression: string): string[] { - return expression.match(TOKEN_PATTERN) || []; -} - -function renderChangedFragment(content: string): string { - return `${renderHighlightedInlineExpression(content)}`; -} - -function renderDestinationTokenDiff(before: string, after: string): { content: string; hasAddedContent: boolean } { - const operations = diffSequence(tokenizeExpression(before), tokenizeExpression(after)); - let html = ""; - let changedContent = ""; - let hasAddedContent = false; - - const flushChangedContent = () => { - if (!changedContent) return; - const trailingWhitespace = changedContent.match(/\s+$/u)?.[0] ?? ""; - const content = changedContent.slice(0, changedContent.length - trailingWhitespace.length); - if (content) html += renderChangedFragment(content); - html += trailingWhitespace; - changedContent = ""; - }; - - operations.forEach((operation, index) => { - if (operation.kind === "added") { - changedContent += operation.value; - hasAddedContent = true; - return; - } - if (operation.kind === "unchanged") { - if (WHITESPACE_PATTERN.test(operation.value) && changedContent && operations[index + 1]?.kind === "added") { - changedContent += operation.value; - return; - } - flushChangedContent(); - html += renderHighlightedInlineExpression(operation.value); - } - }); - flushChangedContent(); - return { content: html, hasAddedContent }; -} - -function getLineSimilarity(before: string, after: string): number { - const beforeTokens = tokenizeExpression(before).filter(token => !WHITESPACE_PATTERN.test(token)); - const afterTokens = tokenizeExpression(after).filter(token => !WHITESPACE_PATTERN.test(token)); - const unchangedLength = diffSequence(beforeTokens, afterTokens) - .filter(operation => operation.kind === "unchanged") - .reduce((length, operation) => length + operation.value.length, 0); - const totalLength = Math.max(beforeTokens.join("").length, afterTokens.join("").length); - return totalLength === 0 ? 0 : unchangedLength / totalLength; -} - -function alignChangedLines(removed: string[], added: string[]): Array<[string | undefined, string | undefined]> { - const similarities = removed.map(before => added.map(after => getLineSimilarity(before, after))); - const scores = createMatrix(removed.length, added.length); - - for (let i = removed.length - 1; i >= 0; i -= 1) { - for (let j = added.length - 1; j >= 0; j -= 1) { - const similarity = similarities[i][j]; - scores[i][j] = Math.max( - scores[i + 1][j], - scores[i][j + 1], - similarity >= MIN_LINE_SIMILARITY ? similarity + scores[i + 1][j + 1] : 0, - ); - } - } - - const lines: Array<[string | undefined, string | undefined]> = []; - let i = 0; - let j = 0; - while (i < removed.length && j < added.length) { - const similarity = similarities[i][j]; - if ( - similarity >= MIN_LINE_SIMILARITY - && scores[i][j] === similarity + scores[i + 1][j + 1] - ) { - lines.push([removed[i++], added[j++]]); - } else if (scores[i][j + 1] >= scores[i + 1][j]) { - lines.push([undefined, added[j++]]); - } else { - lines.push([removed[i++], undefined]); - } - } - while (i < removed.length) lines.push([removed[i++], undefined]); - while (j < added.length) lines.push([undefined, added[j++]]); - return lines; -} - -function renderChangedDestinationLines(removed: string[], added: string[]): string { - if (added.length === 0) return ""; - - return alignChangedLines(removed, added) - .map(([before, after]) => { - if (after === undefined) return ""; - if (before === undefined) return renderVCLine(after, "vc-change-line"); - const change = renderDestinationTokenDiff( - parseImplicationLine(before).predicate, - parseImplicationLine(after).predicate, - ); - return renderVCLine(after, change.hasAddedContent ? "" : "vc-change-line", change.content); - }) - .join(""); -} - -export function renderImplication(node: VCImplication): string { - return getImplicationLines(node) - .map(line => renderVCLine(line)) - .join(""); -} - -export function renderImplicationChange(before: VCImplication, after: VCImplication): string { - const operations = diffSequence(getImplicationLines(before), getImplicationLines(after)); - let html = ""; - const changed = { removed: [] as string[], added: [] as string[] }; - - const flushChanges = () => { - html += renderChangedDestinationLines(changed.removed, changed.added); - changed.removed.length = 0; - changed.added.length = 0; - }; - - for (const operation of operations) { - if (operation.kind === "unchanged") { - flushChanges(); - html += renderVCLine(operation.value); - continue; - } - changed[operation.kind].push(operation.value); - } - - flushChanges(); - return html; -} diff --git a/client/src/webview/views/diagnostics/vc-implications.ts b/client/src/webview/views/diagnostics/vc-implications.ts deleted file mode 100644 index c2b76e61..00000000 --- a/client/src/webview/views/diagnostics/vc-implications.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { RefinementMismatchError } from "../../../types/diagnostics"; -import type { VCSimplificationResult } from "../../../types/vc-implications"; -import { renderHighlightedExpression } from "../../highlighting"; -import { renderCodicon } from "../../icons"; -import { escapeHtml } from "../../utils"; -import { renderImplication, renderImplicationChange } from "./vc-changes"; - -const stepIndexes = new Map(); // errorId => step index, preserved across re-renders -const simplificationSteps = new Map(); // errorId => simplification steps - -function renderStepButton(errorId: string, step: "previous" | "next", disabled: boolean): string { - const label = `${step === "previous" ? "Previous" : "Next"} simplification`; - const icon = step === "previous" ? "arrow-small-left" : "arrow-small-right"; - return ``; -} - -function renderStepHeader( - errorId: string, - current: VCSimplificationResult, - index: number, - stepCount: number, -): string { - const currStep = stepCount - index; - const simplification = current.simplification?.trim(); - const label = escapeHtml(index === 0 ? "Simplified" : simplification || "Original"); - - return /*html*/` -
- ${label} -
- - ${currStep}/${stepCount} - -
- ${renderStepButton(errorId, "previous", index === stepCount - 1)} - ${renderStepButton(errorId, "next", index === 0)} -
-
-
- `; -} - -function getTargetStepIndex(errorId: string, step: string | null): number | undefined { - const steps = simplificationSteps.get(errorId); - if (!steps) return; - - const index = stepIndexes.get(errorId) ?? 0; - const targetIndex = step === "previous" ? index + 1 : step === "next" ? index - 1 : -1; - if (targetIndex < 0 || targetIndex >= steps.length) return; - return targetIndex; -} - -function renderSelectedStep(errorId: string, previousIndex?: number): string { - const steps = simplificationSteps.get(errorId); - if (!steps) return ""; - - const index = Math.min(stepIndexes.get(errorId) ?? 0, steps.length - 1); - const current = steps[index]; - const previous = previousIndex === undefined ? undefined : steps[previousIndex]; - const implication = previous - ? `
${renderImplicationChange(previous.implication, current.implication)}
` - : `
${renderImplication(current.implication)}
`; - - return /*html*/` - ${steps.length > 1 ? renderStepHeader(errorId, current, index, steps.length) : ""} - ${implication} - `; -} - -export function handleVCImplicationStepClick(target: Element): boolean { - const errorId = target.getAttribute("data-error-id"); - const step = target.getAttribute("data-vc-step"); - if (!errorId || (target as HTMLButtonElement).disabled) return false; - - const currentIndex = stepIndexes.get(errorId) ?? 0; - const targetIndex = getTargetStepIndex(errorId, step); - const container = target.closest?.(".vc-container"); - if (targetIndex === undefined) return false; - - stepIndexes.set(errorId, targetIndex); - if (container) container.innerHTML = renderSelectedStep(errorId, currentIndex); - return true; -} - -export function renderVCImplication( - error: RefinementMismatchError, - result: VCSimplificationResult -): string { - if (!result?.implication) return renderHighlightedExpression(String(result)); - - const errorId = encodeURIComponent(JSON.stringify([ - error.file, - error.position?.lineStart, - error.title, - error.message - ])); - const steps: VCSimplificationResult[] = []; - for (let current: VCSimplificationResult | null = result; current; current = current.origin) { - steps.push(current); - } - simplificationSteps.set(errorId, steps); - - const index = Math.min(stepIndexes.get(errorId) ?? 0, steps.length - 1); - stepIndexes.set(errorId, index); - - return /*html*/ ` -
- ${renderSelectedStep(errorId)} -
- `; -} diff --git a/client/src/webview/views/diagnostics/warnings.ts b/client/src/webview/views/diagnostics/warnings.ts deleted file mode 100644 index a5dbc86c..00000000 --- a/client/src/webview/views/diagnostics/warnings.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { CustomWarning, ExternalClassNotFoundWarning, ExternalMethodNotFoundWarning, LJWarning, UnsatisfiableRefinementWarning } from "../../../types/diagnostics"; -import { renderDiagnosticDataAttributes, renderExpressionSection, renderDiagnosticHeader, renderLocation } from "../sections"; -import { renderCopyDiagnosticButton } from "./diagnostics"; - -export function renderWarnings(warnings: LJWarning[]): string { - return /*html*/` -
    - ${warnings.map((warning, index) => /*html*/` -
  • - ${renderCopyDiagnosticButton('warning', index)} - ${renderWarning(warning)} -
  • - `).join("")} -
- `; -} - -type WarningContentRenderers = { [E in LJWarning as E['type']]: (warning: E) => string }; - -const warningContentRenderers: WarningContentRenderers = { - 'external-class-not-found-warning': (w: ExternalClassNotFoundWarning) => /*html*/ ` - ${renderExpressionSection('Class Name', w.className)} - `, - 'external-method-not-found-warning': (w: ExternalMethodNotFoundWarning) => /*html*/ ` - ${renderExpressionSection('Method', w.signature)} - ${w.overloads.length > 0 ? renderExpressionSection('Overloads', w.overloads.join('\n')) : ''} - `, - 'unsatisfiable-refinement-warning': (w: UnsatisfiableRefinementWarning) => /*html*/ ` - ${renderExpressionSection('Refinement', w.refinement)} - `, - "custom-warning": (_: CustomWarning) => "" -} - -export function renderWarning(warning: LJWarning): string { - const header = renderDiagnosticHeader(warning.title, warning.message); - const content = (warningContentRenderers[warning.type] as (warning: LJWarning) => string)?.(warning) || ''; - const location = renderLocation(warning); - return /*html*/`${header}${content}${location}`; -} diff --git a/client/src/webview/views/fsm/fsm.ts b/client/src/webview/views/fsm/fsm.ts deleted file mode 100644 index 3080baac..00000000 --- a/client/src/webview/views/fsm/fsm.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { LJStateMachine } from "../../../types/fsm"; -import { renderCodiconButton } from "../../icons"; -import { renderMainHeader } from "../sections"; - -export function renderStateMachineView(root: HTMLElement, sm: LJStateMachine | undefined, diagram: string, orientation: "LR" | "TB", showConditions: boolean) { - const previousDiagramContainer = root.querySelector('.diagram-container') as HTMLElement | null; - const diagramHeight = previousDiagramContainer?.offsetHeight; - root.innerHTML = renderStateMachineViewHtml(sm, diagram, orientation, showConditions, diagramHeight); -} - -function renderStateMachineViewHtml(sm: LJStateMachine | undefined, diagram: string, orientation: "LR" | "TB", showConditions: boolean, diagramHeight?: number): string { - const initialStateNames = sm ? [...new Set(sm.initialTransitions.map(transition => transition.to))] : []; - const hasConditionExpansions = sm - ? sm.initialTransitions.some(transition => !!transition.postCond) - || sm.transitions.some(transition => !!transition.preCond || !!transition.postCond) - : false; - const conditionToggleLabel = showConditions ? 'Collapse Conditions' : 'Expand Conditions'; - - return /*html*/` -
- ${renderMainHeader("", 'fsm')} - ${sm ? /*html*/` -
-
-
- ${renderCodiconButton("zoom-in", { id: "zoom-in-btn", className: "diagram-control-btn", title: "Zoom In" })} - ${renderCodiconButton("zoom-out", { id: "zoom-out-btn", className: "diagram-control-btn", title: "Zoom Out" })} - ${renderCodiconButton("screen-normal", { id: "zoom-reset-btn", className: "diagram-control-btn", title: "Reset Zoom" })} - ${renderCodiconButton(orientation === "TB" ? "arrow-down" : "arrow-right", { id: "diagram-orientation-btn", className: "diagram-control-btn", title: "Toggle Orientation" })} - ${renderCodiconButton(showConditions ? "collapse-all" : "expand-all", { id: "diagram-conditions-btn", className: `diagram-control-btn${showConditions ? ' active' : ''}`, title: conditionToggleLabel, attributes: `aria-pressed="${showConditions ? 'true' : 'false'}"`, disabled: !hasConditionExpansions })} - ${renderCodiconButton("copy", { id: "copy-diagram-btn", className: "diagram-control-btn", title: "Copy Mermaid Source" })} -
- ${showConditions && hasConditionExpansions ? /*html*/` -
- Precondition - Postcondition -
- ` : ''} -
-
${diagram}
-
-
-
-

States: ${sm.states.join(', ')}

-

Initial state${initialStateNames.length > 1 ? 's' : ''}: ${initialStateNames.join(', ')}

-

Number of states: ${sm.states.length}

-

Number of transitions: ${sm.transitions.length + sm.initialTransitions.length}

-
-
` - : 'No state machine available for the current file'} -
- `; -} diff --git a/client/src/webview/views/loading.ts b/client/src/webview/views/loading.ts deleted file mode 100644 index 08c97570..00000000 --- a/client/src/webview/views/loading.ts +++ /dev/null @@ -1,11 +0,0 @@ - -import { renderMainHeader } from "./sections"; - -export function renderLoading(): string { - return /*html*/` -
- ${renderMainHeader("Verification Pending", "diagnostics")} -

Running the LiquidJava verification...

-
- `; -} diff --git a/client/src/webview/views/sections.ts b/client/src/webview/views/sections.ts deleted file mode 100644 index 2b8c16e3..00000000 --- a/client/src/webview/views/sections.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { LJDiagnostic, SourcePosition } from "../../types/diagnostics"; -import { escapeHtml, getSimpleName } from "../utils"; -import { renderHighlightedExpression, renderHighlightedInlineExpression } from "../highlighting"; -import { getDiagnosticRevealTarget, getDiagnosticRevealTargetKey } from "../diagnostic-reveal"; -import { renderCodicon, renderCodiconButton } from "../icons"; -import { LJVariable } from "../../types/context"; - -export const renderMainHeader = (title: string, selectedTab: NavTab): string => /*html*/` -
- ${renderNav(selectedTab)} -

${title}

-
-`; - -export const renderCustomSection = (title: string, body: string): string => /*html*/ - `
${title}:
${body}
`; - -export const renderSection = (title: string, body: string): string => /*html*/ - renderCustomSection(title, `
${body}
`); - -export const renderExpressionSection = (title: string, expression: string): string => /*html*/ - renderCustomSection(title, renderHighlightedExpression(expression)); - -export const renderToggleSection = (title: string, targetId: string, isExpanded: boolean = true): string => /*html*/` - - `; - -export const renderDiagnosticHeader = (title: string, message: string): string => /*html*/ - `

${title}

${message}

`; - -export function renderDiagnosticDataAttributes(diagnostic: LJDiagnostic): string { - const target = getDiagnosticRevealTarget(diagnostic); - return target ? `data-diagnostic-target="${getDiagnosticRevealTargetKey(target)}"` : ""; -} - -export const renderLocation = (diagnostic: LJDiagnostic): string => { - if (!diagnostic.position || !diagnostic.file) return ""; - return renderCustomSection("Location", /*html*/`
${renderLocationLink(diagnostic.position)}
`); -}; - -export function renderVariableHighlightButton(variable: LJVariable): string { - const displayName = getSimpleName(variable.name); - const position = variable.position; - if (!position || !position.file) return `${displayName}`; - return /*html*/` - - `; -} - -export function renderDiagnosticContextButton(position?: SourcePosition | null): string { - if (!position?.file) return ""; - return renderCodiconButton("symbol-variable", { - className: "diagnostic-context-btn", - title: "View related context", - attributes: `data-diagnostic-target="${getDiagnosticRevealTargetKey({ file: position.file, position })}"`, - }); -} - -export function renderDiagnosticRevealButton(position: SourcePosition, content: string): string { - if (!position.file) return `${content}` - return /*html*/` - - `; -} - -export function renderLocationLink(position?: SourcePosition): string { - if (!position) return 'No location'; - return /*html*/`${escapeHtml(getFile(position))}`; -} - -function getFile(position: SourcePosition): string { - return `${position.file?.split('/').pop()?.trim() || position.file}:${position.lineStart + 1}`; -} - -export type NavTab = 'diagnostics' | 'fsm' | 'context'; - -export function renderNav(selectedTab: NavTab): string { - return /*html*/` - - `; -} diff --git a/client/src/webview/views/stopped.ts b/client/src/webview/views/stopped.ts deleted file mode 100644 index 7f228aa8..00000000 --- a/client/src/webview/views/stopped.ts +++ /dev/null @@ -1,23 +0,0 @@ -type StoppedViewStatus = "stopped" | "crashed"; - -const stoppedViewContent: Record = { - stopped: { - title: "LiquidJava Not Running", - message: /*html*/`To use LiquidJava, run LiquidJava: Start from the command palette.`, - }, - crashed: { - title: "LiquidJava Crashed", - message: /*html*/`LiquidJava could not verify this project.
Check for Java compilation errors.

To inspect the problem, run LiquidJava: Show Logs from the command palette.`, - }, -}; - -export function renderStopped(status: StoppedViewStatus): string { - const { title, message } = stoppedViewContent[status]; - return /*html*/` -
- -

${title}

-

${message}

-
- `; -} diff --git a/client/syntaxes/liquidjava.json b/client/syntaxes/liquidjava.json deleted file mode 100644 index aa7675d6..00000000 --- a/client/syntaxes/liquidjava.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "LiquidJava", - "scopeName": "source.liquidjava", - "injectionSelector": "L:source.java - (comment, string)", - "patterns": [ - { - "begin": "@(liquidjava\\.specification\\.)?(Refinement|RefinementMultiple|RefinementAlias|RefinementAliasMultiple|RefinementPredicate|RefinementPredicateMultiple|StateSet|StateSets|Ghost)\\s*\\(", - "end": "\\)", - "name": "meta.annotation.refinement.liquidjava", - "patterns": [ - { - "begin": "\\b(msg)\\s*=\\s*(\")", - "beginCaptures": { - "1": { "name": "variable.parameter.annotation.liquidjava" }, - "2": { "name": "string.quoted.double.java" } - }, - "end": "\"", - "endCaptures": { - "0": { "name": "string.quoted.double.java" } - }, - "contentName": "string.quoted.double.java" - }, - { - "begin": "\"", - "end": "\"", - "contentName": "source.liquidjava", - "patterns": [ - { "include": "#keywords" }, - { "include": "#functions" }, - { "include": "#operators" }, - { "include": "#types" }, - { "include": "#literals" }, - { "include": "#identifiers" } - ] - } - ] - }, - { - "begin": "@(liquidjava\\.specification\\.)?(StateRefinement|StateRefinementMultiple)\\s*\\(", - "end": "\\)", - "name": "meta.annotation.refinement.liquidjava", - "patterns": [ - { - "match": "\\b(from|to)\\b", - "name": "variable.parameter.annotation.liquidjava" - }, - { - "begin": "\\b(msg)\\s*=\\s*(\")", - "beginCaptures": { - "1": { "name": "variable.parameter.annotation.liquidjava" }, - "2": { "name": "string.quoted.double.java" } - }, - "end": "\"", - "endCaptures": { - "0": { "name": "string.quoted.double.java" } - }, - "contentName": "string.quoted.double.java" - }, - { - "begin": "\"", - "end": "\"", - "contentName": "source.liquidjava", - "patterns": [ - { "include": "#keywords" }, - { "include": "#functions" }, - { "include": "#operators" }, - { "include": "#types" }, - { "include": "#literals" }, - { "include": "#identifiers" } - ] - } - ] - }, - { - "begin": "@(liquidjava\\.specification\\.)?ExternalRefinementsFor\\s*\\(", - "end": "\\)", - "name": "meta.annotation.externalrefinement.liquidjava", - "patterns": [ - { - "begin": "\"", - "end": "\"", - "contentName": "entity.name.type.externalref.liquidjava", - "patterns": [ - { "include": "#qualified-names" } - ] - } - ] - } - ], - "repository": { - "keywords": { - "patterns": [ - { "match": "\\bthis\\b", "name": "variable.language.this.liquidjava" }, - { "match": "\\bghost\\b|\\balias\\b|\\btype\\b", "name": "keyword.other.liquidjava" } - ] - }, - "functions": { - "patterns": [ - { "match": "\\bold\\b|\\blength\\b|\\baddToIndex\\b|\\bgetFromIndex\\b", "name": "entity.name.function.liquidjava" } - ] - }, - "operators": { - "patterns": [ - { "match": "&&|\\|\\||-->|==|!=|>=|>|<=|<|\\+|\\*|/|%|!|-|\\?|:", "name": "keyword.operator.liquidjava" } - ] - }, - "types": { - "patterns": [ - { "match": "\\b(int|double|float|boolean)\\b", "name": "storage.type.primitive.liquidjava" }, - { "match": "\\b[A-Z][a-zA-Z0-9]*\\b", "name": "entity.name.type.liquidjava" } - ] - }, - "literals": { - "patterns": [ - { "match": "\\btrue\\b|\\bfalse\\b", "name": "constant.language.boolean.liquidjava" }, - { "match": "\\d+", "name": "constant.numeric.liquidjava" } - ] - }, - "identifiers": { - "patterns": [ - { "match": "#*[a-zA-Z_][a-zA-Z0-9_#]*", "name": "variable.other.liquidjava" } - ] - }, - "qualified-names": { - "patterns": [ - { "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*\\.)+[A-Z][a-zA-Z0-9_]*\\b", "name": "entity.name.type.class.liquidjava" } - ] - } - } -} diff --git a/client/webpack.config.js b/client/webpack.config.js index 40ecd26a..94b6e749 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -1,108 +1,54 @@ //@ts-check -'use strict'; +"use strict"; -const path = require('path'); -const fs = require('fs'); - -/** @type {() => import('webpack').RuleSetRule} */ -const createTsRule = () => ({ - test: /\.ts$/, - exclude: /node_modules/, - use: [ - { - loader: 'ts-loader' - } - ] -}); - -const copyCodiconsAssets = () => { - const codiconsDist = path.resolve(__dirname, 'node_modules', '@vscode', 'codicons', 'dist'); - const codiconsDest = path.resolve(__dirname, 'media', 'codicons'); - const assets = ['codicon.css', 'codicon.ttf']; - - if (!fs.existsSync(codiconsDest)) { - fs.mkdirSync(codiconsDest, { recursive: true }); - } - - for (const asset of assets) { - fs.copyFileSync(path.resolve(codiconsDist, asset), path.resolve(codiconsDest, asset)); - } -}; +const fs = require("fs"); +const path = require("path"); /** @type {import('webpack').Configuration} */ -const extensionConfig = { - target: 'node', - mode: 'none', - entry: './src/extension.ts', +module.exports = { + target: "node", + mode: "none", + entry: "./src/extension.ts", output: { - // store bundle in dist folder - path: path.resolve(__dirname, 'dist'), - filename: 'extension.js', - libraryTarget: 'commonjs2', - devtoolModuleFilenameTemplate: '../[resource-path]' + path: path.resolve(__dirname, "dist"), + filename: "extension.js", + libraryTarget: "commonjs2", + devtoolModuleFilenameTemplate: "../[resource-path]", }, - devtool: 'source-map', + devtool: "source-map", externals: { - vscode: 'commonjs vscode' + vscode: "commonjs vscode", }, resolve: { - extensions: ['.ts', '.js'], + extensions: [".ts", ".js"], alias: { - 'vscode-languageserver-types$': path.resolve( + "vscode-languageserver-types$": path.resolve( __dirname, - 'node_modules/vscode-languageserver-types/lib/esm/main.js' - ) - } + "node_modules/vscode-languageserver-types/lib/esm/main.js" + ), + }, }, module: { - rules: [createTsRule()] + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: [{ loader: "ts-loader" }], + }, + ], }, plugins: [ { apply: (compiler) => { - compiler.hooks.afterEmit.tap('CopyCodiconsAssets', copyCodiconsAssets); - } - }, - // Copy server JAR to dist folder after build - { - apply: (compiler) => { - compiler.hooks.afterEmit.tap('CopyServerJar', () => { - const serverDir = path.resolve(__dirname, 'dist', 'server'); - const jarSource = path.resolve(__dirname, 'server', 'language-server-liquidjava.jar'); - const jarDest = path.resolve(serverDir, 'language-server-liquidjava.jar'); - if (!fs.existsSync(serverDir)) { - fs.mkdirSync(serverDir, { recursive: true }); - } - if (fs.existsSync(jarSource)) { - fs.copyFileSync(jarSource, jarDest); - console.log('Copied language-server-liquidjava.jar to dist/server/'); - } else { - console.warn('Warning: language-server-liquidjava.jar not found at', jarSource); - console.warn('Run: cd ../server && mvn clean package'); - } + compiler.hooks.afterEmit.tap("CopyServerJar", () => { + const serverDir = path.resolve(__dirname, "dist", "server"); + const jarSource = path.resolve(__dirname, "server", "language-server-liquidjava.jar"); + const jarDest = path.resolve(serverDir, "language-server-liquidjava.jar"); + if (!fs.existsSync(serverDir)) fs.mkdirSync(serverDir, { recursive: true }); + if (fs.existsSync(jarSource)) fs.copyFileSync(jarSource, jarDest); }); - } - } - ] -}; - -/** @type {import('webpack').Configuration} */ -const webviewConfig = { - target: 'web', - mode: 'none', - entry: './src/webview/main.ts', - output: { - path: path.resolve(__dirname, 'media'), - filename: 'webview.js' - }, - devtool: 'source-map', - resolve: { - extensions: ['.ts', '.js'] - }, - module: { - rules: [createTsRule()] - } + }, + }, + ], }; - -module.exports = [extensionConfig, webviewConfig]; diff --git a/server/pom.xml b/server/pom.xml index a4ccaac8..0773366d 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -6,12 +6,6 @@ vscode-liquid-java-server 0.0.1-SNAPSHOT - src/test/java - - - src/test/resources - - 3.8.0 - 3.1.2 @@ -172,7 +155,7 @@ io.github.liquid-java liquidjava-verifier - 0.0.28 + 0.0.1 tools.aqua @@ -195,37 +178,7 @@ org.eclipse.lsp4j ${lsp4j.version} - - - org.antlr - antlr4 - 4.7.1 - - - org.antlr - antlr4-runtime - 4.7.1 - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.9.3 - test - - - org.junit.platform - junit-platform-launcher - 1.9.3 - test - - language-server-liquidjava - \ No newline at end of file + diff --git a/server/src/main/java/LJDiagnostics.java b/server/src/main/java/LJDiagnostics.java index a327dc96..d9500210 100644 --- a/server/src/main/java/LJDiagnostics.java +++ b/server/src/main/java/LJDiagnostics.java @@ -1,9 +1,8 @@ import java.util.List; import liquidjava.diagnostics.errors.LJError; -import liquidjava.diagnostics.warnings.LJWarning; /** - * Container for LiquidJava diagnostics after verification + * Verifier errors produced by a verification run. */ -public record LJDiagnostics(List errors, List warnings) {} \ No newline at end of file +public record LJDiagnostics(List errors) {} diff --git a/server/src/main/java/LJDiagnosticsHandler.java b/server/src/main/java/LJDiagnosticsHandler.java index d4617fd1..98e5c67f 100644 --- a/server/src/main/java/LJDiagnosticsHandler.java +++ b/server/src/main/java/LJDiagnosticsHandler.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; @@ -13,98 +12,59 @@ import liquidjava.api.CommandLineLauncher; import liquidjava.diagnostics.Diagnostics; -import liquidjava.diagnostics.LJDiagnostic; import liquidjava.diagnostics.errors.LJError; -import liquidjava.diagnostics.warnings.LJWarning; import spoon.reflect.cu.SourcePosition; import utils.PathUtils; public class LJDiagnosticsHandler { - private static final String SOURCE = "liquidjava"; /** - * Generates LJDiagnostics for the given URI - * @param uri the document URI - * @param path the file path - * @return LJDiagnostics + * Runs the verifier and returns its errors. */ public static LJDiagnostics getLJDiagnostics(String path) throws Exception { - List errors = new ArrayList<>(); - List warnings = new ArrayList<>(); - CommandLineLauncher.cmdArgs.lspMode = true; CommandLineLauncher.launch(path); Diagnostics diagnostics = Diagnostics.getInstance(); - if (diagnostics.foundWarning()) { - warnings.addAll(diagnostics.getWarnings()); - } - if (diagnostics.foundError()) { - System.out.println("Failed verification"); - errors.addAll(diagnostics.getErrors()); - } else { - System.out.println("Passed verification"); - } - return new LJDiagnostics(errors, warnings); + List errors = diagnostics.foundError() + ? new ArrayList<>(diagnostics.getErrors()) + : Collections.emptyList(); + return new LJDiagnostics(errors); } /** - * Generates VS Code diagnostics for the given LJDiagnostics and URI - * @param diagnostics - * @param uri - * @return List of PublishDiagnosticsParams + * Converts verifier errors to standard LSP diagnostics. */ public static List getNativeDiagnostics(LJDiagnostics diagnostics, String uri) { - List errors = getDiagnostics(new ArrayList<>(diagnostics.errors()), DiagnosticSeverity.Error); - List warnings = getDiagnostics(new ArrayList<>(diagnostics.warnings()), DiagnosticSeverity.Warning); - List combined = Stream.concat(errors.stream(), warnings.stream()).collect(Collectors.toList()); - return combined.isEmpty() ? List.of(getEmptyDiagnostics(uri)) : combined; + List errors = getDiagnostics(new ArrayList<>(diagnostics.errors())); + return errors.isEmpty() ? List.of(getEmptyDiagnostics(uri)) : errors; } - /** - * Generates error and warning diagnostics - * @return diagnostics - */ - public static List getDiagnostics(List diagnostics, - DiagnosticSeverity severity) { - // group diagnostics by file + private static List getDiagnostics(List diagnostics) { Map> diagnosticsByFile = diagnostics.stream() - .collect(Collectors.groupingBy( - d -> PathUtils.toFileUri(d.getFile()), - Collectors.mapping(d -> { - Range range = getRangeFromPosition(d.getPosition()); - String message = String.format("%s: %s", d.getTitle(), d.getMessage()); - return new Diagnostic(range, message, severity, SOURCE); - }, Collectors.toList()) - )); - - // create a PublishDiagnosticsParams per file with all its diagnostics + .collect(Collectors.groupingBy( + diagnostic -> PathUtils.toFileUri(diagnostic.getFile()), + Collectors.mapping(d -> { + Range range = getRangeFromPosition(d.getPosition()); + String message = "Refinement Type Error"; + String source = d.getTitleMessage() + "\n" + d.getFullMessage(); + return new Diagnostic(range, message, DiagnosticSeverity.Error, source); + }, Collectors.toList()))); + return diagnosticsByFile.entrySet().stream() - .map(entry -> new PublishDiagnosticsParams(entry.getKey(), entry.getValue())) - .toList(); + .map(entry -> new PublishDiagnosticsParams(entry.getKey(), entry.getValue())) + .toList(); } - /** - * Generates empty diagnostics for the given URI - * @param uri the uri used for the verification - * @return PublishDiagnosticsParams - */ public static PublishDiagnosticsParams getEmptyDiagnostics(String uri) { return new PublishDiagnosticsParams(uri, Collections.emptyList()); } - /** - * Gets the Range from the given SourcePosition If the position is null, returns a default Range at (0,0)-(0,0) - * @param pos the SourcePosition - * @return Range - */ - public static Range getRangeFromPosition(SourcePosition pos) { - if (pos == null) { - // no location information available + private static Range getRangeFromPosition(SourcePosition position) { + if (position == null) { return new Range(new Position(0, 0), new Position(0, 0)); } return new Range( - new Position(pos.getLine() - 1, pos.getColumn() - 1), - new Position(pos.getEndLine() - 1, pos.getEndColumn() - 1) - ); + new Position(position.getLine() - 1, position.getColumn() - 1), + new Position(position.getEndLine() - 1, position.getEndColumn() - 1)); } } diff --git a/server/src/main/java/LJDiagnosticsService.java b/server/src/main/java/LJDiagnosticsService.java index 6ee9ed79..f11ccfa1 100644 --- a/server/src/main/java/LJDiagnosticsService.java +++ b/server/src/main/java/LJDiagnosticsService.java @@ -1,13 +1,10 @@ import java.io.File; import java.net.URI; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.lsp4j.DidChangeConfigurationParams; import org.eclipse.lsp4j.DidChangeTextDocumentParams; @@ -19,10 +16,6 @@ import org.eclipse.lsp4j.services.TextDocumentService; import org.eclipse.lsp4j.services.WorkspaceService; -import liquidjava.diagnostics.LJDiagnostic; -import liquidjava.processor.context.ContextHistory; -import utils.ContextHistoryConverter; -import utils.DiagnosticConverter; import utils.PathUtils; public class LJDiagnosticsService implements TextDocumentService, WorkspaceService { @@ -45,18 +38,8 @@ public void setWorkspaceRoot(String workspaceRoot) { this.workspaceRoot = workspaceRoot; } - /** - * Sends diagnostics notification to the client - * @param diagnostics the diagnostics to send - */ - public void sendDiagnosticsNotification(List diagnostics) { - if (this.client == null) return; - - System.out.println("Sending diagnostics notification with " + diagnostics.size() + " diagnostics"); - List dtos = diagnostics.stream() - .map(DiagnosticConverter::convertToDTO) - .collect(Collectors.toList()); - this.client.sendDiagnostics(dtos); + private boolean isInWorkspace(String uri) { + return workspaceRoot == null || PathUtils.isFileInDirectory(uri, workspaceRoot); } /** @@ -69,20 +52,15 @@ public void generateDiagnostics(String uri) { try { LJDiagnostics ljDiagnostics = LJDiagnosticsHandler.getLJDiagnostics(path); - List nativeDiagnostics = LJDiagnosticsHandler.getNativeDiagnostics(ljDiagnostics, uri); + var nativeDiagnostics = LJDiagnosticsHandler.getNativeDiagnostics(ljDiagnostics, uri); nativeDiagnostics.forEach(params -> { this.client.publishDiagnostics(params); if (!params.getDiagnostics().isEmpty()) { publishedDiagnosticUris.add(params.getUri()); } }); - List diagnostics = Stream.concat(ljDiagnostics.errors().stream(), ljDiagnostics.warnings().stream()).collect(Collectors.toList()); - sendDiagnosticsNotification(diagnostics); - this.client.sendContext(ContextHistoryConverter.convertToDTO(ContextHistory.getInstance())); } catch (Exception e) { - System.err.println("LiquidJava internal error: " + e.getMessage()); clearPublishedDiagnostics(uri); - this.client.sendFailure(); } } @@ -109,8 +87,6 @@ public void shutdown() { public void clearDiagnostic(String uri) { this.client.publishDiagnostics(LJDiagnosticsHandler.getEmptyDiagnostics(uri)); publishedDiagnosticUris.remove(uri); - // TODO: fix consistency between native and custom diagnostics - // sendDiagnosticsNotification(List.of()); } private void clearPublishedDiagnostics(String uri) { @@ -127,9 +103,8 @@ private void clearPublishedDiagnostics(String uri) { @Override public void didOpen(DidOpenTextDocumentParams params) { String uri = params.getTextDocument().getUri(); - if (!PathUtils.isFileInDirectory(uri, workspaceRoot) || initialVerification) return; + if (!isInWorkspace(uri) || initialVerification) return; initialVerification = true; - System.out.println("First document opened — checking diagnostics"); generateDiagnosticsAsync(uri); } @@ -140,8 +115,7 @@ public void didOpen(DidOpenTextDocumentParams params) { @Override public void didSave(DidSaveTextDocumentParams params) { String uri = params.getTextDocument().getUri(); - if (!PathUtils.isFileInDirectory(uri, workspaceRoot)) return; - System.out.println("Document saved — checking diagnostics"); + if (!isInWorkspace(uri)) return; clearDiagnostic(uri); generateDiagnosticsAsync(uri); } @@ -153,12 +127,11 @@ public void didSave(DidSaveTextDocumentParams params) { @Override public void didClose(DidCloseTextDocumentParams params) { String uri = params.getTextDocument().getUri(); - if (!PathUtils.isFileInDirectory(uri, workspaceRoot)) return; + if (!isInWorkspace(uri)) return; try { // check if the file still exists on disk File file = new File(new URI(uri)); if (!file.exists()) { - System.out.println("File deleted — clearing diagnostic"); clearDiagnostic(uri); } } catch (Exception e) {} diff --git a/server/src/main/java/LJLanguageClient.java b/server/src/main/java/LJLanguageClient.java index fe194f3e..ce6a107c 100644 --- a/server/src/main/java/LJLanguageClient.java +++ b/server/src/main/java/LJLanguageClient.java @@ -1,33 +1,6 @@ -import java.util.List; - import org.eclipse.lsp4j.services.LanguageClient; -import dtos.context.ContextHistoryDTO; - -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; - /** - * Language client interface to specify custom notifications + * Standard LSP client used to publish verifier errors. */ -public interface LJLanguageClient extends LanguageClient { - - /** - * Sends custom diagnostics notification to the client - * @param diagnostics the LiquidJava diagnostics to send - */ - @JsonNotification("liquidjava/diagnostics") - void sendDiagnostics(List diagnostics); - - /** - * Sends a verifier failure notification to the client - */ - @JsonNotification("liquidjava/failure") - void sendFailure(); - - /** - * Sends the context history to the client - * @param contextHistory the context history to send - */ - @JsonNotification("liquidjava/context") - void sendContext(ContextHistoryDTO contextHistory); -} +public interface LJLanguageClient extends LanguageClient {} diff --git a/server/src/main/java/LJLanguageServer.java b/server/src/main/java/LJLanguageServer.java index 889c1eac..de6f5e2e 100644 --- a/server/src/main/java/LJLanguageServer.java +++ b/server/src/main/java/LJLanguageServer.java @@ -1,6 +1,4 @@ import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; @@ -8,76 +6,54 @@ import org.eclipse.lsp4j.TextDocumentSyncKind; import org.eclipse.lsp4j.WorkspaceFoldersOptions; import org.eclipse.lsp4j.WorkspaceServerCapabilities; -import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.lsp4j.services.TextDocumentService; import org.eclipse.lsp4j.services.WorkspaceService; -import dtos.uri.Uri; -import fsm.StateMachine; -import fsm.StateMachineParser; - public class LJLanguageServer implements LanguageServer { private final LJDiagnosticsService diagnosticsService; - private final ExecutorService stateMachineExecutor; public LJLanguageServer() { this.diagnosticsService = new LJDiagnosticsService(); - this.stateMachineExecutor = Executors.newSingleThreadExecutor(r -> { - Thread thread = new Thread(r, "liquidjava-fsm"); - thread.setDaemon(true); - return thread; - }); } - /** - * Initializes the language server with the given parameters - * @param params the initialize parameters - * @return CompletableFuture with the InitializeResult - */ + @Override public CompletableFuture initialize(InitializeParams params) { - CompletableFuture completableFuture = new CompletableFuture<>(); ServerCapabilities capabilities = new ServerCapabilities(); - WorkspaceServerCapabilities workspaceServerCapabilities = new WorkspaceServerCapabilities(); WorkspaceFoldersOptions workspaceFoldersOptions = new WorkspaceFoldersOptions(); + WorkspaceServerCapabilities workspaceCapabilities = new WorkspaceServerCapabilities(); - // extract workspace root from initialization params if (params.getWorkspaceFolders() != null && !params.getWorkspaceFolders().isEmpty()) { - String workspaceRoot = params.getWorkspaceFolders().get(0).getUri(); - diagnosticsService.setWorkspaceRoot(workspaceRoot); + diagnosticsService.setWorkspaceRoot(params.getWorkspaceFolders().get(0).getUri()); } - // set options workspaceFoldersOptions.setChangeNotifications(true); workspaceFoldersOptions.setSupported(true); - workspaceServerCapabilities.setWorkspaceFolders(workspaceFoldersOptions); - capabilities.setWorkspace(workspaceServerCapabilities); + workspaceCapabilities.setWorkspaceFolders(workspaceFoldersOptions); + capabilities.setWorkspace(workspaceCapabilities); capabilities.setDocumentSymbolProvider(false); capabilities.setTextDocumentSync(TextDocumentSyncKind.Full); - capabilities.setDocumentLinkProvider(null); // new DocumentLinkOptions(true)); - // More in: - // https://github.com/nedap/archetype-languageserver/blob/24b0890c0f046c6c1af8269a5c9770a8860a96b3/src/main/java/com/nedap/openehr/lsp/ADL2LanguageServer.java - - completableFuture.complete(new InitializeResult(capabilities)); - return completableFuture; + return CompletableFuture.completedFuture(new InitializeResult(capabilities)); } + @Override public CompletableFuture shutdown() { diagnosticsService.shutdown(); - stateMachineExecutor.shutdownNow(); return CompletableFuture.completedFuture(null); } + @Override public void exit() { System.exit(1); } + @Override public TextDocumentService getTextDocumentService() { return diagnosticsService; } + @Override public WorkspaceService getWorkspaceService() { return diagnosticsService; } @@ -85,20 +61,4 @@ public WorkspaceService getWorkspaceService() { public void connect(LJLanguageClient client) { diagnosticsService.setClient(client); } - - @SuppressWarnings("unused") - @JsonNotification("$/setTraceNotification") - public void setTrace(Object params) { - // suppress notification - } - - @JsonRequest("liquidjava/fsm") - public CompletableFuture fsm(Uri uri) { - return CompletableFuture.supplyAsync(() -> StateMachineParser.parse(uri.uri()), stateMachineExecutor); - } - - @JsonNotification("liquidjava/verify") - public void verify(Uri uri) { - diagnosticsService.generateDiagnosticsAsync(uri.uri()); - } } diff --git a/server/src/main/java/dtos/context/AliasDTO.java b/server/src/main/java/dtos/context/AliasDTO.java deleted file mode 100644 index 4a5b530e..00000000 --- a/server/src/main/java/dtos/context/AliasDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package dtos.context; - -import java.util.List; -import java.util.stream.Collectors; - -import liquidjava.processor.context.AliasWrapper; - -/** - * DTO for serializing AliasWrapper instances to JSON. - */ -public record AliasDTO( - String name, - List parameters, - List types, - String predicate -) { - public static AliasDTO from(AliasWrapper aliasWrapper) { - return new AliasDTO( - aliasWrapper.getName(), - aliasWrapper.getVarNames(), - aliasWrapper.getTypes().stream().map(ContextHistoryDTO::stringifyType).collect(Collectors.toList()), - aliasWrapper.getClonedPredicate().toString() - ); - } -} \ No newline at end of file diff --git a/server/src/main/java/dtos/context/ContextHistoryDTO.java b/server/src/main/java/dtos/context/ContextHistoryDTO.java deleted file mode 100644 index 19debbd6..00000000 --- a/server/src/main/java/dtos/context/ContextHistoryDTO.java +++ /dev/null @@ -1,26 +0,0 @@ -package dtos.context; - -import java.util.List; -import java.util.Map; - -import dtos.diagnostics.SourcePositionDTO; -import spoon.reflect.reference.CtTypeReference; - -/** - * DTO for serializing ContextHistory instances to JSON. - */ -public record ContextHistoryDTO( - List localVars, - List globalVars, - List ghosts, - List aliases, - List methods, - Map> fileScopes -) { - public static String stringifyType(CtTypeReference typeReference) { - if (typeReference == null) - return ""; - String qualifiedName = typeReference.getQualifiedName(); - return qualifiedName == null || qualifiedName.isBlank() ? typeReference.toString() : qualifiedName; - } -} diff --git a/server/src/main/java/dtos/context/GhostDTO.java b/server/src/main/java/dtos/context/GhostDTO.java deleted file mode 100644 index 825d796c..00000000 --- a/server/src/main/java/dtos/context/GhostDTO.java +++ /dev/null @@ -1,37 +0,0 @@ -package dtos.context; - -import java.util.List; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import liquidjava.processor.context.GhostState; - -/** - * DTO for serializing GhostState instances to JSON. - */ -public record GhostDTO( - String name, - String qualifiedName, - String returnType, - List parameterTypes, - String refinement, - boolean isState, - String file -) { - private static final Pattern STATE_REFINEMENT_PATTERN = Pattern.compile("^state\\d+\\(_\\) == \\d+$"); - - public static GhostDTO from(GhostState ghostState) { - String refinement = ghostState.getRefinement() != null ? ghostState.getRefinement().toString() : null; - boolean isState = refinement != null && STATE_REFINEMENT_PATTERN.matcher(refinement).matches(); - - return new GhostDTO( - ghostState.getName(), - ghostState.getQualifiedName(), - ContextHistoryDTO.stringifyType(ghostState.getReturnType()), - ghostState.getParametersTypes().stream().map(ContextHistoryDTO::stringifyType).collect(Collectors.toList()), - refinement, - isState, - ghostState.getFile() - ); - } -} \ No newline at end of file diff --git a/server/src/main/java/dtos/context/MethodDTO.java b/server/src/main/java/dtos/context/MethodDTO.java deleted file mode 100644 index 04d3fad7..00000000 --- a/server/src/main/java/dtos/context/MethodDTO.java +++ /dev/null @@ -1,46 +0,0 @@ -package dtos.context; - -import java.util.List; -import java.util.stream.Collectors; - -import dtos.diagnostics.SourcePositionDTO; -import liquidjava.processor.context.ObjectState; -import liquidjava.processor.context.RefinedFunction; -import liquidjava.rj_language.Predicate; -import liquidjava.rj_language.ast.formatter.ExpressionFormatter; - -/** - * DTO for serializing RefinedFunction instances to JSON. - */ -public record MethodDTO( - String name, - String targetClass, - String returnRefinement, - List parameters, - List stateRefinements, - SourcePositionDTO position -) { - public static MethodDTO from(RefinedFunction refinedFunction) { - return new MethodDTO( - refinedFunction.getName(), - refinedFunction.getTargetClass(), - format(refinedFunction.getRefReturn()), - refinedFunction.getArguments().stream().map(VariableDTO::from).filter(v -> v != null).collect(Collectors.toList()), - refinedFunction.getAllStates().stream().map(StateRefinementDTO::from).collect(Collectors.toList()), - SourcePositionDTO.from(refinedFunction.getPlacementInCode().getPosition()) - ); - } - - public record StateRefinementDTO(String from, String to) { - public static StateRefinementDTO from(ObjectState state) { - return new StateRefinementDTO( - state.hasFrom() ? format(state.getFrom()) : null, - state.hasTo() ? format(state.getTo()) : null - ); - } - } - - private static String format(Predicate predicate) { - return predicate == null ? "" : ExpressionFormatter.format(predicate); - } -} diff --git a/server/src/main/java/dtos/context/VariableDTO.java b/server/src/main/java/dtos/context/VariableDTO.java deleted file mode 100644 index f643266a..00000000 --- a/server/src/main/java/dtos/context/VariableDTO.java +++ /dev/null @@ -1,34 +0,0 @@ -package dtos.context; - -import dtos.diagnostics.SourcePositionDTO; -import liquidjava.processor.context.PlacementInCode; -import liquidjava.processor.context.RefinedVariable; -import liquidjava.rj_language.ast.formatter.ExpressionFormatter; -import liquidjava.rj_language.ast.formatter.VariableFormatter; - -/** - * DTO for serializing RefinedVariable instances to JSON. - */ -public record VariableDTO( - String name, - String internalName, - String type, - String refinement, - String mainRefinement, - SourcePositionDTO position, - SourcePositionDTO annotationPosition -) { - public static VariableDTO from(RefinedVariable refinedVariable) { - PlacementInCode placement = refinedVariable.getPlacementInCode(); - if (placement == null) return null; - return new VariableDTO( - VariableFormatter.format(refinedVariable.getName()), - refinedVariable.getName(), - ContextHistoryDTO.stringifyType(refinedVariable.getType()), - ExpressionFormatter.format(refinedVariable.getRefinement()), - ExpressionFormatter.format(refinedVariable.getMainRefinement()), - SourcePositionDTO.from(placement.getPosition()), - SourcePositionDTO.from(placement.getAnnotationPosition()) - ); - } -} \ No newline at end of file diff --git a/server/src/main/java/dtos/diagnostics/LJDiagnosticDTO.java b/server/src/main/java/dtos/diagnostics/LJDiagnosticDTO.java deleted file mode 100644 index 83d8d88d..00000000 --- a/server/src/main/java/dtos/diagnostics/LJDiagnosticDTO.java +++ /dev/null @@ -1,37 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.diagnostics.LJDiagnostic; - -/** - * DTO for serializing LJDiagnostic instances to JSON - */ -public class LJDiagnosticDTO { - - public final String category; - public final String type; - public final String title; - public final String message; - public final String details; - public final String file; - public final SourcePositionDTO position; - - public LJDiagnosticDTO(String category, String type, LJDiagnostic diagnostic) { - this(category, type, diagnostic.getTitle(), diagnostic.getMessage(), diagnostic.getDetails(), - diagnostic.getFile(), SourcePositionDTO.from(diagnostic.getPosition())); - } - - public LJDiagnosticDTO(String category, String type, String title, String message, String details, String file, - SourcePositionDTO position) { - this.category = category; - this.type = type; - this.title = title; - this.message = message; - this.details = details; - this.file = file; - this.position = position; - } - - public static LJDiagnosticDTO from(LJDiagnostic diagnostic) { - return new LJDiagnosticDTO(null, null, diagnostic); - } -} diff --git a/server/src/main/java/dtos/diagnostics/PlacementInCodeDTO.java b/server/src/main/java/dtos/diagnostics/PlacementInCodeDTO.java deleted file mode 100644 index f782c8fc..00000000 --- a/server/src/main/java/dtos/diagnostics/PlacementInCodeDTO.java +++ /dev/null @@ -1,15 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.processor.context.PlacementInCode; - -/** - * DTO for serializing PlacementInCode instances to JSON - */ -public record PlacementInCodeDTO(String text, SourcePositionDTO position) { - - public static PlacementInCodeDTO from(PlacementInCode placement) { - if (placement == null) - return null; - return new PlacementInCodeDTO(placement.getText(), SourcePositionDTO.from(placement.getPosition())); - } -} diff --git a/server/src/main/java/dtos/diagnostics/RefinementDTO.java b/server/src/main/java/dtos/diagnostics/RefinementDTO.java deleted file mode 100644 index 5489f40e..00000000 --- a/server/src/main/java/dtos/diagnostics/RefinementDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.rj_language.Predicate; -import liquidjava.rj_language.ast.formatter.ExpressionFormatter; - -/** - * DTO for serializing refinement predicates. - */ -public record RefinementDTO(String predicate) { - - public static RefinementDTO from(Predicate refinement) { - if (refinement == null) - return null; - - return new RefinementDTO(ExpressionFormatter.format(refinement)); - } -} diff --git a/server/src/main/java/dtos/diagnostics/SourcePositionDTO.java b/server/src/main/java/dtos/diagnostics/SourcePositionDTO.java deleted file mode 100644 index ca9e8b64..00000000 --- a/server/src/main/java/dtos/diagnostics/SourcePositionDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package dtos.diagnostics; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import spoon.reflect.cu.SourcePosition; - -public record SourcePositionDTO(String file, int lineStart, int colStart, int lineEnd, int colEnd) { - - public static SourcePositionDTO from(SourcePosition pos) { - if (pos == null) return null; - try { - String file = pos.getFile() != null ? pos.getFile().getAbsolutePath() : null; - return new SourcePositionDTO(file, pos.getLine() - 1, pos.getColumn() - 1, pos.getEndLine() - 1, pos.getEndColumn()); - } catch (UnsupportedOperationException e) { - return null; - } - } - - public static SourcePositionDTO from(String pos) { - if (pos == null) return null; - Pattern p = Pattern.compile("(\\d+):(\\d+)-(\\d+):(\\d+)"); - Matcher m = p.matcher(pos); - if (!m.matches()) return null; - - int line = Integer.parseInt(m.group(1)); - int column = Integer.parseInt(m.group(2)); - int endLine = Integer.parseInt(m.group(3)); - int endColumn = Integer.parseInt(m.group(4)); - return new SourcePositionDTO(null, line - 1, column - 1, endLine - 1, endColumn); - } -} diff --git a/server/src/main/java/dtos/diagnostics/TranslationTableDTO.java b/server/src/main/java/dtos/diagnostics/TranslationTableDTO.java deleted file mode 100644 index c1a0f56f..00000000 --- a/server/src/main/java/dtos/diagnostics/TranslationTableDTO.java +++ /dev/null @@ -1,23 +0,0 @@ -package dtos.diagnostics; - -import java.util.HashMap; - -import liquidjava.diagnostics.TranslationTable; -import liquidjava.rj_language.ast.formatter.VariableFormatter; - -/** - * DTO for serializing TranslationTable to JSON - * Converts the complex Spoon objects to simple serializable objects - */ -public class TranslationTableDTO extends HashMap { - - public static TranslationTableDTO from(TranslationTable translationTable) { - TranslationTableDTO dto = new TranslationTableDTO(); - if (translationTable != null) { - translationTable.forEach((key, value) -> { - dto.put(VariableFormatter.format(key), PlacementInCodeDTO.from(value)); - }); - } - return dto; - } -} diff --git a/server/src/main/java/dtos/diagnostics/VCBinderDTO.java b/server/src/main/java/dtos/diagnostics/VCBinderDTO.java deleted file mode 100644 index 80027434..00000000 --- a/server/src/main/java/dtos/diagnostics/VCBinderDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.processor.VCImplication; -import liquidjava.rj_language.ast.formatter.VariableFormatter; -import liquidjava.utils.Utils; - -/** - * DTO for serializing the binder part of a VC implication node. - */ -public record VCBinderDTO(String name, String type) { - - public static VCBinderDTO from(VCImplication implication) { - if (implication == null || !implication.hasBinder()) - return null; - - String qualifiedType = implication.getType().getQualifiedName(); - String simpleType = qualifiedType.contains(".") ? Utils.getSimpleName(qualifiedType) : qualifiedType; - return new VCBinderDTO(VariableFormatter.format(implication.getName()), simpleType); - } -} diff --git a/server/src/main/java/dtos/diagnostics/VCImplicationDTO.java b/server/src/main/java/dtos/diagnostics/VCImplicationDTO.java deleted file mode 100644 index 4bc76f4b..00000000 --- a/server/src/main/java/dtos/diagnostics/VCImplicationDTO.java +++ /dev/null @@ -1,28 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.processor.VCImplication; -import liquidjava.rj_language.ast.formatter.VariableFormatter; -import liquidjava.utils.Utils; - -/** - * DTO for serializing a complete VC implication chain. - */ -public record VCImplicationDTO(String name, String type, String predicate, VCImplicationDTO next) { - - public static VCImplicationDTO from(VCImplication implication) { - if (implication == null) - return null; - - String name = null; - String type = null; - if (implication.hasBinder()) { - name = VariableFormatter.format(implication.getName()); - type = Utils.getSimpleName(implication.getType().getQualifiedName()); - } - return new VCImplicationDTO( - name, - type, - implication.getRefinement().getExpression().toDisplayString(), - from(implication.getNext())); - } -} diff --git a/server/src/main/java/dtos/diagnostics/VCSimplificationResultDTO.java b/server/src/main/java/dtos/diagnostics/VCSimplificationResultDTO.java deleted file mode 100644 index 0dc9d262..00000000 --- a/server/src/main/java/dtos/diagnostics/VCSimplificationResultDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.diagnostics; - -import liquidjava.rj_language.opt.VCSimplificationResult; - -/** - * DTO for serializing a simplified VC and its complete predecessor states. - */ -public record VCSimplificationResultDTO(VCImplicationDTO implication, VCSimplificationResultDTO origin, String simplification) { - - public static VCSimplificationResultDTO from(VCSimplificationResult result) { - if (result == null) - return null; - - return new VCSimplificationResultDTO( - VCImplicationDTO.from(result.getImplication()), - from(result.getOrigin()), - result.getSimplification() - ); - } -} diff --git a/server/src/main/java/dtos/errors/ArgumentMismatchErrorDTO.java b/server/src/main/java/dtos/errors/ArgumentMismatchErrorDTO.java deleted file mode 100644 index 6f700b00..00000000 --- a/server/src/main/java/dtos/errors/ArgumentMismatchErrorDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.ArgumentMismatchError; - -/** - * DTO for serializing ArgumentMismatchErrorDTO instances to JSON - */ -public class ArgumentMismatchErrorDTO extends LJErrorDTO { - - public ArgumentMismatchErrorDTO(ArgumentMismatchError error) { - super("argument-mismatch-error", error); - } - - public static ArgumentMismatchErrorDTO from(ArgumentMismatchError error) { - return new ArgumentMismatchErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/CustomErrorDTO.java b/server/src/main/java/dtos/errors/CustomErrorDTO.java deleted file mode 100644 index e8c48d25..00000000 --- a/server/src/main/java/dtos/errors/CustomErrorDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.CustomError; - -/** - * DTO for serializing CustomError instances to JSON - */ -public class CustomErrorDTO extends LJErrorDTO { - - public CustomErrorDTO(CustomError error) { - super("custom-error", error); - } - - public static CustomErrorDTO from(CustomError error) { - return new CustomErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/IllegalConstructorTransitionErrorDTO.java b/server/src/main/java/dtos/errors/IllegalConstructorTransitionErrorDTO.java deleted file mode 100644 index 08af9829..00000000 --- a/server/src/main/java/dtos/errors/IllegalConstructorTransitionErrorDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.IllegalConstructorTransitionError; - -/** - * DTO for serializing IllegalConstructorTransitionError instances to JSON - */ -public class IllegalConstructorTransitionErrorDTO extends LJErrorDTO { - - public IllegalConstructorTransitionErrorDTO(IllegalConstructorTransitionError error) { - super("illegal-constructor-transition-error", error); - } - - public static IllegalConstructorTransitionErrorDTO from(IllegalConstructorTransitionError error) { - return new IllegalConstructorTransitionErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/InvalidRefinementErrorDTO.java b/server/src/main/java/dtos/errors/InvalidRefinementErrorDTO.java deleted file mode 100644 index 7e745d48..00000000 --- a/server/src/main/java/dtos/errors/InvalidRefinementErrorDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.InvalidRefinementError; - -/** - * DTO for serializing InvalidRefinementError instances to JSON - */ -public class InvalidRefinementErrorDTO extends LJErrorDTO { - - public final String refinement; - - public InvalidRefinementErrorDTO(InvalidRefinementError error) { - super("invalid-refinement-error", error); - this.refinement = error.getRefinement(); - } - - public static InvalidRefinementErrorDTO from(InvalidRefinementError error) { - return new InvalidRefinementErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/LJErrorDTO.java b/server/src/main/java/dtos/errors/LJErrorDTO.java deleted file mode 100644 index 82efc118..00000000 --- a/server/src/main/java/dtos/errors/LJErrorDTO.java +++ /dev/null @@ -1,34 +0,0 @@ -package dtos.errors; - -import dtos.diagnostics.LJDiagnosticDTO; -import dtos.diagnostics.SourcePositionDTO; -import dtos.diagnostics.TranslationTableDTO; -import liquidjava.diagnostics.errors.LJError; - -/** - * DTO for serializing LJError instances to JSON - */ -public class LJErrorDTO extends LJDiagnosticDTO { - - public final TranslationTableDTO translationTable; - - public LJErrorDTO(String type, LJError error) { - super("error", type, error); - this.translationTable = TranslationTableDTO.from(error.getTranslationTable()); - } - - protected LJErrorDTO(String category, String type, LJError error) { - super(category, type, error); - this.translationTable = TranslationTableDTO.from(error.getTranslationTable()); - } - - public LJErrorDTO(String category, String type, String title, String message, String details, String file, - SourcePositionDTO position, TranslationTableDTO translationTable) { - super(category, type, title, message, details, file, position); - this.translationTable = translationTable; - } - - public static LJErrorDTO from(LJError error) { - return new LJErrorDTO(null, error); - } -} diff --git a/server/src/main/java/dtos/errors/NotFoundErrorDTO.java b/server/src/main/java/dtos/errors/NotFoundErrorDTO.java deleted file mode 100644 index 72f0cf94..00000000 --- a/server/src/main/java/dtos/errors/NotFoundErrorDTO.java +++ /dev/null @@ -1,22 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.NotFoundError; - -/** - * DTO for serializing NotFoundError instances to JSON - */ -public class NotFoundErrorDTO extends LJErrorDTO { - - public final String name; - public final String kind; - - public NotFoundErrorDTO(NotFoundError error) { - super("not-found-error", error); - this.name = error.getName(); - this.kind = error.getKind(); - } - - public static NotFoundErrorDTO from(NotFoundError error) { - return new NotFoundErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/RefinementErrorDTO.java b/server/src/main/java/dtos/errors/RefinementErrorDTO.java deleted file mode 100644 index 599fd21f..00000000 --- a/server/src/main/java/dtos/errors/RefinementErrorDTO.java +++ /dev/null @@ -1,28 +0,0 @@ -package dtos.errors; - -import dtos.diagnostics.VCSimplificationResultDTO; -import liquidjava.diagnostics.errors.RefinementError; -import liquidjava.rj_language.ast.formatter.ExpressionFormatter; - -/** - * DTO for serializing RefinementError instances to JSON - */ -public class RefinementErrorDTO extends LJErrorDTO { - - public final String expected; - public final VCSimplificationResultDTO found; - public final String customMessage; - public final String counterexample; - - public RefinementErrorDTO(RefinementError error) { - super("refinement-error", error); - this.expected = error.getExpected() == null ? null : ExpressionFormatter.format(error.getExpected()); - this.found = VCSimplificationResultDTO.from(error.getFound()); - this.customMessage = error.getCustomMessage(); - this.counterexample = error.getCounterExampleString(); - } - - public static RefinementErrorDTO from(RefinementError error) { - return new RefinementErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/StateConflictErrorDTO.java b/server/src/main/java/dtos/errors/StateConflictErrorDTO.java deleted file mode 100644 index db58642c..00000000 --- a/server/src/main/java/dtos/errors/StateConflictErrorDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.StateConflictError; - -/** - * DTO for serializing StateConflictError instances to JSON - */ -public class StateConflictErrorDTO extends LJErrorDTO { - - public final String state; - - public StateConflictErrorDTO(StateConflictError error) { - super("state-conflict-error", error); - this.state = error.getState(); - } - - public static StateConflictErrorDTO from(StateConflictError error) { - return new StateConflictErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/StateRefinementErrorDTO.java b/server/src/main/java/dtos/errors/StateRefinementErrorDTO.java deleted file mode 100644 index a985e2fe..00000000 --- a/server/src/main/java/dtos/errors/StateRefinementErrorDTO.java +++ /dev/null @@ -1,26 +0,0 @@ -package dtos.errors; - -import dtos.diagnostics.VCSimplificationResultDTO; -import liquidjava.diagnostics.errors.StateRefinementError; -import liquidjava.rj_language.ast.formatter.ExpressionFormatter; - -/** - * DTO for serializing StateRefinementError instances to JSON - */ -public class StateRefinementErrorDTO extends LJErrorDTO { - - public final String expected; - public final VCSimplificationResultDTO found; - public final String customMessage; - - public StateRefinementErrorDTO(StateRefinementError error) { - super("state-refinement-error", error); - this.expected = error.getExpected() == null ? null : ExpressionFormatter.format(error.getExpected()); - this.found = VCSimplificationResultDTO.from(error.getFoundSimplification()); - this.customMessage = error.getCustomMessage(); - } - - public static StateRefinementErrorDTO from(StateRefinementError error) { - return new StateRefinementErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/errors/SyntaxErrorDTO.java b/server/src/main/java/dtos/errors/SyntaxErrorDTO.java deleted file mode 100644 index e08cd84d..00000000 --- a/server/src/main/java/dtos/errors/SyntaxErrorDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.errors; - -import liquidjava.diagnostics.errors.SyntaxError; - -/** - * DTO for serializing SyntaxError instances to JSON - */ -public class SyntaxErrorDTO extends LJErrorDTO { - - public final String refinement; - - public SyntaxErrorDTO(SyntaxError error) { - super("syntax-error", error); - this.refinement = error.getRefinement(); - } - - public static SyntaxErrorDTO from(SyntaxError error) { - return new SyntaxErrorDTO(error); - } -} diff --git a/server/src/main/java/dtos/uri/Uri.java b/server/src/main/java/dtos/uri/Uri.java deleted file mode 100644 index 6146ae09..00000000 --- a/server/src/main/java/dtos/uri/Uri.java +++ /dev/null @@ -1,3 +0,0 @@ -package dtos.uri; - -public record Uri(String uri) {} \ No newline at end of file diff --git a/server/src/main/java/dtos/warnings/CustomWarningDTO.java b/server/src/main/java/dtos/warnings/CustomWarningDTO.java deleted file mode 100644 index 740351e4..00000000 --- a/server/src/main/java/dtos/warnings/CustomWarningDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package dtos.warnings; - -import liquidjava.diagnostics.warnings.CustomWarning; - -/** - * DTO for serializing CustomError instances to JSON - */ -public class CustomWarningDTO extends LJWarningDTO { - - public CustomWarningDTO(CustomWarning warning) { - super("custom-warning", warning); - } - - public static CustomWarningDTO from(CustomWarning warning) { - return new CustomWarningDTO(warning); - } -} diff --git a/server/src/main/java/dtos/warnings/ExternalClassNotFoundWarningDTO.java b/server/src/main/java/dtos/warnings/ExternalClassNotFoundWarningDTO.java deleted file mode 100644 index e380c31e..00000000 --- a/server/src/main/java/dtos/warnings/ExternalClassNotFoundWarningDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.warnings; - -import liquidjava.diagnostics.warnings.ExternalClassNotFoundWarning; - -/** - * DTO for serializing ExternalClassNotFoundWarning instances to JSON - */ -public class ExternalClassNotFoundWarningDTO extends LJWarningDTO { - - public final String className; - - public ExternalClassNotFoundWarningDTO(ExternalClassNotFoundWarning warning) { - super("external-class-not-found-warning", warning); - this.className = warning.getClassName(); - } - - public static ExternalClassNotFoundWarningDTO from(ExternalClassNotFoundWarning warning) { - return new ExternalClassNotFoundWarningDTO(warning); - } -} diff --git a/server/src/main/java/dtos/warnings/ExternalMethodNotFoundWarningDTO.java b/server/src/main/java/dtos/warnings/ExternalMethodNotFoundWarningDTO.java deleted file mode 100644 index c5d695d5..00000000 --- a/server/src/main/java/dtos/warnings/ExternalMethodNotFoundWarningDTO.java +++ /dev/null @@ -1,24 +0,0 @@ -package dtos.warnings; - -import liquidjava.diagnostics.warnings.ExternalMethodNotFoundWarning; - -/** - * DTO for serializing ExternalMethodNotFoundWarning instances to JSON - */ -public class ExternalMethodNotFoundWarningDTO extends LJWarningDTO { - - public final String signature; - public final String className; - public final String[] overloads; - - public ExternalMethodNotFoundWarningDTO(ExternalMethodNotFoundWarning warning) { - super("external-method-not-found-warning", warning); - this.signature = warning.getSignature(); - this.className = warning.getClassName(); - this.overloads = warning.getOverloads(); - } - - public static ExternalMethodNotFoundWarningDTO from(ExternalMethodNotFoundWarning warning) { - return new ExternalMethodNotFoundWarningDTO(warning); - } -} diff --git a/server/src/main/java/dtos/warnings/LJWarningDTO.java b/server/src/main/java/dtos/warnings/LJWarningDTO.java deleted file mode 100644 index 6e41d990..00000000 --- a/server/src/main/java/dtos/warnings/LJWarningDTO.java +++ /dev/null @@ -1,22 +0,0 @@ -package dtos.warnings; - -import dtos.diagnostics.LJDiagnosticDTO; -import liquidjava.diagnostics.warnings.LJWarning; - -/** - * DTO for serializing LJWarning instances to JSON - */ -public class LJWarningDTO extends LJDiagnosticDTO { - - public LJWarningDTO(String type, LJWarning warning) { - super("warning", type, warning); - } - - protected LJWarningDTO(String category, String type, LJWarning warning) { - super(category, type, warning); - } - - public static LJWarningDTO from(LJWarning warning) { - return new LJWarningDTO(null, warning); - } -} diff --git a/server/src/main/java/dtos/warnings/UnsatisfiableRefinementWarningDTO.java b/server/src/main/java/dtos/warnings/UnsatisfiableRefinementWarningDTO.java deleted file mode 100644 index a127460a..00000000 --- a/server/src/main/java/dtos/warnings/UnsatisfiableRefinementWarningDTO.java +++ /dev/null @@ -1,20 +0,0 @@ -package dtos.warnings; - -import liquidjava.diagnostics.warnings.UnsatisfiableRefinementWarning; - -/** - * DTO for serializing UnsatisfiableRefinementWarning instances to JSON - */ -public class UnsatisfiableRefinementWarningDTO extends LJWarningDTO { - - public final String refinement; - - public UnsatisfiableRefinementWarningDTO(UnsatisfiableRefinementWarning warning) { - super("unsatisfiable-refinement-warning", warning); - this.refinement = warning.getRefinement(); - } - - public static UnsatisfiableRefinementWarningDTO from(UnsatisfiableRefinementWarning warning) { - return new UnsatisfiableRefinementWarningDTO(warning); - } -} diff --git a/server/src/main/java/fsm/StateMachine.java b/server/src/main/java/fsm/StateMachine.java deleted file mode 100644 index f2cee343..00000000 --- a/server/src/main/java/fsm/StateMachine.java +++ /dev/null @@ -1,13 +0,0 @@ -package fsm; - -import java.util.List; - -/** - * Represents a state machine - */ -public record StateMachine( - String className, - List states, - List transitions, - List initialTransitions -) { } diff --git a/server/src/main/java/fsm/StateMachineInitialTransition.java b/server/src/main/java/fsm/StateMachineInitialTransition.java deleted file mode 100644 index 23a9b9c1..00000000 --- a/server/src/main/java/fsm/StateMachineInitialTransition.java +++ /dev/null @@ -1,11 +0,0 @@ -package fsm; - -/** - * Represents an initial transition in a state machine - */ -public record StateMachineInitialTransition(String to, String postCond) { - - public StateMachineInitialTransition(String to) { - this(to, null); - } -} diff --git a/server/src/main/java/fsm/StateMachineParser.java b/server/src/main/java/fsm/StateMachineParser.java deleted file mode 100644 index 5a8dfb32..00000000 --- a/server/src/main/java/fsm/StateMachineParser.java +++ /dev/null @@ -1,414 +0,0 @@ -package fsm; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import liquidjava.rj_language.ast.*; -import liquidjava.rj_language.parsing.RefinementsParser; -import liquidjava.utils.Utils; -import spoon.Launcher; -import spoon.reflect.CtModel; -import spoon.reflect.declaration.CtAnnotation; -import spoon.reflect.declaration.CtClass; -import spoon.reflect.declaration.CtElement; -import spoon.reflect.declaration.CtMethod; -import spoon.reflect.declaration.CtType; - -public class StateMachineParser { - - private static final String STATE_SET_ANNOTATION = "StateSet"; - private static final String STATE_REFINEMENT_ANNOTATION = "StateRefinement"; - private static final String EXTERNAL_REFINEMENTS_FOR_ANNOTATION = "ExternalRefinementsFor"; - - private record TransitionSource(String from, String cond) {} - - /** - * Parses a class or interface for the given uri and extracts the state machine information - * @param uri the document URI - * @return StateMachine or null if none found - */ - public static StateMachine parse(String uri) { - try { - String filePath = new URI(uri).getPath(); - Launcher launcher = new Launcher(); - launcher.getEnvironment().setNoClasspath(true); - launcher.getEnvironment().setAutoImports(true); - launcher.addInputResource(filePath); - launcher.buildModel(); - CtModel model = launcher.getModel(); - - // get class or interface - CtType ctType = getType(model); - if (ctType == null) - return null; // no class or interface found - - // extract class name and states - List states = getStates(ctType); - if (states == null || states.isEmpty()) - return null; // no states found - String className = getClassName(ctType); - - // get initial transitions and method transitions - List initialTransitions = getInitialTransitions(ctType, className, states); - if (initialTransitions.isEmpty()) { - initialTransitions = List.of(new StateMachineInitialTransition(states.get(0))); - } - List transitions = getTransitions(ctType, className, states); - if (transitions.isEmpty()) - return null; // no transitions found - - return new StateMachine(className, states, transitions, initialTransitions); - - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Finds the first class or interface in the model (we assume only one per file) - * @param model the CtModel - * @return CtType or null if none found - */ - private static CtType getType(CtModel model) { - for (CtType type : model.getAllTypes()) { - if (type.isClass() || type.isInterface()) - return type; - } - return null; - } - - /** - * Gets the simple name from a class or interface - * Uses name from ExternalRefinementsFor if present, otherwise uses class or interface name - * @param ctType the CtType (class or interface) - * @return class name - */ - private static String getClassName(CtType ctType) { - for (CtAnnotation annotation : ctType.getAnnotations()) { - if (annotation.getAnnotationType().getSimpleName().equals(EXTERNAL_REFINEMENTS_FOR_ANNOTATION)) { - String qualifiedName = (String) annotation.getValueAsObject("value"); - return Utils.getSimpleName(qualifiedName); - } - } - return ctType.getSimpleName(); - } - - /** - * Gets the possible states from a class or interface - * @param ctType the CtType (class or interface) - * @return list of states - */ - private static List getStates(CtType ctType) { - for (CtAnnotation annotation : ctType.getAnnotations()) { - if (annotation.getAnnotationType().getSimpleName().equals(STATE_SET_ANNOTATION)) { - String[] stateArray = (String[]) annotation.getValueAsObject("value"); - return List.of(stateArray); - } - } - return null; - } - - /** - * Gets the elements that represent constructors (actual constructors for classes, methods named after the class for interfaces) - * @param ctType the CtType (class or interface) - * @param className the class name - * @return collection of constructor elements - */ - private static Collection getConstructorElements(CtType ctType, String className) { - if (ctType instanceof CtClass ctClass) { - return ctClass.getConstructors(); - } - // for interfaces the constructors are methods with the same name as the class - return ctType.getMethods().stream().filter(m -> m.getSimpleName().equals(className)).toList(); - } - - /** - * Gets the initial transitions from a class or interface - * If not explicitly defined, uses the first state in the state set - * @param ctType the CtType (class or interface) - * @param className the class name - * @param states the list of states - * @return initial transitions - */ - private static List getInitialTransitions(CtType ctType, String className, List states) { - List initialTransitions = new ArrayList<>(); - for (CtElement element : getConstructorElements(ctType, className)) { - for (CtAnnotation annotation : element.getAnnotations()) { - if (annotation.getAnnotationType().getSimpleName().equals(STATE_REFINEMENT_ANNOTATION)) { - String to = annotation.getValueAsString("to"); - initialTransitions.addAll(parseInitialTransitions(to, states)); - } - } - } - return initialTransitions; - } - - /** - * Gets transitions from a class or interface - * @param ctType the CtType (class or interface) - * @param className the class name - * @param states the list of states - * @return list of StateMachineTransition - */ - private static List getTransitions(CtType ctType, String className, List states) { - List transitions = new ArrayList<>(); - for (CtMethod method : ctType.getMethods()) { - // for interfaces we skip constructor methods (methods with same name as class) - if (ctType.isInterface() && method.getSimpleName().equals(className)) - continue; - - for (CtAnnotation annotation : method.getAnnotations()) { - if (annotation.getAnnotationType().getSimpleName().equals(STATE_REFINEMENT_ANNOTATION)) { - List extracted = getTransitions(annotation, method.getSimpleName(), states); - transitions.addAll(extracted); - } - } - } - return transitions; - } - - /** - * Gets transitions from the given annotation - * @param ann the CtAnnotation - * @param method the method name - * @param states the list of states - * @return list of StateMachineTransition - */ - private static List getTransitions(CtAnnotation ann, String method, List states) { - List transitions = new ArrayList<>(); - String from = ann.getValueAsString("from"); - String to = ann.getValueAsString("to"); - - // parse from and to expressions - List fromSources = from.isEmpty() ? allStateSources(states) : parsePrecondition(from, states); - List toSources = !from.isEmpty() && to.isEmpty() - ? parseStateSources(from, states) - : parsePostcondition(to, states); - - // create transitions for each combination of from and to states - for (TransitionSource fromSource : fromSources) { - for (TransitionSource toSource : toSources) { - transitions.add(new StateMachineTransition(fromSource.from(), toSource.from(), method, fromSource.cond(), toSource.cond())); - } - } - return transitions; - } - - private static List allStateSources(List states) { - List sources = new ArrayList<>(); - for (String state : states) { - sources.add(new TransitionSource(state, null)); - } - return sources; - } - - private static List parsePrecondition(String expr, List states) { - Expression ast = RefinementsParser.createAST(expr, ""); - List sources = getTransitionSources(ast, states, false); - if (sources.isEmpty()) { - sources = addCondition(allStateSources(states), ast.toString()); - } - return sources; - } - - private static List parsePostcondition(String expr, List states) { - if (expr == null || expr.isEmpty()) return new ArrayList<>(); - Expression ast = RefinementsParser.createAST(expr, ""); - return getTransitionSources(ast, states, true); - } - - private static List getTransitionSources(Expression expr, List states, boolean stateOnlyDisjunctions) { - String state = getStateName(expr, states); - if (state != null) { - return List.of(new TransitionSource(state, null)); - } - - if (expr instanceof BinaryExpression bin) { - String op = bin.getOperator(); - if (op.equals("&&")) { - return getConjunctionSources(bin, states, stateOnlyDisjunctions); - } else if (op.equals("||")) { - return stateOnlyDisjunctions ? getStateSources(bin, states) : getDisjunctionSources(bin, states); - } - } else if (expr instanceof UnaryExpression unary) { - if (unary.getOp().equals("!")) { - List negatedStates = getStateExpressions(unary.getExpression(), states); - if (!negatedStates.isEmpty()) { - List sources = new ArrayList<>(); - for (String possibleState : states) { - if (!negatedStates.contains(possibleState)) { - sources.add(new TransitionSource(possibleState, null)); - } - } - return sources; - } - } - } else if (expr instanceof Ite ite) { - List sources = new ArrayList<>(); - sources.addAll(addCondition(getTransitionSources(ite.getThen(), states, stateOnlyDisjunctions), ite.getCondition().toString())); - sources.addAll(addCondition(getTransitionSources(ite.getElse(), states, stateOnlyDisjunctions), negateCondition(ite.getCondition()))); - return sources; - } - return new ArrayList<>(); - } - - private static List getConjunctionSources(BinaryExpression bin, List states, boolean stateOnlyDisjunctions) { - List leftSources = getTransitionSources(bin.getFirstOperand(), states, stateOnlyDisjunctions); - List rightSources = getTransitionSources(bin.getSecondOperand(), states, stateOnlyDisjunctions); - - if (leftSources.isEmpty() && rightSources.isEmpty()) { - return new ArrayList<>(); - } else if (leftSources.isEmpty()) { - return addCondition(rightSources, bin.getFirstOperand().toString()); - } else if (rightSources.isEmpty()) { - return addCondition(leftSources, bin.getSecondOperand().toString()); - } - - List sources = new ArrayList<>(leftSources); - sources.addAll(rightSources); - return sources; - } - - private static List getDisjunctionSources(BinaryExpression bin, List states) { - List sources = new ArrayList<>(); - addDisjunctionBranch(sources, bin.getFirstOperand(), states); - addDisjunctionBranch(sources, bin.getSecondOperand(), states); - return removeRedundantGuardedSources(sources); - } - - private static void addDisjunctionBranch(List sources, Expression expr, List states) { - List parsedSources = getTransitionSources(expr, states, false); - if (parsedSources.isEmpty()) { - sources.addAll(addCondition(allStateSources(states), expr.toString())); - } else { - sources.addAll(parsedSources); - } - } - - private static List removeRedundantGuardedSources(List sources) { - List filteredSources = new ArrayList<>(); - for (TransitionSource source : sources) { - if (source.cond() == null || !hasUnguardedSource(sources, source.from())) { - filteredSources.add(source); - } - } - return filteredSources; - } - - private static boolean hasUnguardedSource(List sources, String from) { - for (TransitionSource source : sources) { - if (source.from().equals(from) && source.cond() == null) { - return true; - } - } - return false; - } - - private static List addCondition(List sources, String cond) { - List guardedSources = new ArrayList<>(); - for (TransitionSource source : sources) { - guardedSources.add(new TransitionSource(source.from(), combineConditions(source.cond(), cond))); - } - return guardedSources; - } - - private static String combineConditions(String first, String second) { - if (first == null || first.isEmpty()) { - return second; - } - if (second == null || second.isEmpty()) { - return first; - } - return first + " && " + second; - } - - private static String negateCondition(Expression expr) { - String condition = expr.toString(); - if (expr instanceof Var || expr instanceof FunctionInvocation) { - return "!" + condition; - } - return "!(" + condition + ")"; - } - - private static List parseInitialTransitions(String expr, List states) { - if (expr == null || expr.isEmpty()) return new ArrayList<>(); - List initialTransitions = new ArrayList<>(); - for (TransitionSource source : parsePostcondition(expr, states)) { - initialTransitions.add(new StateMachineInitialTransition(source.from(), source.cond())); - } - return initialTransitions; - } - - private static List parseStateSources(String expr, List states) { - if (expr == null || expr.isEmpty()) return new ArrayList<>(); - Expression ast = RefinementsParser.createAST(expr, ""); - return getStateSources(ast, states); - } - - private static List getStateSources(Expression expr, List states) { - List sources = new ArrayList<>(); - for (String state : getStateExpressions(expr, states)) { - sources.add(new TransitionSource(state, null)); - } - return sources; - } - - /** - * Gets state names from an expression AST recursively - * @param expr the expression - * @param states the list of possible states - * @return list of states - */ - private static List getStateExpressions(Expression expr, List states) { - List stateExpressions = new ArrayList<>(); - String state = getStateName(expr, states); - if (state != null) { - stateExpressions.add(state); - } else if (expr instanceof BinaryExpression bin) { - stateExpressions.addAll(getStateExpressions(bin.getFirstOperand(), states)); - stateExpressions.addAll(getStateExpressions(bin.getSecondOperand(), states)); - } else if (expr instanceof UnaryExpression unary) { - if (unary.getOp().equals("!")) { - // all except those in the expression - List negatedStates = getStateExpressions(unary.getExpression(), states); - if (!negatedStates.isEmpty()) { - for (String possibleState : states) { - if (!negatedStates.contains(possibleState)) { - stateExpressions.add(possibleState); - } - } - } - } - } else if (expr instanceof Ite ite) { - // combine states from then and else branches - stateExpressions.addAll(getStateExpressions(ite.getThen(), states)); - stateExpressions.addAll(getStateExpressions(ite.getElse(), states)); - } - return stateExpressions; - } - - private static String getStateName(Expression expr, List states) { - if (expr instanceof Var var) { - return findState(var.getName(), states); - } else if (expr instanceof FunctionInvocation func) { - return findState(func.getName(), states); - } - return null; - } - - private static String findState(String name, List states) { - if (states.contains(name)) { - return name; - } - String simpleName = Utils.getSimpleName(name); - for (String state : states) { - if (state.equals(simpleName) || Utils.getSimpleName(state).equals(simpleName)) { - return state; - } - } - return null; - } -} diff --git a/server/src/main/java/fsm/StateMachineTransition.java b/server/src/main/java/fsm/StateMachineTransition.java deleted file mode 100644 index 33f0f580..00000000 --- a/server/src/main/java/fsm/StateMachineTransition.java +++ /dev/null @@ -1,11 +0,0 @@ -package fsm; - -/** - * Represents a transition in a state machine - */ -public record StateMachineTransition(String from, String to, String label, String preCond, String postCond) { - - public StateMachineTransition(String from, String to, String label) { - this(from, to, label, null, null); - } -} diff --git a/server/src/main/java/utils/ContextHistoryConverter.java b/server/src/main/java/utils/ContextHistoryConverter.java deleted file mode 100644 index aab0e1b2..00000000 --- a/server/src/main/java/utils/ContextHistoryConverter.java +++ /dev/null @@ -1,46 +0,0 @@ -package utils; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import dtos.context.AliasDTO; -import dtos.context.ContextHistoryDTO; -import dtos.context.MethodDTO; -import dtos.context.GhostDTO; -import dtos.context.VariableDTO; -import dtos.diagnostics.SourcePositionDTO; -import liquidjava.processor.context.ContextHistory; - -/** - * Utility class for converting LiquidJava context objects to DTOs. - */ -public class ContextHistoryConverter { - - /** - * Converts a ContextHistory to its DTO type. - * @param contextHistory the context history to convert - * @return the corresponding DTO - */ - public static ContextHistoryDTO convertToDTO(ContextHistory contextHistory) { - return new ContextHistoryDTO( - contextHistory.getLocalVars().stream().map(VariableDTO::from).filter(v -> v != null).collect(Collectors.toList()), - contextHistory.getGlobalVars().stream().map(VariableDTO::from).filter(v -> v != null).collect(Collectors.toList()), - contextHistory.getGhosts().stream().map(GhostDTO::from).collect(Collectors.toList()), - contextHistory.getAliases().stream().map(AliasDTO::from).collect(Collectors.toList()), - contextHistory.getMethods().stream().map(MethodDTO::from).filter(f -> f != null).collect(Collectors.toList()), - parseFileScopes(contextHistory.getFileScopes()) - ); - } - - private static Map> parseFileScopes(Map> fileScopes) { - return fileScopes.entrySet().stream().collect(Collectors.toMap( - Map.Entry::getKey, - entry -> entry.getValue().stream().map(SourcePositionDTO::from).collect(Collectors.toList()), - (left, right) -> left, - HashMap::new - )); - } -} diff --git a/server/src/main/java/utils/DiagnosticConverter.java b/server/src/main/java/utils/DiagnosticConverter.java deleted file mode 100644 index 11ce71f6..00000000 --- a/server/src/main/java/utils/DiagnosticConverter.java +++ /dev/null @@ -1,83 +0,0 @@ - - -package utils; - -import dtos.diagnostics.LJDiagnosticDTO; -import dtos.errors.ArgumentMismatchErrorDTO; -import dtos.errors.CustomErrorDTO; -import dtos.errors.IllegalConstructorTransitionErrorDTO; -import dtos.errors.InvalidRefinementErrorDTO; -import dtos.errors.LJErrorDTO; -import dtos.errors.NotFoundErrorDTO; -import dtos.errors.RefinementErrorDTO; -import dtos.errors.StateConflictErrorDTO; -import dtos.errors.StateRefinementErrorDTO; -import dtos.errors.SyntaxErrorDTO; -import dtos.warnings.CustomWarningDTO; -import dtos.warnings.ExternalClassNotFoundWarningDTO; -import dtos.warnings.ExternalMethodNotFoundWarningDTO; -import dtos.warnings.LJWarningDTO; -import dtos.warnings.UnsatisfiableRefinementWarningDTO; -import liquidjava.diagnostics.LJDiagnostic; -import liquidjava.diagnostics.errors.ArgumentMismatchError; -import liquidjava.diagnostics.errors.CustomError; -import liquidjava.diagnostics.errors.IllegalConstructorTransitionError; -import liquidjava.diagnostics.errors.InvalidRefinementError; -import liquidjava.diagnostics.errors.LJError; -import liquidjava.diagnostics.errors.NotFoundError; -import liquidjava.diagnostics.errors.RefinementError; -import liquidjava.diagnostics.errors.StateConflictError; -import liquidjava.diagnostics.errors.StateRefinementError; -import liquidjava.diagnostics.errors.SyntaxError; -import liquidjava.diagnostics.warnings.CustomWarning; -import liquidjava.diagnostics.warnings.ExternalClassNotFoundWarning; -import liquidjava.diagnostics.warnings.ExternalMethodNotFoundWarning; -import liquidjava.diagnostics.warnings.LJWarning; -import liquidjava.diagnostics.warnings.UnsatisfiableRefinementWarning; - -/** - * Utility class for converting LiquidJava diagnostic objects to their corresponding DTOs - */ -public class DiagnosticConverter { - - /** - * Converts a diagnostic to its appropriate DTO type - * @param diagnostic the diagnostic to convert - * @return the corresponding DTO - */ - public static Object convertToDTO(LJDiagnostic diagnostic) { - if (diagnostic instanceof RefinementError d) { - return RefinementErrorDTO.from(d); - } else if (diagnostic instanceof StateRefinementError d) { - return StateRefinementErrorDTO.from(d); - } else if (diagnostic instanceof SyntaxError d) { - return SyntaxErrorDTO.from(d); - } else if (diagnostic instanceof CustomError d) { - return CustomErrorDTO.from(d); - } else if (diagnostic instanceof InvalidRefinementError d) { - return InvalidRefinementErrorDTO.from(d); - } else if (diagnostic instanceof StateConflictError d) { - return StateConflictErrorDTO.from(d); - } else if (diagnostic instanceof NotFoundError d) { - return NotFoundErrorDTO.from(d); - } else if (diagnostic instanceof IllegalConstructorTransitionError d) { - return IllegalConstructorTransitionErrorDTO.from(d); - } else if (diagnostic instanceof ArgumentMismatchError d) { - return ArgumentMismatchErrorDTO.from(d); - } else if (diagnostic instanceof ExternalClassNotFoundWarning d) { - return ExternalClassNotFoundWarningDTO.from(d); - } else if (diagnostic instanceof ExternalMethodNotFoundWarning d) { - return ExternalMethodNotFoundWarningDTO.from(d); - } else if (diagnostic instanceof UnsatisfiableRefinementWarning d) { - return UnsatisfiableRefinementWarningDTO.from(d); - } else if (diagnostic instanceof CustomWarning d) { - return CustomWarningDTO.from(d); - } else if (diagnostic instanceof LJError d) { - return LJErrorDTO.from(d); - } else if (diagnostic instanceof LJWarning d) { - return LJWarningDTO.from(d); - } else { - return LJDiagnosticDTO.from(diagnostic); - } - } -} diff --git a/server/src/test/java/fsm/StateMachineParserTests.java b/server/src/test/java/fsm/StateMachineParserTests.java deleted file mode 100644 index 08e97e26..00000000 --- a/server/src/test/java/fsm/StateMachineParserTests.java +++ /dev/null @@ -1,194 +0,0 @@ -package fsm; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class StateMachineParserTests { - - private static final String BASE_URI = "src/test/resources/fsm/"; - - @Test - public void testSimpleStateMachine() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "Simple.java"); - StateMachine expectedSm = new StateMachine("Simple", List.of("open", "closed"), - List.of(new StateMachineTransition("open", "closed", "close"), - new StateMachineTransition("open", "open", "read")), - List.of(new StateMachineInitialTransition("open"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testOrTransition() { - // state1 || state2 => separate transitions from both state1 and state2 - StateMachine sm = StateMachineParser.parse(BASE_URI + "OrTransition.java"); - StateMachine expectedSm = new StateMachine("OrTransition", List.of("a", "b", "c"), List - .of(new StateMachineTransition("a", "c", "action"), new StateMachineTransition("b", "c", "action")), - List.of(new StateMachineInitialTransition("a"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testNegationTransition() { - // !state => all states except state - StateMachine sm = StateMachineParser.parse(BASE_URI + "NegationTransition.java"); - StateMachine expectedSm = new StateMachine("NegationTransition", List.of("open", "closed", "locked"), - List.of(new StateMachineTransition("open", "locked", "lock"), - new StateMachineTransition("closed", "locked", "lock")), - List.of(new StateMachineInitialTransition("open"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testSelfLoop() { - // from=state, to=state or from=state => self-loop - StateMachine sm = StateMachineParser.parse(BASE_URI + "SelfLoop.java"); - StateMachine expectedSm = new StateMachine("SelfLoop", List.of("idle", "running"), - List.of(new StateMachineTransition("idle", "idle", "noop"), - new StateMachineTransition("idle", "running", "start"), - new StateMachineTransition("running", "running", "tick")), - List.of(new StateMachineInitialTransition("idle"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testToOnlyTransition() { - // no from => all states contain a transition to state - StateMachine sm = StateMachineParser.parse(BASE_URI + "ToOnlyTransition.java"); - StateMachine expectedSm = new StateMachine("ToOnlyTransition", List.of("a", "b", "c"), - List.of(new StateMachineTransition("a", "c", "action"), new StateMachineTransition("b", "c", "action"), - new StateMachineTransition("c", "c", "action")), - List.of(new StateMachineInitialTransition("a"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testMultipleInitialStates() { - // overloading constructors with different initial states - StateMachine sm = StateMachineParser.parse(BASE_URI + "MultipleInitialStates.java"); - StateMachine expectedSm = new StateMachine("MultipleInitialStates", List.of("initialized", "uninitialized", "error"), - List.of(new StateMachineTransition("uninitialized", "initialized", "init")), - List.of(new StateMachineInitialTransition("uninitialized"), - new StateMachineInitialTransition("initialized"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testExternalRefinementsInterface() { - // class name from @ExternalStateRefinements - StateMachine sm = StateMachineParser.parse(BASE_URI + "ExternalRefinements.java"); - StateMachine expectedSm = new StateMachine("Connection", List.of("connected", "disconnected"), - List.of(new StateMachineTransition("disconnected", "connected", "connect")), - List.of(new StateMachineInitialTransition("disconnected"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testConditionalTransition() { - // transitions for both branches of condition - StateMachine sm = StateMachineParser.parse(BASE_URI + "ConditionalTransition.java"); - StateMachine expectedSm = new StateMachine("ConditionalTransition", List.of("on", "off"), - List.of(new StateMachineTransition("on", "off", "turnOff"), - new StateMachineTransition("off", "on", "turnOn")), - List.of(new StateMachineInitialTransition("on", "flag"), - new StateMachineInitialTransition("off", "!flag"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testConjunctionInitialTransition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "ConjunctionInitialTransition.java"); - StateMachine expectedSm = new StateMachine("ConjunctionInitialTransition", List.of("on", "off"), - List.of(new StateMachineTransition("on", "off", "turnOff")), - List.of(new StateMachineInitialTransition("on", "flag"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testConjunctionPrecondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "ConjunctionPrecondition.java"); - StateMachine expectedSm = new StateMachine("ConjunctionPrecondition", List.of("open", "closed"), - List.of(new StateMachineTransition("open", "closed", "close", "flag", null)), - List.of(new StateMachineInitialTransition("open"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testDisjunctionPrecondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "DisjunctionPrecondition.java"); - StateMachine expectedSm = new StateMachine("DisjunctionPrecondition", List.of("ready", "waiting", "done"), - List.of(new StateMachineTransition("waiting", "done", "action", "flag", null), - new StateMachineTransition("done", "done", "action", "flag", null), - new StateMachineTransition("ready", "done", "action")), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testConditionalPrecondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "ConditionalPrecondition.java"); - StateMachine expectedSm = new StateMachine("ConditionalPrecondition", List.of("left", "right", "done"), - List.of(new StateMachineTransition("left", "done", "finish", "flag", null), - new StateMachineTransition("right", "done", "finish", "!flag", null)), - List.of(new StateMachineInitialTransition("left"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testPostConditionFiltering() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "PostConditionFiltering.java"); - StateMachine expectedSm = new StateMachine("PostConditionFiltering", List.of("ready", "done"), - List.of(new StateMachineTransition("ready", "done", "finish", null, "flag")), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testCombinedPostCondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "CombinedPostCondition.java"); - StateMachine expectedSm = new StateMachine("CombinedPostCondition", List.of("ready", "done"), - List.of(new StateMachineTransition("ready", "done", "finish", "x", "flag")), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testConditionalPostCondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "ConditionalPostCondition.java"); - StateMachine expectedSm = new StateMachine("ConditionalPostCondition", List.of("ready", "done", "error"), - List.of(new StateMachineTransition("ready", "done", "finish", null, "flag"), - new StateMachineTransition("ready", "error", "finish", null, "!flag")), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testDisjunctionPostCondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "DisjunctionPostCondition.java"); - StateMachine expectedSm = new StateMachine("DisjunctionPostCondition", List.of("ready", "done"), - List.of(new StateMachineTransition("ready", "done", "finish")), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - @Test - public void testGuardedSelfLoopDoesNotDuplicateCondition() { - StateMachine sm = StateMachineParser.parse(BASE_URI + "GuardedSelfLoop.java"); - StateMachine expectedSm = new StateMachine("GuardedSelfLoop", List.of("ready", "done"), - List.of(new StateMachineTransition("ready", "ready", "poll", "flag", null)), - List.of(new StateMachineInitialTransition("ready"))); - assertStateMachineEquals(expectedSm, sm); - } - - private static void assertStateMachineEquals(StateMachine expected, StateMachine actual) { - assertNotNull(actual, "State machine should not be null"); - assertEquals(expected.className(), actual.className(), "Class names should match"); - assertEquals(expected.initialTransitions(), actual.initialTransitions(), "Initial transitions should match"); - assertEquals(expected.states(), actual.states(), "States should match"); - assertEquals(expected.transitions(), actual.transitions(), "State transitions should match"); - } -} diff --git a/server/src/test/resources/fsm/CombinedPostCondition.java b/server/src/test/resources/fsm/CombinedPostCondition.java deleted file mode 100644 index 83f0099a..00000000 --- a/server/src/test/resources/fsm/CombinedPostCondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "done"}) -public class CombinedPostCondition { - - @StateRefinement(to="ready(this)") - public CombinedPostCondition() {} - - @StateRefinement(from="x && ready(this)", to="done(this) && flag") - public void finish(boolean x, boolean flag) {} -} diff --git a/server/src/test/resources/fsm/ConditionalPostCondition.java b/server/src/test/resources/fsm/ConditionalPostCondition.java deleted file mode 100644 index 9225cc3b..00000000 --- a/server/src/test/resources/fsm/ConditionalPostCondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "done", "error"}) -public class ConditionalPostCondition { - - @StateRefinement(to="ready(this)") - public ConditionalPostCondition() {} - - @StateRefinement(from="ready(this)", to="flag ? done(this) : error(this)") - public void finish(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/ConditionalPrecondition.java b/server/src/test/resources/fsm/ConditionalPrecondition.java deleted file mode 100644 index 9d869217..00000000 --- a/server/src/test/resources/fsm/ConditionalPrecondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"left", "right", "done"}) -public class ConditionalPrecondition { - - @StateRefinement(to="left(this)") - public ConditionalPrecondition() {} - - @StateRefinement(from="flag ? left(this) : right(this)", to="done(this)") - public void finish(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/ConditionalTransition.java b/server/src/test/resources/fsm/ConditionalTransition.java deleted file mode 100644 index 2e41d355..00000000 --- a/server/src/test/resources/fsm/ConditionalTransition.java +++ /dev/null @@ -1,18 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"on", "off"}) -public class ConditionalTransition { - - // include transitions of both branches - @StateRefinement(to="flag ? on(this) : off(this)") - public ConditionalTransition(boolean flag) {} - - @StateRefinement(from="off(this)", to="on(this)") - public void turnOn() {} - - @StateRefinement(from="on(this)", to="off(this)") - public void turnOff() {} -} diff --git a/server/src/test/resources/fsm/ConjunctionInitialTransition.java b/server/src/test/resources/fsm/ConjunctionInitialTransition.java deleted file mode 100644 index e54a32e8..00000000 --- a/server/src/test/resources/fsm/ConjunctionInitialTransition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"on", "off"}) -public class ConjunctionInitialTransition { - - @StateRefinement(to="flag && on(this)") - public ConjunctionInitialTransition(boolean flag) {} - - @StateRefinement(from="on(this)", to="off(this)") - public void turnOff() {} -} diff --git a/server/src/test/resources/fsm/ConjunctionPrecondition.java b/server/src/test/resources/fsm/ConjunctionPrecondition.java deleted file mode 100644 index 549733c8..00000000 --- a/server/src/test/resources/fsm/ConjunctionPrecondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"open", "closed"}) -public class ConjunctionPrecondition { - - @StateRefinement(to="open(this)") - public ConjunctionPrecondition() {} - - @StateRefinement(from="flag && open(this)", to="closed(this)") - public void close(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/DisjunctionPostCondition.java b/server/src/test/resources/fsm/DisjunctionPostCondition.java deleted file mode 100644 index 8bd23f11..00000000 --- a/server/src/test/resources/fsm/DisjunctionPostCondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "done"}) -public class DisjunctionPostCondition { - - @StateRefinement(to="ready(this)") - public DisjunctionPostCondition() {} - - @StateRefinement(from="ready(this)", to="done(this) || flag") - public void finish(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/DisjunctionPrecondition.java b/server/src/test/resources/fsm/DisjunctionPrecondition.java deleted file mode 100644 index c2eb62b0..00000000 --- a/server/src/test/resources/fsm/DisjunctionPrecondition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "waiting", "done"}) -public class DisjunctionPrecondition { - - @StateRefinement(to="ready(this)") - public DisjunctionPrecondition() {} - - @StateRefinement(from="flag || ready(this)", to="done(this)") - public void action(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/ExternalRefinements.java b/server/src/test/resources/fsm/ExternalRefinements.java deleted file mode 100644 index e348341d..00000000 --- a/server/src/test/resources/fsm/ExternalRefinements.java +++ /dev/null @@ -1,16 +0,0 @@ -package fsm; - -import liquidjava.specification.ExternalRefinementsFor; -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@ExternalRefinementsFor("com.example.Connection") -@StateSet({"connected", "disconnected"}) -public interface ExternalRefinements { - - @StateRefinement(to="disconnected(this)") - void Connection(); - - @StateRefinement(from="disconnected(this)", to="connected(this)") - void connect(); -} diff --git a/server/src/test/resources/fsm/GuardedSelfLoop.java b/server/src/test/resources/fsm/GuardedSelfLoop.java deleted file mode 100644 index 685bc7e0..00000000 --- a/server/src/test/resources/fsm/GuardedSelfLoop.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "done"}) -public class GuardedSelfLoop { - - @StateRefinement(to="ready(this)") - public GuardedSelfLoop() {} - - @StateRefinement(from="flag && ready(this)") - public void poll(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/MultipleInitialStates.java b/server/src/test/resources/fsm/MultipleInitialStates.java deleted file mode 100644 index 4f9b39c9..00000000 --- a/server/src/test/resources/fsm/MultipleInitialStates.java +++ /dev/null @@ -1,17 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"initialized", "uninitialized", "error"}) -public class MultipleInitialStates { - - @StateRefinement(to="uninitialized(this)") - public MultipleInitialStates() {} - - @StateRefinement(to="initialized(this)") - public MultipleInitialStates(int code) {} - - @StateRefinement(from="uninitialized(this)", to="initialized(this)") - public void init(int code) {} -} diff --git a/server/src/test/resources/fsm/NegationTransition.java b/server/src/test/resources/fsm/NegationTransition.java deleted file mode 100644 index a1b6c0f4..00000000 --- a/server/src/test/resources/fsm/NegationTransition.java +++ /dev/null @@ -1,15 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"open", "closed", "locked"}) -public class NegationTransition { - - @StateRefinement(to="open(this)") - public NegationTransition() {} - - // transition from all states except "locked" to "locked" - @StateRefinement(from="!locked(this)", to="locked(this)") - public void lock() {} -} diff --git a/server/src/test/resources/fsm/OrTransition.java b/server/src/test/resources/fsm/OrTransition.java deleted file mode 100644 index c96df8de..00000000 --- a/server/src/test/resources/fsm/OrTransition.java +++ /dev/null @@ -1,15 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"a", "b", "c"}) -public class OrTransition { - - @StateRefinement(to="a(this)") - public OrTransition() {} - - // transition from both a and b to c - @StateRefinement(from="a(this) || b(this)", to="c(this)") - public void action() {} -} diff --git a/server/src/test/resources/fsm/PostConditionFiltering.java b/server/src/test/resources/fsm/PostConditionFiltering.java deleted file mode 100644 index 4df211c2..00000000 --- a/server/src/test/resources/fsm/PostConditionFiltering.java +++ /dev/null @@ -1,14 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"ready", "done"}) -public class PostConditionFiltering { - - @StateRefinement(to="ready(this)") - public PostConditionFiltering() {} - - @StateRefinement(from="ready(this)", to="flag && done(this)") - public void finish(boolean flag) {} -} diff --git a/server/src/test/resources/fsm/SelfLoop.java b/server/src/test/resources/fsm/SelfLoop.java deleted file mode 100644 index 5a3c7457..00000000 --- a/server/src/test/resources/fsm/SelfLoop.java +++ /dev/null @@ -1,23 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"idle", "running"}) -public class SelfLoop { - - @StateRefinement(to="idle(this)") - public SelfLoop() {} - - // explicit self-loop - @StateRefinement(from="running(this)", to="running(this)") - public void tick() {} - - // implicit self-loop - @StateRefinement(from="idle(this)") - public void noop() {} - - // transition to another state - @StateRefinement(from="idle(this)", to="running(this)") - public void start() {} -} diff --git a/server/src/test/resources/fsm/Simple.java b/server/src/test/resources/fsm/Simple.java deleted file mode 100644 index 389e3e1b..00000000 --- a/server/src/test/resources/fsm/Simple.java +++ /dev/null @@ -1,17 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"open", "closed"}) -public class Simple { - - @StateRefinement(to="open(this)") - public Simple() {} - - @StateRefinement(from="open(this)") - public void read() {} - - @StateRefinement(from="open(this)", to="closed(this)") - public void close() {} -} diff --git a/server/src/test/resources/fsm/ToOnlyTransition.java b/server/src/test/resources/fsm/ToOnlyTransition.java deleted file mode 100644 index 5f6dc168..00000000 --- a/server/src/test/resources/fsm/ToOnlyTransition.java +++ /dev/null @@ -1,15 +0,0 @@ -package fsm; - -import liquidjava.specification.StateRefinement; -import liquidjava.specification.StateSet; - -@StateSet({"a", "b", "c"}) -public class ToOnlyTransition { - - @StateRefinement(to="a(this)") - public ToOnlyTransition() {} - - // all transitions to state c - @StateRefinement(to="c(this)") - public void action() {} -}