From e0d691b867f1585dfc3f18344cf767fdb8b648a4 Mon Sep 17 00:00:00 2001 From: Yannick Daveluy Date: Mon, 12 Aug 2024 14:09:16 +0200 Subject: [PATCH] update eslint version --- .eslintrc.json | 13 - .github/workflows/action.yml | 27 +- .vscodeignore | 1 + README.md | 1 + eslint.config.mjs | 24 + package-lock.json | 538 ++++++++---------- package.json | 31 +- src/extension/main.ts | 7 + src/language/builtins.ts | 8 + src/language/generator/smp/generator.ts | 2 +- src/language/generator/smp/model/elements.ts | 5 - src/language/lsp/xsmpcat-code-action.ts | 2 +- .../lsp/xsmpproject-completion-provider.ts | 2 +- src/language/utils/solver.ts | 25 +- .../validation/xsmpcat-issue-codes.ts | 22 + src/language/validation/xsmpcat-validator.ts | 34 +- .../validation/xsmpproject-validator.ts | 2 +- src/language/wizard/wizard.ts | 348 +++++++++++ 18 files changed, 684 insertions(+), 408 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.mjs create mode 100644 src/language/validation/xsmpcat-issue-codes.ts create mode 100644 src/language/wizard/wizard.ts diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 8252235..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 025433f..bd5a37a 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -49,27 +49,6 @@ jobs: -Dsonar.exclusions=src/language/generated/*,src/language/builtins.ts,out/** -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info -Dsonar.coverage.exclusions=**/*.test.* - - lint: - name: Lint - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Build - shell: bash - run: | - npm ci - npm run langium:generate - npm run build:clean - - name: Check Git Status - shell: bash - run: git diff --exit-code . - - name: Lint - shell: bash - run: npm run lint + -Dsonar.tests=test/ + -Dsonar.links.scm=https://github.com/ydaveluy/xsmp-modeler + -Dsonar.links.issue=https://github.com/ydaveluy/xsmp-modeler/issues diff --git a/.vscodeignore b/.vscodeignore index cf559af..7217056 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -10,6 +10,7 @@ coverage/ examples/ sonar-report.xml esbuild.mjs +eslint.config.mjs langium-config.json package.json tsconfig.json diff --git a/README.md b/README.md index 31ed34f..d4288ad 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ - [ ] AsciiDoc Tool - generator - [ ] xsmp-sdk Profile - generator - [ ] esa-cdk Profile - generator +- [x] Project Wizard ### xsmp-modeler-core (**Xtext**) vs xsmp-modeler (**Langium**) comparison diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..5e1264d --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,24 @@ + +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config({ + files: ['src/**/*.ts'], + extends: [ + eslint.configs.recommended, + ...tseslint.configs.recommended, + ], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: true, + }, + }, + rules: { + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, +}); + diff --git a/package-lock.json b/package-lock.json index 8106f65..0d3fdbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,16 +22,15 @@ "devDependencies": { "@types/node": "^18.0.0", "@types/vscode": "~1.67.0", - "@typescript-eslint/eslint-plugin": "~8.0.0", - "@typescript-eslint/parser": "~8.0.0", "@vitest/coverage-v8": "~2.0.5", "@vscode/vsce": "^2.31.1", "concurrently": "~8.2.1", "esbuild": "~0.23.0", - "eslint": "~8.57.0", + "eslint": "~9.9.0", "langium-cli": "~3.1.1", "shx": "~0.3.4", "typescript": "~5.5.4", + "typescript-eslint": "^8.0.1", "vitest": "~2.0.5" }, "engines": { @@ -810,6 +809,19 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/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, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", @@ -820,17 +832,32 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -838,84 +865,30 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -932,13 +905,19 @@ "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", + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -1550,6 +1529,32 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", @@ -1591,12 +1596,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "node_modules/@typescript-eslint/visitor-keys/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, - "license": "ISC" + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, "node_modules/@vitest/coverage-v8": { "version": "2.0.5", @@ -1912,17 +1923,6 @@ "node": ">=4" } }, - "node_modules/@vscode/vsce/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@vscode/vsce/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1968,19 +1968,6 @@ "node": ">=4" } }, - "node_modules/@vscode/vsce/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@vscode/vsce/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2164,12 +2151,14 @@ "license": "ISC" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { @@ -2813,19 +2802,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -3034,42 +3010,38 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.9.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@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.3.2", - "doctrine": "^3.0.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", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.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", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -3083,16 +3055,24 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "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==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3100,20 +3080,20 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3135,17 +3115,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3183,19 +3152,6 @@ "dev": true, "license": "MIT" }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3210,18 +3166,18 @@ } }, "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==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3413,16 +3369,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -3456,18 +3412,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -3662,6 +3617,16 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/glob/node_modules/minimatch": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", @@ -3679,16 +3644,13 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3918,9 +3880,9 @@ "optional": true }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "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": { @@ -4719,19 +4681,16 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { @@ -5437,69 +5396,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/rollup": { "version": "4.20.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", @@ -5686,17 +5582,6 @@ "node": ">=4" } }, - "node_modules/shelljs/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/shelljs/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5719,19 +5604,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/shelljs/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/shx": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", @@ -6104,6 +5976,16 @@ "node": ">=18" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/test-exclude/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -6148,6 +6030,22 @@ "dev": true, "license": "ISC" }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/test-exclude/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -6309,19 +6207,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "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": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-rest-client": { "version": "1.8.11", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", @@ -6348,6 +6233,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.0.1.tgz", + "integrity": "sha512-V3Y+MdfhawxEjE16dWpb7/IOgeXnLwAEEkS7v8oDqNcR1oYlqWhGH/iHqHdKVdpWme1VPZ0SoywXAkCqawj2eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.0.1", + "@typescript-eslint/parser": "8.0.1", + "@typescript-eslint/utils": "8.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -7025,6 +6934,15 @@ "vscode": "^1.82.0" } }, + "node_modules/vscode-languageclient/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/vscode-languageclient/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", diff --git a/package.json b/package.json index 7a0d871..8c9dda9 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build": "tsc -b tsconfig.src.json && node esbuild.mjs", "build:clean": "npm run clean && npm run build", "watch": "concurrently -n tsc,esbuild -c blue,yellow \"tsc -b tsconfig.src.json --watch\" \"node esbuild.mjs --watch\"", - "lint": "eslint src --ext ts", + "lint": "eslint src", "langium:generate": "langium generate", "langium:watch": "langium generate --watch", "vscode:prepublish": "npm run clean && npm run build -- --minify", @@ -32,16 +32,15 @@ "devDependencies": { "@types/node": "^18.0.0", "@types/vscode": "~1.67.0", - "@typescript-eslint/eslint-plugin": "~8.0.0", - "@typescript-eslint/parser": "~8.0.0", "@vitest/coverage-v8": "~2.0.5", "@vscode/vsce": "^2.31.1", "concurrently": "~8.2.1", "esbuild": "~0.23.0", - "eslint": "~8.57.0", + "eslint": "~9.9.0", "langium-cli": "~3.1.1", "shx": "~0.3.4", "typescript": "~5.5.4", + "typescript-eslint": "^8.0.1", "vitest": "~2.0.5" }, "volta": { @@ -71,10 +70,10 @@ "xsmp.project" ], "configuration": "./xsmpproject-language-configuration.json", - "icon": { - "light": "./icons/xsmpproject.png", - "dark": "./icons/xsmpproject.png" - } + "icon": { + "light": "./icons/xsmpproject.png", + "dark": "./icons/xsmpproject.png" + } }, { "id": "xsmpcat", @@ -85,10 +84,10 @@ ".xsmpcat" ], "configuration": "./xsmpcat-language-configuration.json", - "icon": { - "light": "./icons/xsmp.png", - "dark": "./icons/xsmp.png" - } + "icon": { + "light": "./icons/xsmp.png", + "dark": "./icons/xsmp.png" + } } ], "grammars": [ @@ -103,6 +102,14 @@ "path": "syntaxes/xsmpcat.tmLanguage.json" } ], + + "commands": [ + { + "command": "xsmp.wizard", + "category": "Xsmp", + "title": "Create a new project" + } + ], "configurationDefaults": { "editor.tokenColorCustomizations": { "textMateRules": [ diff --git a/src/extension/main.ts b/src/extension/main.ts index 86b200f..cd86a4d 100644 --- a/src/extension/main.ts +++ b/src/extension/main.ts @@ -3,6 +3,7 @@ import * as vscode from 'vscode'; import * as path from 'node:path'; import { LanguageClient, TransportKind } from 'vscode-languageclient/node.js'; import { builtins } from '../language/builtins.js'; +import { createProjectWizard } from '../language/wizard/wizard.js'; let client: LanguageClient; @@ -11,6 +12,12 @@ let client: LanguageClient; export function activate(context: vscode.ExtensionContext): void { client = startLanguageClient(context); BuiltinLibraryFileSystemProvider.register(context); + + // New project Wizard + context.subscriptions.push( + vscode.commands.registerCommand('xsmp.wizard', createProjectWizard) + ); + } // This function is called when the extension is deactivated. diff --git a/src/language/builtins.ts b/src/language/builtins.ts index db871da..48594fd 100644 --- a/src/language/builtins.ts +++ b/src/language/builtins.ts @@ -56,8 +56,16 @@ tool "smp" [URI.parse('builtin:///org.eclipse.xsmp.tool.python.tool').toString(), ` /** * Python tool + * @deprecated Use the "python" tool instead. */ tool "org.eclipse.xsmp.tool.python" +`], + +[URI.parse('builtin:///python.tool').toString(), ` +/** + * Python tool + */ +tool "python" `], [URI.parse('builtin:///org.eclipse.xsmp.tool.adoc.tool').toString(), ` diff --git a/src/language/generator/smp/generator.ts b/src/language/generator/smp/generator.ts index 746a179..285f693 100644 --- a/src/language/generator/smp/generator.ts +++ b/src/language/generator/smp/generator.ts @@ -1,5 +1,4 @@ import * as ast from '../../generated/ast.js'; -const { create } = require('xmlbuilder2'); import * as Catalogue from './model/catalogue.js'; import * as Elements from './model/elements.js'; import * as Types from './model/types.js'; @@ -11,6 +10,7 @@ import * as fs from 'fs'; import { Solver } from '../../utils/solver.js'; import { Duration, Instant } from '@js-joda/core'; import { XsmpGenerator } from '../generator.js'; +import { create } from 'xmlbuilder2'; diff --git a/src/language/generator/smp/model/elements.ts b/src/language/generator/smp/model/elements.ts index f99890b..1b371f3 100644 --- a/src/language/generator/smp/model/elements.ts +++ b/src/language/generator/smp/model/elements.ts @@ -28,9 +28,4 @@ export interface Metadata extends NamedElement { export interface Comment extends Metadata { } -export interface Documentation extends Metadata { - Resource?: any[]; -} - - diff --git a/src/language/lsp/xsmpcat-code-action.ts b/src/language/lsp/xsmpcat-code-action.ts index c0284ec..4c075d7 100644 --- a/src/language/lsp/xsmpcat-code-action.ts +++ b/src/language/lsp/xsmpcat-code-action.ts @@ -5,7 +5,7 @@ import { CodeActionProvider, LangiumServices } from 'langium/lsp'; import { CodeActionKind, type Diagnostic } from 'vscode-languageserver'; import type { CodeActionParams } from 'vscode-languageserver-protocol'; import type { CodeAction, Command } from 'vscode-languageserver-types'; -import { IssueCodes } from '../validation/xsmpcat-validator.js'; +import * as IssueCodes from '../validation/xsmpcat-issue-codes.js'; import { randomUUID } from 'crypto'; export class XsmpcatCodeActionProvider implements CodeActionProvider { diff --git a/src/language/lsp/xsmpproject-completion-provider.ts b/src/language/lsp/xsmpproject-completion-provider.ts index 7014da8..3f4497c 100644 --- a/src/language/lsp/xsmpproject-completion-provider.ts +++ b/src/language/lsp/xsmpproject-completion-provider.ts @@ -17,7 +17,7 @@ export class XsmpprojectCompletionProvider extends DefaultCompletionProvider { * @param _context Information about the completion request including document, cursor position, token under cursor, etc. * @returns A stream of all elements being valid for the given reference. */ - protected override getReferenceCandidates(refInfo: ReferenceInfo, _context: CompletionContext): Stream { + protected override getReferenceCandidates(refInfo: ReferenceInfo/*, context: CompletionContext*/): Stream { if (ast.isProject(refInfo.container)) { const project = refInfo.container switch (refInfo.property) { diff --git a/src/language/utils/solver.ts b/src/language/utils/solver.ts index 3c2b8e4..3fea59c 100644 --- a/src/language/utils/solver.ts +++ b/src/language/utils/solver.ts @@ -84,22 +84,24 @@ export class StringValue extends Value { override stringValue(): this | undefined { return this } override integralValue(type: IntegralPrimitiveTypeKind): IntegralValue | undefined { - if (type === 'DateTime') + if (type === 'DateTime') { try { const instant = Instant.parse(this.value) return new IntegralValue(BigInt(instant.epochSecond()) * BigInt(1000000000) + BigInt(instant.nano()), type) } - catch (error) { - // return undefined + catch { + return undefined } - else if (type === 'Duration') + } + else if (type === 'Duration') { try { const duration = Duration.parse(this.value) return new IntegralValue(BigInt(duration.get(ChronoUnit.SECONDS)) * BigInt(1000000000) + BigInt(duration.get(ChronoUnit.NANOS)), type) } - catch (error) { - // return undefined + catch { + return undefined } + } return undefined } @@ -239,7 +241,7 @@ export class FloatValue extends Value { this.type = type } public static of(expr: ast.FloatingLiteral, accept?: ValidationAcceptor): FloatValue { - let text = expr.text.replaceAll("'", '') + const text = expr.text.replaceAll("'", '') if (text.endsWith('f') || text.endsWith('F')) { return new FloatValue(parseFloat(text.slice(0, -1)), 'Float32') } @@ -252,9 +254,8 @@ export class FloatValue extends Value { override boolValue(): BoolValue { return new BoolValue(this.value != 0.) } override integralValue(type: IntegralPrimitiveTypeKind): IntegralValue | undefined { try { - return new IntegralValue(BigInt(this.value), type) - } catch (error) { + } catch { return undefined } } @@ -449,8 +450,8 @@ export class Solver { private static binaryOperation(expression: ast.BinaryOperation, accept?: ValidationAcceptor): Value | undefined { - let left = this.getValue(expression.leftOperand, accept) - let right = this.getValue(expression.rightOperand, accept) + const left = this.getValue(expression.leftOperand, accept) + const right = this.getValue(expression.rightOperand, accept) if (!left || !right) return undefined @@ -512,7 +513,7 @@ export class Solver { } } private static unaryOperation(expression: ast.UnaryOperation, accept?: ValidationAcceptor): Value | undefined { - let operand = this.getValue(expression.operand, accept) + const operand = this.getValue(expression.operand, accept) if (!operand) return undefined diff --git a/src/language/validation/xsmpcat-issue-codes.ts b/src/language/validation/xsmpcat-issue-codes.ts new file mode 100644 index 0000000..d033908 --- /dev/null +++ b/src/language/validation/xsmpcat-issue-codes.ts @@ -0,0 +1,22 @@ + + +export const TypeNotVisible = 'type-not-visible'; +export const FieldNotVisible = 'field-not-visible'; +export const InvalidFieldName = 'invalid-field-name'; +export const MissingValue = 'missing-value'; +export const MissingUuid = 'missing-uuid'; +export const DuplicatedUuid = 'duplicated-uuid'; +export const InvalidUuid = 'invalid-uuid'; +export const IllegalModifier = 'illegal-modifier'; +export const InvalidModifier = 'invalid-modifier'; +export const DuplicatedInterfaceBase = 'duplicated-interface-base'; +export const CyclicInterfaceBase = 'cyclic-interface-base'; +export const CyclicComponentBase = 'cyclic-component-base'; +export const CyclicClassBase = 'cyclic-class-base'; +export const MissingAbstract = 'missing-abstract'; +export const DuplicatedComponentInterface = 'duplicated-component-interface'; +export const InvalidUsage = 'invalid-usage'; +export const DuplicatedUsage = 'duplicated-usage'; +export const NonSimpleArray = 'non-simple-array'; +export const InvalidAttribute = 'invalid-attribute'; +export const DuplicatedException = 'duplicated-exception'; diff --git a/src/language/validation/xsmpcat-validator.ts b/src/language/validation/xsmpcat-validator.ts index 628234c..04cc298 100644 --- a/src/language/validation/xsmpcat-validator.ts +++ b/src/language/validation/xsmpcat-validator.ts @@ -5,6 +5,7 @@ import { isFloatingType, PrimitiveTypeKind, XsmpUtils } from '../utils/xsmp-util import { Solver } from '../utils/solver.js'; import { Instant } from '@js-joda/core'; import { findVisibleUris } from '../utils/project-utils.js'; +import * as IssueCodes from './xsmpcat-issue-codes.js'; /** * Register custom validation checks. @@ -76,29 +77,6 @@ const namedElementRegex = /^[a-zA-Z]\w*$/; const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; -export namespace IssueCodes { - export const TypeNotVisible = 'type-not-visible'; - export const FieldNotVisible = 'field-not-visible'; - export const InvalidFieldName = 'invalid-field-name'; - export const MissingValue = 'missing-value'; - export const MissingUuid = 'missing-uuid'; - export const DuplicatedUuid = 'duplicated-uuid'; - export const InvalidUuid = 'invalid-uuid'; - export const IllegalModifier = 'illegal-modifier'; - export const InvalidModifier = 'invalid-modifier'; - export const DuplicatedInterfaceBase = 'duplicated-interface-base'; - export const CyclicInterfaceBase = 'cyclic-interface-base'; - export const CyclicComponentBase = 'cyclic-component-base'; - export const CyclicClassBase = 'cyclic-class-base'; - export const MissingAbstract = 'missing-abstract'; - export const DuplicatedComponentInterface = 'duplicated-component-interface'; - export const InvalidUsage = 'invalid-usage'; - export const DuplicatedUsage = 'duplicated-usage'; - export const NonSimpleArray = 'non-simple-array'; - export const InvalidAttribute = 'invalid-attribute'; - export const DuplicatedException = 'duplicated-exception'; -} - /** * Implementation of custom validations. */ @@ -244,7 +222,7 @@ export class XsmpcatValidator { } - checkTypeReference>(accept: ValidationAcceptor, node: N, reference: Reference, property: Properties, index?: number): boolean { + checkTypeReference(accept: ValidationAcceptor, node: N, reference: Reference, property: Properties, index?: number): boolean { if (!reference.ref) return false @@ -270,7 +248,7 @@ export class XsmpcatValidator { } - checkFieldReference>(accept: ValidationAcceptor, node: N, field: ast.Field | undefined, property: Properties, index?: number): field is ast.Field { + checkFieldReference(accept: ValidationAcceptor, node: N, field: ast.Field | undefined, property: Properties, index?: number): field is ast.Field { if (!field) return false @@ -323,7 +301,7 @@ export class XsmpcatValidator { const size = collectionSize < fieldCount ? collectionSize : fieldCount for (let i = 0; i < size; ++i) { let exp = expression.elements[i] - let field = fields[i] + const field = fields[i] if (ast.isDesignatedInitializer(exp)) { if (exp.field.ref !== field) accept('error', `Invalid field name, expecting ${field.name}.`, { node: exp, property: 'field', data: diagnosticData(IssueCodes.InvalidFieldName) }) @@ -381,7 +359,7 @@ export class XsmpcatValidator { accept('error', 'An Enumeration shall contains at least one literal.', { node: enumeration, property: 'literal' }); } - const values = new Set(); + const values = new Set(); const literals = new Set(); for (const literal of enumeration.literal) { if (literals.has(literal.name)) @@ -803,7 +781,7 @@ export class XsmpcatValidator { try { Instant.parse(date.toString()) } - catch (error) { + catch { accept('error', 'Invalid date format (e.g: 1970-01-01T00:00:00Z).', { node: catalogue, range: date.range }) } } diff --git a/src/language/validation/xsmpproject-validator.ts b/src/language/validation/xsmpproject-validator.ts index ce0b9d3..e95578e 100644 --- a/src/language/validation/xsmpproject-validator.ts +++ b/src/language/validation/xsmpproject-validator.ts @@ -22,7 +22,7 @@ export function registerXsmpprojectValidationChecks(services: XsmpprojectService */ export class XsmpprojectValidator { - checkTypeReference>(accept: ValidationAcceptor, node: N, reference: Reference, property: Properties, index?: number): boolean { + checkTypeReference(accept: ValidationAcceptor, node: N, reference: Reference, property: Properties, index?: number): boolean { if (!reference.ref) return false diff --git a/src/language/wizard/wizard.ts b/src/language/wizard/wizard.ts new file mode 100644 index 0000000..8cd9b4b --- /dev/null +++ b/src/language/wizard/wizard.ts @@ -0,0 +1,348 @@ + +import * as vscode from 'vscode'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as os from "os"; +import { Instant } from '@js-joda/core'; + +const esaCdkProfileId = "esa-cdk"; +const esaCdkLegacyProfileId = "esa-cdk-legacy"; +const xsmpSdkProfileId = "xsmp-sdk"; +const smpToolId = "smp" +const pythonToolId = "python" +const adocToolId = "adoc" + +export async function createProjectWizard() { + + const destinationFolders = await vscode.window.showOpenDialog({ + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + title:'Root directory containing the new project.', + openLabel: "Select the root directory containing the new project." + }); + + if (!destinationFolders || destinationFolders.length === 0) + return; + + const destinationFolder = destinationFolders[0].fsPath; + + // Project name input + let projectName: string | undefined; + while (true) { + projectName = await vscode.window.showInputBox({ + prompt: "Enter project name" + }); + if (!projectName) + return + + if (/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(projectName)) { + break; + } else { + vscode.window.showErrorMessage("Project name must follow the format [a-zA-Z][a-zA-Z0-9_.-]\\w*"); + } + } + + // Select profile + const profiles = [ + { id: xsmpSdkProfileId, label: "XSMP-SDK Profile" }, + { id: esaCdkProfileId, label: "ESA-CDK Profile" }, + ]; + + const profile = await vscode.window.showQuickPick(profiles, { + placeHolder: "Select a profile" + }); + + if (!profile) + return; // If user cancels selection + + + // Select tools + const tools = [ + { id: smpToolId, label: "SMP Tool", "picked": true }, + { id: pythonToolId, label: "Python Wrapper", "picked": profile.id === xsmpSdkProfileId }, + { id: adocToolId, label: "AsciiDoc generator", "picked": true } + ]; + + + const selectedTools = await vscode.window.showQuickPick(tools, { + canPickMany: true, + placeHolder: "Select tools to enable" + }); + + if (!selectedTools) + return; // If user cancels selection + + // Create specific files + const projectFolderPath = path.join(destinationFolder, projectName); + + createTemplateProject(projectName, projectFolderPath, profile, selectedTools) + + // Add project to workspace + const addToWorkspace = await vscode.window.showQuickPick( + [ + { label: "Yes", addToWorkspace: true }, + { label: "No", addToWorkspace: false } + ], + { + placeHolder: "Add project to workspace?" + } + ); + + + const uri = vscode.Uri.file(projectFolderPath); + if (!vscode.workspace.workspaceFolders?.some(folder => uri.fsPath.startsWith(folder.uri.fsPath))) { + if (addToWorkspace?.addToWorkspace) { + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri }); + } + } + const xsmpcatFilePath = path.join(projectFolderPath, "smdl", `${projectName}.xsmpcat`); + const xsmpcatDocument = await vscode.workspace.openTextDocument(xsmpcatFilePath); + await vscode.window.showTextDocument(xsmpcatDocument); +} + + +async function createTemplateProject(projectName: string, dirPath: string, + profile: { label: string, id: string }, tools: { label: string, id: string }[]) { + fs.mkdirSync(dirPath); // Create project directory + + const smdlPath = path.join(dirPath, 'smdl'); + fs.mkdirSync(smdlPath); + + // Create the catalog file + const creator = os.userInfo().username; + const currentDate = Instant.now().toString(); + const catalogueName = projectName.replace(/[.-]/, '_'); + + await fs.promises.writeFile(path.join(smdlPath, `${projectName}.xsmpcat`), `// Copyright \${year} \${user}. All rights reserved. +// +// YOUR NOTICE +// +// Generation date: \${date} \${time} + +/** + * Catalogue ${projectName} + * + * @creator ${creator} + * @date ${currentDate} + */ +catalogue ${catalogueName} + +namespace ${catalogueName} +{ + +} // namespace ${catalogueName} + +`); + + + if (profile.id === xsmpSdkProfileId) { + await fs.promises.writeFile(path.join(dirPath, 'CMakeLists.txt'), ` +cmake_minimum_required(VERSION 3.14) + +project( + ${projectName} +# VERSION 1.0.0 +# DESCRIPTION "" +# HOMEPAGE_URL "" + LANGUAGES CXX) + +include(FetchContent) +FetchContent_Declare( + xsmp-sdk + GIT_REPOSITORY https://github.com/ThalesGroup/xsmp-sdk.git + GIT_TAG main # replace with a specific tag +) +FetchContent_MakeAvailable(xsmp-sdk) +list(APPEND CMAKE_MODULE_PATH "\${xsmp-sdk_SOURCE_DIR}/cmake") + +# add python directory to PYTHONPATH +include(PathUtils) +python_path_prepend("python") + +file(GLOB_RECURSE SRC CONFIGURE_DEPENDS src/*.cpp src-gen/*.cpp) + +add_library(${projectName} SHARED \${SRC}) +target_include_directories(${projectName} PUBLIC src src-gen) +target_link_libraries(${projectName} PUBLIC Xsmp::Cdk) + +# -------------------------------------------------------------------- + +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + include(CTest) +endif() + +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) + include(Pytest) + pytest_discover_tests() +endif() +`) + await fs.promises.writeFile(path.join(dirPath, 'README.md'), ` +# ${projectName} + +Project description. + +## System Requirements + +Check [xsmp-sdk system requirements](https://thalesgroup.github.io/xsmp-sdk/requirements.html). + +## How to Build + +\`\`\`bash +cmake -B ./build -DCMAKE_BUILD_TYPE=Release +cmake --build ./build --config Release +\`\`\` + +## How to Test + +\`\`\`bash +cd build && ctest -C Release --output-on-failure +\`\`\` + +`) + } + else if (profile.id === esaCdkProfileId || profile.id === esaCdkLegacyProfileId) { + await fs.promises.writeFile(path.join(dirPath, 'CMakeLists.txt'), ` +file(GLOB_RECURSE SRC CONFIGURE_DEPENDS src/*.cpp src-gen/*.cpp) + +simulus_library( + MAIN + SOURCES + \${SRC} + LIBRARIES + esa.ecss.smp.cdk +) +target_include_directories(${projectName} PUBLIC src src-gen) +`) + } + + if (tools.some(t => t.id === pythonToolId)) { + const py_path = path.join(dirPath, 'python') + fs.mkdirSync(py_path); + await fs.promises.writeFile(path.join(dirPath, `pytest.ini`), ` +# pytest.ini +[pytest] +testpaths = python`); + +const py_projectPath = path.join(py_path, catalogueName) + fs.mkdirSync(py_projectPath); + await fs.promises.writeFile(path.join(py_projectPath, `test_${catalogueName}.py`), ` +import ecss_smp +import xsmp +import ${catalogueName} + +class Test${catalogueName}(xsmp.unittest.TestCase): + try: + sim: ${catalogueName}._test_${catalogueName}.Simulator + except AttributeError: + pass + + def loadAssembly(self, sim: ecss_smp.Smp.ISimulator): + sim.LoadLibrary("${catalogueName}") + #TODO create instances, configuration, connections, ... + + def test_${catalogueName}(self): + # TODO write unit-test + pass`); + } + + if (tools.some(t => t.id === adocToolId)) { + const adoc_path = path.join(dirPath, 'doc') + fs.mkdirSync(adoc_path) + await fs.promises.writeFile(path.join(adoc_path, `${catalogueName}.adoc`), ` +:doctype: book +:toc: +:pdf-themesdir: {docdir} + += Catalogue document + +include::${catalogueName}-gen.adoc[] + `); + + const adoc_themepath = path.join(dirPath, 'doc', 'themes') + fs.mkdirSync(adoc_themepath); + await fs.promises.writeFile(path.join(adoc_themepath, `default.yml`), ` +extends: default +page: + margin: [1.5in, 0.75in] + numbering: + start_at: title +base: + font-family: Helvetica +running_content: + start_at: title +header: + height: 1.25in + border-width: 0.25 + border-color: #DDDDDD + recto: + center: + content: '{testvar}' + right: + content: | + *Date:* {localdatetime} + + *Page:* {page-number}/{page-count} + verso: + center: + content: $header-recto-center-content + right: + content: $header-recto-right-content +footer: + height: 0.85in + font-size: 9 + recto: + left: + content: '' + center: + content: | + *XSMP* + + This document has been automatically generated using the Adoc tool from XSMP Modeler. + + © {localyear}, All Rights Reserved + right: + content: '' + verso: + left: + content: $footer-recto-left-content + center: + content: $footer-recto-center-content + right: + content: $footer-recto-right-content + `); + } + + // Create the project file + + let content = ` +/** + * XSMP Project configuration for ${projectName} + */ +project "${projectName}" + +// project relative path(s) containing modeling file(s) +source "smdl" + +` + + if (profile) + content += ` +// use ${profile.label} +profile "${profile.id}" + +` + for (const tool of tools) + content += ` +// use ${tool.label} +tool "${tool.id}" + +` + + content += ` +// If your project needs types from outside sources, +// you can include them by adding project dependencies. +// For example: dependency "otherProject" +// dependency "otherProject2" + +` + + await fs.promises.writeFile(path.join(dirPath, 'xsmp.project'), content); +}