diff --git a/client/package-lock.json b/client/package-lock.json index 158d7b1..0a5b396 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "language-server-client", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "language-server-client", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "dependencies": { "axios": "^1.15.0", "vscode-languageclient": "^9.0.1" diff --git a/client/package.json b/client/package.json index 7d04fce..ac93a77 100644 --- a/client/package.json +++ b/client/package.json @@ -1,7 +1,7 @@ { "name": "language-server-client", "author": "InterSystems Corporation", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "private": true, "engines": { "vscode": "^1.93.0" @@ -15,4 +15,4 @@ "@types/semver": "^7.7.0", "@types/vscode": "1.93.0" } -} +} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index bd0725c..7a97ddb 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -10,6 +10,9 @@ export default tseslint.config( { rules: { "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-unused-vars": "warn", "no-control-regex": "off", }, } diff --git a/package-lock.json b/package-lock.json index 528508d..889f275 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "language-server", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "language-server", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE.txt", "devDependencies": { "@eslint/js": "^10.0.1", + "@types/eslint": "^9.6.1", "@types/node": "^22.15.33", "@types/turndown": "^5.0.6", "@vscode/vsce": "^3.7.1", @@ -30,6 +31,11 @@ "vscode": "^1.93.0" } }, + "../iris-class/pkg": { + "name": "iris-class", + "version": "0.1.0", + "extraneous": true + }, "node_modules/@azu/format-text": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@azu/format-text/-/format-text-1.0.2.tgz", @@ -309,40 +315,6 @@ "node": ">=14.17.0" } }, - "node_modules/@emnapi/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", - "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", - "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -667,19 +639,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", - "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, "node_modules/@node-rs/crc32": { "version": "1.10.6", "resolved": "https://registry.npmjs.org/@node-rs/crc32/-/crc32-1.10.6.tgz", @@ -710,40 +669,6 @@ "@node-rs/crc32-win32-x64-msvc": "1.10.6" } }, - "node_modules/@node-rs/crc32-android-arm-eabi": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.10.6.tgz", - "integrity": "sha512-vZAMuJXm3TpWPOkkhxdrofWDv+Q+I2oO7ucLRbXyAPmXFNDhHtBxbO1rk9Qzz+M3eep8ieS4/+jCL1Q0zacNMQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-android-arm64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm64/-/crc32-android-arm64-1.10.6.tgz", - "integrity": "sha512-Vl/JbjCinCw/H9gEpZveWCMjxjcEChDcDBM8S4hKay5yyoRCUHJPuKr4sjVDBeOm+1nwU3oOm6Ca8dyblwp4/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@node-rs/crc32-darwin-arm64": { "version": "1.10.6", "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.10.6.tgz", @@ -761,193 +686,6 @@ "node": ">= 10" } }, - "node_modules/@node-rs/crc32-darwin-x64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-x64/-/crc32-darwin-x64-1.10.6.tgz", - "integrity": "sha512-Q99bevJVMfLTISpkpKBlXgtPUItrvTWKFyiqoKH5IvscZmLV++NH4V13Pa17GTBmv9n18OwzgQY4/SRq6PQNVA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-freebsd-x64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-freebsd-x64/-/crc32-freebsd-x64-1.10.6.tgz", - "integrity": "sha512-66hpawbNjrgnS9EDMErta/lpaqOMrL6a6ee+nlI2viduVOmRZWm9Rg9XdGTK/+c4bQLdtC6jOd+Kp4EyGRYkAg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm-gnueabihf": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm-gnueabihf/-/crc32-linux-arm-gnueabihf-1.10.6.tgz", - "integrity": "sha512-E8Z0WChH7X6ankbVm8J/Yym19Cq3otx6l4NFPS6JW/cWdjv7iw+Sps2huSug+TBprjbcEA+s4TvEwfDI1KScjg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-gnu/-/crc32-linux-arm64-gnu-1.10.6.tgz", - "integrity": "sha512-LmWcfDbqAvypX0bQjQVPmQGazh4dLiVklkgHxpV4P0TcQ1DT86H/SWpMBMs/ncF8DGuCQ05cNyMv1iddUDugoQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-arm64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-musl/-/crc32-linux-arm64-musl-1.10.6.tgz", - "integrity": "sha512-k8ra/bmg0hwRrIEE8JL1p32WfaN9gDlUUpQRWsbxd1WhjqvXea7kKO6K4DwVxyxlPhBS9Gkb5Urq7Y4mXANzaw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-x64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-gnu/-/crc32-linux-x64-gnu-1.10.6.tgz", - "integrity": "sha512-IfjtqcuFK7JrSZ9mlAFhb83xgium30PguvRjIMI45C3FJwu18bnLk1oR619IYb/zetQT82MObgmqfKOtgemEKw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-linux-x64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-musl/-/crc32-linux-x64-musl-1.10.6.tgz", - "integrity": "sha512-LbFYsA5M9pNunOweSt6uhxenYQF94v3bHDAQRPTQ3rnjn+mK6IC7YTAYoBjvoJP8lVzcvk9hRj8wp4Jyh6Y80g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-wasm32-wasi": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-wasm32-wasi/-/crc32-wasm32-wasi-1.10.6.tgz", - "integrity": "sha512-KaejdLgHMPsRaxnM+OG9L9XdWL2TabNx80HLdsCOoX9BVhEkfh39OeahBo8lBmidylKbLGMQoGfIKDjq0YMStw==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@node-rs/crc32-win32-arm64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.10.6.tgz", - "integrity": "sha512-x50AXiSxn5Ccn+dCjLf1T7ZpdBiV1Sp5aC+H2ijhJO4alwznvXgWbopPRVhbp2nj0i+Gb6kkDUEyU+508KAdGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-ia32-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-ia32-msvc/-/crc32-win32-ia32-msvc-1.10.6.tgz", - "integrity": "sha512-DpDxQLaErJF9l36aghe1Mx+cOnYLKYo6qVPqPL9ukJ5rAGLtCdU0C+Zoi3gs9ySm8zmbFgazq/LvmsZYU42aBw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@node-rs/crc32-win32-x64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-x64-msvc/-/crc32-win32-x64-msvc-1.10.6.tgz", - "integrity": "sha512-5B1vXosIIBw1m2Rcnw62IIfH7W9s9f7H7Ma0rRuhT8HR4Xh8QCgw6NJSI2S2MCngsGktYnAhyUvs81b7efTyQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1279,37 +1017,17 @@ "@textlint/ast-node-types": "15.5.0" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -1686,32 +1404,6 @@ "@vscode/vsce-sign-win32-x64": "2.0.2" } }, - "node_modules/@vscode/vsce-sign-alpine-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz", - "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "alpine" - ] - }, - "node_modules/@vscode/vsce-sign-alpine-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz", - "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "alpine" - ] - }, "node_modules/@vscode/vsce-sign-darwin-arm64": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz", @@ -1725,84 +1417,6 @@ "darwin" ] }, - "node_modules/@vscode/vsce-sign-darwin-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz", - "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@vscode/vsce-sign-linux-arm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz", - "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@vscode/vsce-sign-linux-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz", - "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@vscode/vsce-sign-linux-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz", - "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@vscode/vsce-sign-win32-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz", - "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@vscode/vsce-sign-win32-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz", - "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@vscode/vsce/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -6562,6 +6176,17 @@ "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6995,37 +6620,6 @@ "integrity": "sha512-dDlz3W405VMFO4w5kIP9DOmELBcvFQGmLoKSdIRstBDubKFYwaNHV1NnlzMCQpXQFGWVALmeMORAuiLx18AvZQ==", "dev": true }, - "@emnapi/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", - "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", - "dev": true, - "optional": true, - "requires": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", - "dev": true, - "optional": true, - "requires": { - "tslib": "^2.4.0" - } - }, - "@emnapi/wasi-threads": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", - "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", - "dev": true, - "optional": true, - "requires": { - "tslib": "^2.4.0" - } - }, "@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -7236,18 +6830,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@napi-rs/wasm-runtime": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", - "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", - "dev": true, - "optional": true, - "requires": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, "@node-rs/crc32": { "version": "1.10.6", "resolved": "https://registry.npmjs.org/@node-rs/crc32/-/crc32-1.10.6.tgz", @@ -7270,20 +6852,6 @@ "@node-rs/crc32-win32-x64-msvc": "1.10.6" } }, - "@node-rs/crc32-android-arm-eabi": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.10.6.tgz", - "integrity": "sha512-vZAMuJXm3TpWPOkkhxdrofWDv+Q+I2oO7ucLRbXyAPmXFNDhHtBxbO1rk9Qzz+M3eep8ieS4/+jCL1Q0zacNMQ==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-android-arm64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm64/-/crc32-android-arm64-1.10.6.tgz", - "integrity": "sha512-Vl/JbjCinCw/H9gEpZveWCMjxjcEChDcDBM8S4hKay5yyoRCUHJPuKr4sjVDBeOm+1nwU3oOm6Ca8dyblwp4/w==", - "dev": true, - "optional": true - }, "@node-rs/crc32-darwin-arm64": { "version": "1.10.6", "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.10.6.tgz", @@ -7291,86 +6859,6 @@ "dev": true, "optional": true }, - "@node-rs/crc32-darwin-x64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-x64/-/crc32-darwin-x64-1.10.6.tgz", - "integrity": "sha512-Q99bevJVMfLTISpkpKBlXgtPUItrvTWKFyiqoKH5IvscZmLV++NH4V13Pa17GTBmv9n18OwzgQY4/SRq6PQNVA==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-freebsd-x64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-freebsd-x64/-/crc32-freebsd-x64-1.10.6.tgz", - "integrity": "sha512-66hpawbNjrgnS9EDMErta/lpaqOMrL6a6ee+nlI2viduVOmRZWm9Rg9XdGTK/+c4bQLdtC6jOd+Kp4EyGRYkAg==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-linux-arm-gnueabihf": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm-gnueabihf/-/crc32-linux-arm-gnueabihf-1.10.6.tgz", - "integrity": "sha512-E8Z0WChH7X6ankbVm8J/Yym19Cq3otx6l4NFPS6JW/cWdjv7iw+Sps2huSug+TBprjbcEA+s4TvEwfDI1KScjg==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-linux-arm64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-gnu/-/crc32-linux-arm64-gnu-1.10.6.tgz", - "integrity": "sha512-LmWcfDbqAvypX0bQjQVPmQGazh4dLiVklkgHxpV4P0TcQ1DT86H/SWpMBMs/ncF8DGuCQ05cNyMv1iddUDugoQ==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-linux-arm64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-musl/-/crc32-linux-arm64-musl-1.10.6.tgz", - "integrity": "sha512-k8ra/bmg0hwRrIEE8JL1p32WfaN9gDlUUpQRWsbxd1WhjqvXea7kKO6K4DwVxyxlPhBS9Gkb5Urq7Y4mXANzaw==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-linux-x64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-gnu/-/crc32-linux-x64-gnu-1.10.6.tgz", - "integrity": "sha512-IfjtqcuFK7JrSZ9mlAFhb83xgium30PguvRjIMI45C3FJwu18bnLk1oR619IYb/zetQT82MObgmqfKOtgemEKw==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-linux-x64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-musl/-/crc32-linux-x64-musl-1.10.6.tgz", - "integrity": "sha512-LbFYsA5M9pNunOweSt6uhxenYQF94v3bHDAQRPTQ3rnjn+mK6IC7YTAYoBjvoJP8lVzcvk9hRj8wp4Jyh6Y80g==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-wasm32-wasi": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-wasm32-wasi/-/crc32-wasm32-wasi-1.10.6.tgz", - "integrity": "sha512-KaejdLgHMPsRaxnM+OG9L9XdWL2TabNx80HLdsCOoX9BVhEkfh39OeahBo8lBmidylKbLGMQoGfIKDjq0YMStw==", - "dev": true, - "optional": true, - "requires": { - "@napi-rs/wasm-runtime": "^0.2.5" - } - }, - "@node-rs/crc32-win32-arm64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.10.6.tgz", - "integrity": "sha512-x50AXiSxn5Ccn+dCjLf1T7ZpdBiV1Sp5aC+H2ijhJO4alwznvXgWbopPRVhbp2nj0i+Gb6kkDUEyU+508KAdGQ==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-win32-ia32-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-ia32-msvc/-/crc32-win32-ia32-msvc-1.10.6.tgz", - "integrity": "sha512-DpDxQLaErJF9l36aghe1Mx+cOnYLKYo6qVPqPL9ukJ5rAGLtCdU0C+Zoi3gs9ySm8zmbFgazq/LvmsZYU42aBw==", - "dev": true, - "optional": true - }, - "@node-rs/crc32-win32-x64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-x64-msvc/-/crc32-win32-x64-msvc-1.10.6.tgz", - "integrity": "sha512-5B1vXosIIBw1m2Rcnw62IIfH7W9s9f7H7Ma0rRuhT8HR4Xh8QCgw6NJSI2S2MCngsGktYnAhyUvs81b7efTyQw==", - "dev": true, - "optional": true - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7622,16 +7110,6 @@ "@textlint/ast-node-types": "15.5.0" } }, - "@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "optional": true, - "requires": { - "tslib": "^2.4.0" - } - }, "@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -7642,16 +7120,6 @@ "@types/json-schema": "*" } }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -7901,20 +7369,6 @@ "@vscode/vsce-sign-win32-x64": "2.0.2" } }, - "@vscode/vsce-sign-alpine-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz", - "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-alpine-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz", - "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==", - "dev": true, - "optional": true - }, "@vscode/vsce-sign-darwin-arm64": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz", @@ -7922,48 +7376,6 @@ "dev": true, "optional": true }, - "@vscode/vsce-sign-darwin-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz", - "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-linux-arm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz", - "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-linux-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz", - "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-linux-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz", - "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-win32-arm64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz", - "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==", - "dev": true, - "optional": true - }, - "@vscode/vsce-sign-win32-x64": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz", - "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==", - "dev": true, - "optional": true - }, "@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -11197,6 +10609,18 @@ "terser-webpack-plugin": "^5.3.17", "watchpack": "^2.5.1", "webpack-sources": "^3.3.4" + }, + "dependencies": { + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + } } }, "webpack-cli": { diff --git a/package.json b/package.json index ccaecad..a40bfc1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A language server for InterSystems ObjectScript.", "author": "InterSystems Corporation", "license": "SEE LICENSE IN LICENSE.txt", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "publisher": "intersystems", "repository": { "type": "github", @@ -1796,6 +1796,7 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@types/eslint": "^9.6.1", "@types/node": "^22.15.33", "@types/turndown": "^5.0.6", "@vscode/vsce": "^3.7.1", diff --git a/server/lib/analyzer.wasm b/server/lib/analyzer.wasm new file mode 100755 index 0000000..7711e86 Binary files /dev/null and b/server/lib/analyzer.wasm differ diff --git a/server/package-lock.json b/server/package-lock.json index 0233843..13a65e7 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,13 +1,14 @@ { "name": "language-server-server", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "language-server-server", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "dependencies": { + "@vscode/wasm-component-model": "^1.0.2", "node-html-parser": "^7.1.0", "turndown": "^7.2.4", "vscode-languageserver": "^9.0.1", @@ -23,11 +24,84 @@ "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" }, + "node_modules/@vscode/wasm-component-model": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vscode/wasm-component-model/-/wasm-component-model-1.0.2.tgz", + "integrity": "sha512-3eBdSLvW1wAg2xHHupPD65S7/5eNpHiUY6hurLsoLB39GRGeC+hdthYXLHhbP7OtClhQS+flVH4Uy3ua9kT0pA==", + "license": "MIT", + "dependencies": { + "semver": "^7.7.2", + "uuid": "^11.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "wit2ts": "bin/wit2ts" + }, + "engines": { + "node": ">=18.18.2" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "license": "MIT" + }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -105,6 +179,12 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "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==", + "license": "MIT" + }, "node_modules/entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -116,6 +196,24 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -124,6 +222,15 @@ "he": "bin/he" } }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/node-html-parser": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-7.1.0.tgz", @@ -145,6 +252,53 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/turndown": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", @@ -158,6 +312,19 @@ "npm": ">=9" } }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", @@ -200,6 +367,59 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } } }, "dependencies": { @@ -208,11 +428,57 @@ "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" }, + "@vscode/wasm-component-model": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vscode/wasm-component-model/-/wasm-component-model-1.0.2.tgz", + "integrity": "sha512-3eBdSLvW1wAg2xHHupPD65S7/5eNpHiUY6hurLsoLB39GRGeC+hdthYXLHhbP7OtClhQS+flVH4Uy3ua9kT0pA==", + "requires": { + "semver": "^7.7.2", + "uuid": "^11.1.0", + "yargs": "^17.7.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "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==", + "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==" + }, "css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -263,16 +529,36 @@ "domhandler": "^5.0.1" } }, + "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==" + }, "entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "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==" + }, "node-html-parser": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-7.1.0.tgz", @@ -290,6 +576,34 @@ "boolbase": "^1.0.0" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "turndown": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", @@ -298,6 +612,11 @@ "@mixmark-io/domino": "^2.2.0" } }, + "uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==" + }, "vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", @@ -334,6 +653,40 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" } } } diff --git a/server/package.json b/server/package.json index f8e221c..a56c479 100644 --- a/server/package.json +++ b/server/package.json @@ -1,16 +1,17 @@ { "name": "language-server-server", - "version": "2.8.4-SNAPSHOT", + "version": "2.9.0-LOCAL", "author": "InterSystems Corporation", "private": true, "engines": { "node": "*" }, "dependencies": { + "@vscode/wasm-component-model": "^1.0.2", "node-html-parser": "^7.1.0", "turndown": "^7.2.4", "vscode-languageserver": "^9.0.1", "vscode-languageserver-textdocument": "^1.0.12", "vscode-uri": "^3.1.0" } -} +} \ No newline at end of file diff --git a/server/src/analyzer/bind.ts b/server/src/analyzer/bind.ts new file mode 100644 index 0000000..cf4210a --- /dev/null +++ b/server/src/analyzer/bind.ts @@ -0,0 +1,511 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as $wcm from "@vscode/wasm-component-model"; +import type { u8, i32, ptr, result } from "@vscode/wasm-component-model"; + +export namespace analyzer { + export type SrcLoc = { + ln: u8; + cn: u8; + }; + export type Range = { + lft: SrcLoc; + rht: SrcLoc; + }; + export type NameInfo = { + before: SrcLoc; + text: string; + after: SrcLoc; + }; + export type Arg = { + byRef: boolean; + variadic: boolean; + name: NameInfo; + t?: string | undefined; + }; + export type MethodInfo = { + args: Arg[]; + out?: string | undefined; + }; + export type ParameterInfo = { + t?: string | undefined; + v?: string | undefined; + }; + export namespace MemberKind { + export const parameter = "parameter" as const; + export type Parameter = { readonly tag: typeof parameter; readonly value: ParameterInfo } & _common; + export function Parameter(value: ParameterInfo): Parameter { + return new VariantImpl(parameter, value) as Parameter; + } + + export const property = "property" as const; + export type Property = { readonly tag: typeof property; readonly value: string | undefined } & _common; + export function Property(value: string | undefined): Property { + return new VariantImpl(property, value) as Property; + } + + export const relationship = "relationship" as const; + export type Relationship = { readonly tag: typeof relationship; readonly value: string | undefined } & _common; + export function Relationship(value: string | undefined): Relationship { + return new VariantImpl(relationship, value) as Relationship; + } + + export const foreignKey = "foreignKey" as const; + export type ForeignKey = { readonly tag: typeof foreignKey } & _common; + export function ForeignKey(): ForeignKey { + return new VariantImpl(foreignKey, undefined) as ForeignKey; + } + + export const index = "index" as const; + export type Index = { readonly tag: typeof index } & _common; + export function Index(): Index { + return new VariantImpl(index, undefined) as Index; + } + + export const projection = "projection" as const; + export type Projection = { readonly tag: typeof projection } & _common; + export function Projection(): Projection { + return new VariantImpl(projection, undefined) as Projection; + } + + export const trigger = "trigger" as const; + export type Trigger = { readonly tag: typeof trigger } & _common; + export function Trigger(): Trigger { + return new VariantImpl(trigger, undefined) as Trigger; + } + + export const xData = "xData" as const; + export type XData = { readonly tag: typeof xData } & _common; + export function XData(): XData { + return new VariantImpl(xData, undefined) as XData; + } + + export const storage = "storage" as const; + export type Storage = { readonly tag: typeof storage } & _common; + export function Storage(): Storage { + return new VariantImpl(storage, undefined) as Storage; + } + + export const query = "query" as const; + export type Query = { readonly tag: typeof query } & _common; + export function Query(): Query { + return new VariantImpl(query, undefined) as Query; + } + + export const method = "method" as const; + export type Method = { readonly tag: typeof method; readonly value: MethodInfo } & _common; + export function Method(value: MethodInfo): Method { + return new VariantImpl(method, value) as Method; + } + + export const classMethod = "classMethod" as const; + export type ClassMethod = { readonly tag: typeof classMethod; readonly value: MethodInfo } & _common; + export function ClassMethod(value: MethodInfo): ClassMethod { + return new VariantImpl(classMethod, value) as ClassMethod; + } + + export const clientMethod = "clientMethod" as const; + export type ClientMethod = { readonly tag: typeof clientMethod; readonly value: MethodInfo } & _common; + export function ClientMethod(value: MethodInfo): ClientMethod { + return new VariantImpl(clientMethod, value) as ClientMethod; + } + + export type _tt = + | typeof parameter + | typeof property + | typeof relationship + | typeof foreignKey + | typeof index + | typeof projection + | typeof trigger + | typeof xData + | typeof storage + | typeof query + | typeof method + | typeof classMethod + | typeof clientMethod; + export type _vt = + | ParameterInfo + | string + | undefined + | string + | undefined + | MethodInfo + | MethodInfo + | MethodInfo + | undefined; + type _common = Omit; + export function _ctor(t: _tt, v: _vt): MemberKind { + return new VariantImpl(t, v) as MemberKind; + } + class VariantImpl { + private readonly _tag: _tt; + private readonly _value?: _vt; + constructor(t: _tt, value: _vt) { + this._tag = t; + this._value = value; + } + get tag(): _tt { + return this._tag; + } + get value(): _vt { + return this._value; + } + isParameter(): this is Parameter { + return this._tag === MemberKind.parameter; + } + isProperty(): this is Property { + return this._tag === MemberKind.property; + } + isRelationship(): this is Relationship { + return this._tag === MemberKind.relationship; + } + isForeignKey(): this is ForeignKey { + return this._tag === MemberKind.foreignKey; + } + isIndex(): this is Index { + return this._tag === MemberKind.index; + } + isProjection(): this is Projection { + return this._tag === MemberKind.projection; + } + isTrigger(): this is Trigger { + return this._tag === MemberKind.trigger; + } + isXData(): this is XData { + return this._tag === MemberKind.xData; + } + isStorage(): this is Storage { + return this._tag === MemberKind.storage; + } + isQuery(): this is Query { + return this._tag === MemberKind.query; + } + isMethod(): this is Method { + return this._tag === MemberKind.method; + } + isClassMethod(): this is ClassMethod { + return this._tag === MemberKind.classMethod; + } + isClientMethod(): this is ClientMethod { + return this._tag === MemberKind.clientMethod; + } + } + } + export type MemberKind = + | MemberKind.Parameter + | MemberKind.Property + | MemberKind.Relationship + | MemberKind.ForeignKey + | MemberKind.Index + | MemberKind.Projection + | MemberKind.Trigger + | MemberKind.XData + | MemberKind.Storage + | MemberKind.Query + | MemberKind.Method + | MemberKind.ClassMethod + | MemberKind.ClientMethod; + export type MemberInfo = { + doc: string; + before: SrcLoc; + name: NameInfo; + deprecated: boolean; + kind: MemberKind; + after: SrcLoc; + }; + export type ClassInfo = { + doc: string; + name: NameInfo; + extends: string[]; + deprecated: boolean; + members: MemberInfo[]; + }; + export type MacroInfo = { + name: NameInfo; + args: string[]; + }; + export type SubroutineInfo = { + name: NameInfo; + args: string[]; + }; + export namespace RoutineInfo { + export const inc = "INC" as const; + export type INC = { readonly tag: typeof inc; readonly value: MacroInfo[] } & _common; + export function INC(value: MacroInfo[]): INC { + return new VariantImpl(inc, value) as INC; + } + + export const int = "INT" as const; + export type INT = { readonly tag: typeof int; readonly value: SubroutineInfo[] } & _common; + export function INT(value: SubroutineInfo[]): INT { + return new VariantImpl(int, value) as INT; + } + + export const mac = "MAC" as const; + export type MAC = { readonly tag: typeof mac; readonly value: SubroutineInfo[] } & _common; + export function MAC(value: SubroutineInfo[]): MAC { + return new VariantImpl(mac, value) as MAC; + } + + export type _tt = typeof inc | typeof int | typeof mac; + export type _vt = MacroInfo[] | SubroutineInfo[] | SubroutineInfo[]; + type _common = Omit; + export function _ctor(t: _tt, v: _vt): RoutineInfo { + return new VariantImpl(t, v) as RoutineInfo; + } + class VariantImpl { + private readonly _tag: _tt; + private readonly _value: _vt; + constructor(t: _tt, value: _vt) { + this._tag = t; + this._value = value; + } + get tag(): _tt { + return this._tag; + } + get value(): _vt { + return this._value; + } + isINC(): this is INC { + return this._tag === RoutineInfo.inc; + } + isINT(): this is INT { + return this._tag === RoutineInfo.int; + } + isMAC(): this is MAC { + return this._tag === RoutineInfo.mac; + } + } + } + export type RoutineInfo = RoutineInfo.INC | RoutineInfo.INT | RoutineInfo.MAC; + export type ParseErr = { + range: Range; + message: string; + }; + export namespace AnalysisErr { + export const p = "P" as const; + export type P = { readonly tag: typeof p; readonly value: ParseErr } & _common; + export function P(value: ParseErr): P { + return new VariantImpl(p, value) as P; + } + + export type _tt = typeof p; + export type _vt = ParseErr; + type _common = Omit; + export function _ctor(t: _tt, v: _vt): AnalysisErr { + return new VariantImpl(t, v) as AnalysisErr; + } + class VariantImpl { + private readonly _tag: _tt; + private readonly _value: _vt; + constructor(t: _tt, value: _vt) { + this._tag = t; + this._value = value; + } + get tag(): _tt { + return this._tag; + } + get value(): _vt { + return this._value; + } + isP(): this is P { + return this._tag === AnalysisErr.p; + } + } + } + export type AnalysisErr = AnalysisErr.P; + export namespace AnalysisErr { + export class Error_ extends $wcm.ResultError { + constructor(cause: AnalysisErr) { + super(`AnalysisErr: ${cause}`, cause); + } + } + } + export type Imports = {}; + export namespace Imports { + export type Promisified = $wcm.$imports.Promisify; + } + export namespace imports { + export type Promisify = $wcm.$imports.Promisify; + } + export type Exports = { + /** + * @throws AnalysisErr.Error_ + */ + analyzeCls: (path: string, src: string) => ClassInfo; + /** + * @throws AnalysisErr.Error_ + */ + analyzeRtn: (path: string, src: string) => RoutineInfo; + }; + export namespace Exports { + export type Promisified = $wcm.$exports.Promisify; + } + export namespace exports { + export type Promisify = $wcm.$exports.Promisify; + } +} + +export namespace analyzer.$ { + export const SrcLoc = new $wcm.RecordType([ + ["ln", $wcm.u8], + ["cn", $wcm.u8], + ]); + export const Range = new $wcm.RecordType([ + ["lft", SrcLoc], + ["rht", SrcLoc], + ]); + export const NameInfo = new $wcm.RecordType([ + ["before", SrcLoc], + ["text", $wcm.wstring], + ["after", SrcLoc], + ]); + export const Arg = new $wcm.RecordType([ + ["byRef", $wcm.bool], + ["variadic", $wcm.bool], + ["name", NameInfo], + ["t", new $wcm.OptionType($wcm.wstring)], + ]); + export const MethodInfo = new $wcm.RecordType([ + ["args", new $wcm.ListType(Arg)], + ["out", new $wcm.OptionType($wcm.wstring)], + ]); + export const ParameterInfo = new $wcm.RecordType([ + ["t", new $wcm.OptionType($wcm.wstring)], + ["v", new $wcm.OptionType($wcm.wstring)], + ]); + export const MemberKind = new $wcm.VariantType( + [ + ["parameter", ParameterInfo], + ["property", new $wcm.OptionType($wcm.wstring)], + ["relationship", new $wcm.OptionType($wcm.wstring)], + ["foreignKey", undefined], + ["index", undefined], + ["projection", undefined], + ["trigger", undefined], + ["xData", undefined], + ["storage", undefined], + ["query", undefined], + ["method", MethodInfo], + ["classMethod", MethodInfo], + ["clientMethod", MethodInfo], + ], + analyzer.MemberKind._ctor, + ); + export const MemberInfo = new $wcm.RecordType([ + ["doc", $wcm.wstring], + ["before", SrcLoc], + ["name", NameInfo], + ["deprecated", $wcm.bool], + ["kind", MemberKind], + ["after", SrcLoc], + ]); + export const ClassInfo = new $wcm.RecordType([ + ["doc", $wcm.wstring], + ["name", NameInfo], + ["extends", new $wcm.ListType($wcm.wstring)], + ["deprecated", $wcm.bool], + ["members", new $wcm.ListType(MemberInfo)], + ]); + export const MacroInfo = new $wcm.RecordType([ + ["name", NameInfo], + ["args", new $wcm.ListType($wcm.wstring)], + ]); + export const SubroutineInfo = new $wcm.RecordType([ + ["name", NameInfo], + ["args", new $wcm.ListType($wcm.wstring)], + ]); + export const RoutineInfo = new $wcm.VariantType( + [ + ["INC", new $wcm.ListType(MacroInfo)], + ["INT", new $wcm.ListType(SubroutineInfo)], + ["MAC", new $wcm.ListType(SubroutineInfo)], + ], + analyzer.RoutineInfo._ctor, + ); + export const ParseErr = new $wcm.RecordType([ + ["range", Range], + ["message", $wcm.wstring], + ]); + export const AnalysisErr = new $wcm.VariantType( + [["P", ParseErr]], + analyzer.AnalysisErr._ctor, + ); + export namespace exports { + export const analyzeCls = new $wcm.FunctionType( + "analyze-cls", + [ + ["path", $wcm.wstring], + ["src", $wcm.wstring], + ], + new $wcm.ResultType( + ClassInfo, + AnalysisErr, + analyzer.AnalysisErr.Error_, + ), + ); + export const analyzeRtn = new $wcm.FunctionType( + "analyze-rtn", + [ + ["path", $wcm.wstring], + ["src", $wcm.wstring], + ], + new $wcm.ResultType( + RoutineInfo, + AnalysisErr, + analyzer.AnalysisErr.Error_, + ), + ); + } +} +export namespace analyzer._ { + export const id = "iris:objectscript-analyzer/analyzer" as const; + export const witName = "analyzer" as const; + export namespace exports { + export const functions: Map = new Map([ + ["analyzeCls", $.exports.analyzeCls], + ["analyzeRtn", $.exports.analyzeRtn], + ]); + export function bind(exports: Exports, context: $wcm.WasmContext): analyzer.Exports { + return $wcm.$exports.bind(_, exports, context); + } + } + export type Exports = { + "analyze-cls": ( + path_ptr: i32, + path_len: i32, + src_ptr: i32, + src_len: i32, + result: ptr>, + ) => void; + "analyze-rtn": ( + path_ptr: i32, + path_len: i32, + src_ptr: i32, + src_len: i32, + result: ptr>, + ) => void; + }; + export function bind( + service: analyzer.Imports, + code: $wcm.Code, + context?: $wcm.ComponentModelContext, + ): Promise; + export function bind( + service: analyzer.Imports.Promisified, + code: $wcm.Code, + port: $wcm.RAL.ConnectionPort, + context?: $wcm.ComponentModelContext, + ): Promise; + export function bind( + service: analyzer.Imports | analyzer.Imports.Promisified, + code: $wcm.Code, + portOrContext?: $wcm.RAL.ConnectionPort | $wcm.ComponentModelContext, + context?: $wcm.ComponentModelContext | undefined, + ): Promise | Promise { + return $wcm.$main.bind(_, service, code, portOrContext, context); + } +} diff --git a/server/src/analyzer/index.ts b/server/src/analyzer/index.ts new file mode 100644 index 0000000..c72b018 --- /dev/null +++ b/server/src/analyzer/index.ts @@ -0,0 +1,60 @@ +import { Memory, WasmContext } from "@vscode/wasm-component-model"; +import * as fs from "fs"; +import * as path from "path"; +import { analyzer } from "./bind"; +import { Diagnostic, DiagnosticSeverity, Range } from "vscode-languageserver"; + +const filename = path.resolve(__dirname, "../lib/analyzer.wasm"); + +async function loadAnalyzer() { + const bits = fs.readFileSync(filename); + const module = await WebAssembly.compile(bits); + + // The context for the WASM module + const wasmContext: WasmContext.Default = new WasmContext.Default(); + + // Instantiate the module + const instance = await WebAssembly.instantiate(module, {}); + // Bind the WASM memory to the context + wasmContext.initialize(new Memory.Default(instance.exports)); + + // Bind the TypeScript Api + return analyzer._.exports.bind(instance.exports as analyzer._.Exports, wasmContext); +} + +export type Arg = analyzer.Arg; +export type MethodInfo = analyzer.MethodInfo; +export type ParameterInfo = analyzer.ParameterInfo; +export type MemberKind = analyzer.MemberKind; +export type MemberInfo = analyzer.MemberInfo; +export type ClassInfo = analyzer.ClassInfo; +export type AnalysisErr = analyzer.AnalysisErr; + +const wasm = loadAnalyzer(); + +export type AnalyzeResult = ClassInfo | { error: Diagnostic[] }; + +export async function analyzeCls(path: string, src: string): Promise { + try { + return (await wasm).analyzeCls(path, src); + } catch (rawError) { + const error = rawError["cause"]["_value"] as analyzer.ParseErr; + const range = Range.create( + error.range.lft.ln - 1, + error.range.lft.cn - 1, + error.range.rht.ln - 1, + error.range.rht.cn - 1, + ); + const message = error.message; + return { + error: [ + { + severity: DiagnosticSeverity.Information, + range, + message, + source: "InterSystems Language Server", + }, + ], + }; + } +} diff --git a/server/src/providers/completion.ts b/server/src/providers/completion.ts index 52c1718..9a7a5cd 100644 --- a/server/src/providers/completion.ts +++ b/server/src/providers/completion.ts @@ -36,7 +36,13 @@ import { compressedline, LanguageServerConfiguration, } from "../utils/types"; -import { documents, corePropertyParams, mppContinue } from "../utils/variables"; +import { + documents, + corePropertyParams, + mppContinue, + getAnalyzedClassMembers, + getAnalyzedClasses, +} from "../utils/variables"; import * as ld from "../utils/languageDefinitions"; import structuredSystemVariables from "../documentation/structuredSystemVariables.json"; @@ -57,6 +63,7 @@ import storageKeywords from "../documentation/keywords/Storage.json"; import triggerKeywords from "../documentation/keywords/Trigger.json"; import xdataKeywords from "../documentation/keywords/XData.json"; import { TextDocument } from "vscode-languageserver-textdocument"; +import { localInfoPrefix } from "./hover"; /** * ServerSpec's mapped to the XML assist schema cache for that server. @@ -573,61 +580,81 @@ async function completionFullClassName( ): Promise { const result: CompletionItem[] = []; + // Add locally available classes + const added = new Set(); + for (const [uri, cls] of getAnalyzedClasses()) { + added.add(cls.name.text); + const item = makeClassCompletionItem( + [] /* I tried getImports() but it gives false imports */, + cls.name.text, + uri, + cls.deprecated, + ); + item.documentation = { + kind: MarkupKind.Markdown, + value: documaticHtmlToMarkdown(cls.doc), + }; + item.insertText = item.label; + item.label = localInfoPrefix + item.label; + result.push(item); + } + // Get the list of imports for resolution const imports = await getImports(doc, parsed, line, server); - // Get all classes const querydata = { - query: `SELECT dcd.Name, dcd.Deprecated FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${ - !settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" - }`, + query: `SELECT dcd.Name, dcd.Deprecated FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${!settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" + }`, parameters: ["*.cls", 1, 1, 1, 1, 0, settings.completion.showGenerated ? 1 : 0], }; const respdata = await makeRESTRequest("POST", 1, "/action/query", server, querydata); if (respdata !== undefined && respdata.data.result.content.length > 0) { for (const clsobj of respdata.data.result.content) { - let displayname: string = clsobj.Name; - let compItem: CompletionItem; - if (imports.length > 0) { - // Resolve import - let sortText: string; - for (const imp of imports) { - if (displayname.indexOf(imp) === 0 && displayname.slice(imp.length + 1).indexOf(".") === -1) { - displayname = displayname.slice(imp.length + 1); - sortText = "%%%" + displayname; - break; - } - } - if (displayname.startsWith("%Library.")) { - // Use short form for %Library classes - displayname = "%" + displayname.slice(9); - } - compItem = { - label: displayname, - kind: CompletionItemKind.Class, - data: ["class", clsobj.Name, doc.uri], - sortText, - }; - } else { - if (displayname.startsWith("%Library.")) { - // Use short form for %Library classes - displayname = "%" + displayname.slice(9); - } - compItem = { - label: displayname, - kind: CompletionItemKind.Class, - data: ["class", clsobj.Name, doc.uri], - }; - } - if (clsobj.Deprecated) { - compItem.tags = [CompletionItemTag.Deprecated]; - } + const compItem: CompletionItem = makeClassCompletionItem(imports, clsobj.Name, doc.uri, clsobj.Deprecated); + if (added.has(clsobj.Name)) continue result.push(compItem); } } + return result; } +function makeClassCompletionItem(imports: string[], name: string, uri: TextDocument["uri"], deprecated: boolean) { + let displayName: string = name; + let sortText: string | null = null; + if (imports.length > 0) { + // Resolve import + for (const imp of imports) { + if (displayName.indexOf(imp) === 0 && displayName.slice(imp.length + 1).indexOf(".") === -1) { + displayName = displayName.slice(imp.length + 1); + sortText = "%%%" + displayName; + break; + } + } + if (displayName.startsWith("%Library.")) { + // Use short form for %Library classes + displayName = "%" + displayName.slice(9); + } + } else { + if (displayName.startsWith("%Library.")) { + // Use short form for %Library classes + displayName = "%" + displayName.slice(9); + } + } + const compItem: CompletionItem = { + label: displayName, + kind: CompletionItemKind.Class, + data: ["class", name, uri], + }; + if (sortText !== null) { + compItem.sortText = sortText; + } + if (deprecated) { + compItem.tags = [CompletionItemTag.Deprecated]; + } + return compItem; +} + /** * Build the list of all packages for code completion. * @@ -638,9 +665,8 @@ async function completionPackage(server: ServerSpec, settings: LanguageServerCon // Get all the packages const querydata = { - query: `SELECT DISTINCT $PIECE(dcd.Name,'.',1,$LENGTH(dcd.Name,'.')-1) AS Package FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${ - !settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" - }`, + query: `SELECT DISTINCT $PIECE(dcd.Name,'.',1,$LENGTH(dcd.Name,'.')-1) AS Package FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${!settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" + }`, parameters: ["*.cls", 1, 1, 1, 1, 0, settings.completion.showGenerated ? 1 : 0], }; const respdata = await makeRESTRequest("POST", 1, "/action/query", server, querydata); @@ -756,13 +782,13 @@ async function globalsOrRoutines( server, isRoutine ? { - query: `SELECT DISTINCT $PIECE(Name,'.',1,$LENGTH(Name,'.')-1) AS Name FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,1,1,1,0,'NOT (Name %PATTERN ''.E1"."0.1"G"1N1".obj"'' AND $LENGTH(Name,''.'') > 3)')`, - parameters: [`${prefix.length ? `${prefix.slice(0, -1)}/` : ""}*.mac,*.int,*.obj`], - } + query: `SELECT DISTINCT $PIECE(Name,'.',1,$LENGTH(Name,'.')-1) AS Name FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,1,1,1,0,'NOT (Name %PATTERN ''.E1"."0.1"G"1N1".obj"'' AND $LENGTH(Name,''.'') > 3)')`, + parameters: [`${prefix.length ? `${prefix.slice(0, -1)}/` : ""}*.mac,*.int,*.obj`], + } : { - query: "SELECT Name FROM %SYS.GlobalQuery_NameSpaceList(,?,?,,,1,0)", - parameters: [`${prefix}*`, (await showInternalForServer(server)) ? 1 : 0], - }, + query: "SELECT Name FROM %SYS.GlobalQuery_NameSpaceList(,?,?,,,1,0)", + parameters: [`${prefix}*`, (await showInternalForServer(server)) ? 1 : 0], + }, ); if (Array.isArray(respdata?.data?.result?.content) && respdata.data.result.content.length > 0) { return respdata.data.result.content.map((item: { Name: string }) => { @@ -1120,9 +1146,8 @@ export async function onCompletion(params: CompletionParams): Promise(); + for (const [uri, cls] of getAnalyzedClasses()) { + if (!cls.name.text.startsWith(filter)) { + continue; + } + added.add(cls.name.text); + result.push({ + label: cls.name.text.slice(filter.length), + kind: CompletionItemKind.Class, + data: ["class", cls.name.text.slice(filter.length), uri], + tags: cls.deprecated ? [CompletionItemTag.Deprecated] : undefined, + documentation: { + kind: MarkupKind.Markdown, + value: documaticHtmlToMarkdown(cls.doc), + }, + }); + } + // Get all classes that match the filter const querydata = { - query: `SELECT dcd.Name, dcd.Deprecated FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${ - !settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" - }`, + query: `SELECT dcd.Name, dcd.Deprecated FROM %Library.RoutineMgr_StudioOpenDialog(?,?,?,?,?,?,?,?) AS sod, %Dictionary.ClassDefinition AS dcd WHERE sod.Name = dcd.Name||'.cls'${!settings.completion.showDeprecated ? " AND dcd.Deprecated = 0" : "" + }`, parameters: ["*.cls", 1, 1, 1, 1, 0, settings.completion.showGenerated ? 1 : 0, `Name %STARTSWITH '${filter}'`], }; const respdata = await makeRESTRequest("POST", 1, "/action/query", server, querydata); @@ -1270,6 +1313,7 @@ export async function onCompletion(params: CompletionParams): Promise(); + for (const [_uri, _cls, mem] of getAnalyzedClassMembers(membercontext.baseclass)) { + if (mem.kind.tag === "parameter") { + const name = quoteUDLIdentifier(mem.name.text, 1); + added.add(name); + result.push({ + label: "#" + name, + kind: CompletionItemKind.Constant, + data: "member", + documentation: { + kind: MarkupKind.Markdown, + value: documaticHtmlToMarkdown(mem.doc), + }, + sortText: name, + insertText: name, + detail: mem.kind.value.t, + tags: mem.deprecated ? [CompletionItemTag.Deprecated] : [], + }); + } + } // Query the server to get the names and descriptions of all parameters const data: QueryData = { - query: `SELECT Name, Description, Origin, Type, Deprecated FROM %Dictionary.CompiledParameter WHERE Parent = ?${ - membercontext.context == "instance" - ? " AND (parent->ClassType IS NULL OR parent->ClassType != 'datatype')" - : "" - }${internalStr}${deprecatedStr}`, + query: `SELECT Name, Description, Origin, Type, Deprecated FROM %Dictionary.CompiledParameter WHERE Parent = ?${membercontext.context == "instance" + ? " AND (parent->ClassType IS NULL OR parent->ClassType != 'datatype')" + : "" + }${internalStr}${deprecatedStr}`, parameters: [membercontext.baseclass], }; const respdata = await makeRESTRequest("POST", 1, "/action/query", server, data); if (Array.isArray(respdata?.data?.result?.content) && respdata.data.result.content.length > 0) { // We got data back - for (const memobj of respdata.data.result.content) { const quotedname = quoteUDLIdentifier(memobj.Name, 1); + if (added.has(quotedname)) continue; const item: CompletionItem = { label: "#" + quotedname, kind: CompletionItemKind.Constant, @@ -1353,6 +1417,43 @@ export async function onCompletion(params: CompletionParams): Promise(); + for (const [_uri, _cls, mem] of getAnalyzedClassMembers(membercontext.baseclass)) { + const name = quoteUDLIdentifier(mem.name.text, 1); + added.add(name); + const item: CompletionItem = { + label: name, + kind: CompletionItemKind.Property, + data: "member", + documentation: { + kind: MarkupKind.Markdown, + value: documaticHtmlToMarkdown(mem.doc), + }, + sortText: name, + insertText: name, + }; + if (mem.kind.tag === "classMethod" || mem.kind.tag === "method" || mem.kind.tag === "clientMethod") { + item.kind = CompletionItemKind.Method; + if (mem.kind.value.args.length == 0) { + item.insertText += "()"; + } else { + item.textEdit = TextEdit.insert(params.position, name.replace(/\$/g, "//$") + "($0)"); + item.insertTextFormat = InsertTextFormat.Snippet; + item.command = { + title: "Show SignatureHelp", + command: "editor.action.triggerParameterHints", + }; + } + } else if (mem.kind.tag === "parameter") { + item.kind = CompletionItemKind.Constant; + item.insertText = "#" + name; + } + if (mem.deprecated) { + item.tags = [CompletionItemTag.Deprecated]; + } + result.push(item); + } + // Query the server to get the metadata of all appropriate class members const data: QueryData = { query: "", @@ -1421,6 +1522,7 @@ export async function onCompletion(params: CompletionParams): Promise { + if (item.documentation) return item; if (Array.isArray(item.data) && item.data[0] === "class") { // Get the description for this class from the server const server: ServerSpec = await getServerSpec(item.data[2]); diff --git a/server/src/providers/definition.ts b/server/src/providers/definition.ts index 56703c5..f65b221 100644 --- a/server/src/providers/definition.ts +++ b/server/src/providers/definition.ts @@ -1,4 +1,4 @@ -import { Position, TextDocumentPositionParams, Range, LocationLink } from "vscode-languageserver/node"; +import { Position, TextDocumentPositionParams, Range, LocationLink, uinteger } from "vscode-languageserver/node"; import { TextDocument } from "vscode-languageserver-textdocument"; import { getServerSpec, @@ -19,7 +19,14 @@ import { urlMapAttribute, } from "../utils/functions"; import { ServerSpec, QueryData, compressedline } from "../utils/types"; -import { documents, corePropertyParams, classMemberTypes, mppContinue } from "../utils/variables"; +import { + documents, + corePropertyParams, + classMemberTypes, + mppContinue, + getAnalyzedClass, + getAnalyzedClassMember, +} from "../utils/variables"; import * as ld from "../utils/languageDefinitions"; /** @@ -28,6 +35,34 @@ import * as ld from "../utils/languageDefinitions"; */ const definitionTargetRangeMaxLines: number = 10; +function lookupClassMember(clsName: string, memName: string, originSelectionRange: Range): LocationLink[] | null { + const uri_cls_mem = getAnalyzedClassMember(clsName, memName); + if (!uri_cls_mem) { + return null; + } + const [targetUri, _clsInfo, memInfo] = uri_cls_mem; + const targetRange = Range.create( + Number(memInfo.before.ln) - 1, + Number(memInfo.before.cn) - 1, + Number(memInfo.after.ln) - 1, + Number(memInfo.after.cn) - 1, + ); // the member definition + const targetSelectionRange = Range.create( + Number(memInfo.name.before.ln) - 1, + Number(memInfo.name.before.cn) - 1, + Number(memInfo.name.after.ln) - 1, + Number(memInfo.name.after.cn) - 1, + ); // the member name + return [ + { + targetUri, + targetRange, + originSelectionRange, + targetSelectionRange, + }, + ]; +} + /** Return a `LocationLink` for class member `memberName` in class `cls` */ async function classMemberLocationLink( uri: string, @@ -37,6 +72,11 @@ async function classMemberLocationLink( memberRange: Range, server: ServerSpec, ): Promise { + const localResult = lookupClassMember(cls, memberName, memberRange); + if (localResult) { + return localResult; + } + const targetrange = Range.create(0, 0, 0, 0); let targetselrange = Range.create(0, 0, 0, 0); const newuri = await createDefinitionUri(uri, cls, ".cls"); @@ -108,6 +148,25 @@ async function classLocationLink( range: Range, server: ServerSpec, ): Promise { + const uri_cls = getAnalyzedClass(cls); + if (uri_cls) { + const [targetUri, clsInfo] = uri_cls; + const targetRange = Range.create(0, 0, uinteger.MAX_VALUE, uinteger.MAX_VALUE); // the whole file + const targetSelectionRange = Range.create( + Number(clsInfo.name.before.ln) - 1, + Number(clsInfo.name.before.cn) - 1, + Number(clsInfo.name.after.ln) - 1, + Number(clsInfo.name.after.cn) - 1, + ); // the class name + return [ + { + targetUri, + targetRange, + originSelectionRange: range, + targetSelectionRange, + }, + ]; + } // Get the uri of the target class const newuri = await createDefinitionUri(uri, cls, ".cls"); if (newuri != "") { @@ -452,6 +511,11 @@ export async function onDefinition(params: TextDocumentPositionParams) { return null; } + const localResult = lookupClassMember(membercontext.baseclass, unquotedname, memberrange); + if (localResult) { + return localResult; + } + let memberKeywords = parsed[params.position.line][i].s == ld.cos_prop_attrindex ? "Parameter" diff --git a/server/src/providers/diagnostic.ts b/server/src/providers/diagnostic.ts index f599bd1..c7489a5 100644 --- a/server/src/providers/diagnostic.ts +++ b/server/src/providers/diagnostic.ts @@ -7,6 +7,8 @@ import { DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, + WorkspaceDiagnosticReport, + WorkspaceDocumentDiagnosticReport, } from "vscode-languageserver"; import { @@ -19,8 +21,9 @@ import { normalizeClassname, quoteUDLIdentifier, isClassMember, + getAnalyzedDocument, } from "../utils/functions"; -import { zutilFunctions, lexerLanguages, documents } from "../utils/variables"; +import { zutilFunctions, lexerLanguages, documents, analyzedDocuments } from "../utils/variables"; import { ServerSpec, StudioOpenDialogFile, QueryData } from "../utils/types"; import * as ld from "../utils/languageDefinitions"; import parameterTypes from "../documentation/parameterTypes.json"; @@ -59,11 +62,17 @@ export async function onDiagnostics(params: DocumentDiagnosticParams): Promise { return !(settings.diagnostics.suppressSyntaxErrors).includes( @@ -1451,3 +1460,20 @@ export async function onDiagnostics(params: DocumentDiagnosticParams): Promise { + const items: WorkspaceDocumentDiagnosticReport[] = []; + const uris = [...analyzedDocuments.keys()]; + for (const uri of uris) { + const res = await getAnalyzedDocument(uri); + if ("error" in res) { + items.push({ + kind: "full", + uri, + version: null, + items: res.error, + }); + } + } + return { items }; +} diff --git a/server/src/providers/hover.ts b/server/src/providers/hover.ts index f054f3b..528b28b 100644 --- a/server/src/providers/hover.ts +++ b/server/src/providers/hover.ts @@ -21,7 +21,13 @@ import { urlMapAttribute, } from "../utils/functions"; import { ServerSpec, QueryData, CommandDoc, KeywordDoc } from "../utils/types"; -import { documents, corePropertyParams, mppContinue } from "../utils/variables"; +import { + documents, + corePropertyParams, + mppContinue, + getAnalyzedClass, + getAnalyzedClassMember, +} from "../utils/variables"; import * as ld from "../utils/languageDefinitions"; import commands from "../documentation/commands.json"; @@ -43,6 +49,7 @@ import queryKeywords from "../documentation/keywords/Query.json"; import storageKeywords from "../documentation/keywords/Storage.json"; import triggerKeywords from "../documentation/keywords/Trigger.json"; import xdataKeywords from "../documentation/keywords/XData.json"; +import { Arg, MemberInfo } from "../analyzer"; function documaticLink(server: ServerSpec, cls: string): string { return `[${cls}](${server.scheme}://${server.host}:${server.port}${server.pathPrefix}/csp/documatic/%25CSP.Documatic.cls?LIBRARY=${encodeURIComponent( @@ -54,6 +61,7 @@ function markupValue(header: string, body?: string): string { return body?.trim().length ? [header, "***", body].join("\n") : header; } +export const localInfoPrefix = `[📁] `; export async function onHover(params: TextDocumentPositionParams): Promise { const doc = documents.get(params.textDocument.uri); if (doc === undefined) { @@ -114,6 +122,20 @@ export async function onHover(params: TextDocumentPositionParams): Promise**${memberInfo.name.text}**`; + const { kind } = memberInfo; + if (kind.tag === "classMethod" || kind.tag === "clientMethod" || kind.tag === "method") { + const { args, out } = kind.value; + const argList = args.map(prettifyArg).join(", "); + content += `(${argList})`; + if (out) { + content += ` As ${out}`; + } + } else if (kind.tag === "property" || kind.tag === "relationship") { + if (kind.value) { + content += ` As ${kind.value}`; + } + } else if (kind.tag === "parameter") { + const value = kind.value; + if (value.t) { + content += ` As ${value.t}`; + } + if (value.v) { + content += ` = ${value.v}`; + } + } + return content; +} + +function hoverBodyFromMemberInfo(memberInfo: MemberInfo): string { + let content = ""; + content += memberInfo.doc; + return documaticHtmlToMarkdown(content); +} + +export const prettifyArg = (arg: Arg): string => { + let string = ""; + if (arg.byRef) { + string += "&"; + } + string += arg.name.text; + if (arg.variadic) { + string += "..."; + } + if (arg.t) { + string += ` As ${arg.t}`; + } + return string; +}; diff --git a/server/src/providers/signatureHelp.ts b/server/src/providers/signatureHelp.ts index 6670418..24239ed 100644 --- a/server/src/providers/signatureHelp.ts +++ b/server/src/providers/signatureHelp.ts @@ -23,8 +23,9 @@ import { determineActiveParam, } from "../utils/functions"; import { ServerSpec, SignatureHelpDocCache, SignatureHelpMacroContext } from "../utils/types"; -import { documents } from "../utils/variables"; +import { documents, getAnalyzedClassMember } from "../utils/variables"; import * as ld from "../utils/languageDefinitions"; +import { prettifyArg } from "./hover"; /** * Cache of the macro context info required to do a macro expansion when the selected parameter changes. @@ -362,6 +363,20 @@ export async function onSignatureHelp(params: SignatureHelpParams): Promise ({ + label: arg.name.text, + }), + ), + }; + if (showingDoc) { + signatureHelpDocumentationCache = { + type: "method", + doc: { + kind: MarkupKind.Markdown, + value: documaticHtmlToMarkdown(mem.doc), + }, + }; + sig.documentation = signatureHelpDocumentationCache.doc; + } + return { + signatures: [sig], + activeSignature: 0, + }; + } +} diff --git a/server/src/server.ts b/server/src/server.ts index 2e11a0e..fb3a023 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -1,4 +1,9 @@ -import { DidChangeConfigurationNotification, TextDocumentSyncKind, CodeActionKind } from "vscode-languageserver/node"; +import { + DidChangeConfigurationNotification, + TextDocumentSyncKind, + CodeActionKind, + WorkspaceFolder, +} from "vscode-languageserver/node"; import { URI } from "vscode-uri"; import { onPrepare, onSubtypes, onSupertypes } from "./providers/typeHierarchy"; @@ -25,11 +30,12 @@ import { onHover } from "./providers/hover"; import { onCompletion, onCompletionResolve, schemaCaches } from "./providers/completion"; import { onSignatureHelp } from "./providers/signatureHelp"; import { onDocumentFormatting, onDocumentRangeFormatting } from "./providers/formatting"; -import { onDiagnostics } from "./providers/diagnostic"; +import { onDiagnostics, onWorkspaceDiagnostics } from "./providers/diagnostic"; import { onSemanticTokens, onSemanticTokensDelta } from "./providers/semanticTokens"; import { LanguageServerConfiguration, ServerSpec } from "./utils/types"; import { + analyzedDocuments, connection, documents, languageServerSettings, @@ -39,8 +45,10 @@ import { } from "./utils/variables"; import { parseDocument, getLegend } from "./parse/parse"; import { isolateEmbeddedLanguage, languageAtPosition } from "./providers/requestForwarding"; +import { analyzeCls } from "./analyzer"; -connection.onInitialize(() => { +connection.onInitialize((params) => { + analyzeWorkspaceFolders(params.workspaceFolders ?? []); return { capabilities: { textDocumentSync: TextDocumentSyncKind.Full, @@ -79,7 +87,7 @@ connection.onInitialize(() => { typeHierarchyProvider: true, diagnosticProvider: { interFileDependencies: false, - workspaceDiagnostics: false, + workspaceDiagnostics: true, }, }, }; @@ -129,15 +137,16 @@ documents.onDidClose((e) => { documents.onDidChangeContent(async (change) => { // Clear the parsedDocuments value so we know to wait for an update elsewhere parsedDocuments.set(change.document.uri, undefined); + analyzedDocuments.set(change.document.uri, undefined); const path = URI.parse(change.document.uri).path; + const fsPath = URI.parse(change.document.uri).fsPath; + const fileText = change.document.getText(); parsedDocuments.set( change.document.uri, - parseDocument( - change.document.languageId, - path.slice(path.lastIndexOf(".") + 1).toLowerCase(), - change.document.getText(), - ).compressedlinearray, + parseDocument(change.document.languageId, path.slice(path.lastIndexOf(".") + 1).toLowerCase(), fileText) + .compressedlinearray, ); + analyzedDocuments.set(change.document.uri, await analyzeCls(fsPath, fileText)); }); connection.onDocumentFormatting(onDocumentFormatting); @@ -234,6 +243,30 @@ connection.onRequest("intersystems/embedded/isolateEmbeddedLanguage", isolateEmb connection.languages.diagnostics.on(onDiagnostics); +connection.languages.diagnostics.onWorkspace(onWorkspaceDiagnostics); + documents.listen(connection); connection.listen(); + +import * as fs from "fs"; +import * as path from "path"; + +async function analyzeWorkspaceFolders(folders: WorkspaceFolder[]) { + for (const folder of folders) { + const folderURI = URI.parse(folder.uri); + if (folderURI.scheme !== "file") { + continue; + } + for (const file of fs.readdirSync(folderURI.fsPath, { recursive: true, withFileTypes: true })) { + if (!(file.isFile() && file.name.endsWith(".cls"))) { + continue; + } + const filePath = path.join(file.parentPath, file.name); + const fileURI = URI.file(filePath).toString(); + const fileString = fs.readFileSync(filePath, "utf-8"); + analyzedDocuments.set(fileURI, undefined); + analyzedDocuments.set(fileURI, await analyzeCls(filePath, fileString)); + } + } +} diff --git a/server/src/utils/functions.ts b/server/src/utils/functions.ts index a1f7e8c..d3773d6 100644 --- a/server/src/utils/functions.ts +++ b/server/src/utils/functions.ts @@ -1,4 +1,4 @@ -import { MarkupContent, MarkupKind, Position, Range } from "vscode-languageserver"; +import { Diagnostic, MarkupContent, MarkupKind, Position, Range } from "vscode-languageserver"; import { TextDocument } from "vscode-languageserver-textdocument"; import { URI } from "vscode-uri"; import { parse } from "node-html-parser"; @@ -22,6 +22,7 @@ import { languageServerSettings, documents, classMemberTypes, + analyzedDocuments, } from "./variables"; import * as ld from "./languageDefinitions"; @@ -32,6 +33,7 @@ import systemVariables from "../documentation/systemVariables.json"; // Initialize turndown and tune it for Documatic HTML import { default as TurndownService } from "turndown"; +import { ClassInfo } from "../analyzer"; const turndown = new TurndownService({ codeBlockStyle: "fenced", blankReplacement: (content, node: HTMLElement) => (node.nodeName == "SPAN" ? node.outerHTML : ""), @@ -3029,6 +3031,22 @@ export async function getParsedDocument(uri: string): Promise { + if (!analyzedDocuments.has(uri)) { + return undefined; + } + const start = Date.now(); + function wait(resolve: (value: ClassInfo | { error: Diagnostic[] }) => void) { + const result = analyzedDocuments.get(uri); + if (result != undefined || Date.now() - start >= 5000) { + resolve(result); + } else { + setTimeout(wait, 25, resolve); + } + } + return new Promise(wait); +} + /** * Check if label on `line` of `doc` is a procedure block. * diff --git a/server/src/utils/variables.ts b/server/src/utils/variables.ts index 55cd5be..b4ea39d 100644 --- a/server/src/utils/variables.ts +++ b/server/src/utils/variables.ts @@ -1,12 +1,63 @@ -import { createConnection, SemanticTokensBuilder, TextDocuments } from "vscode-languageserver/node"; +import { createConnection, Diagnostic, SemanticTokensBuilder, TextDocuments } from "vscode-languageserver/node"; import { TextDocument } from "vscode-languageserver-textdocument"; import { compressedline, LanguageServerConfiguration, ServerSpec } from "./types"; +import { ClassInfo, MemberInfo } from "../analyzer"; /** * TextDocument URI's mapped to the tokenized representation of the document. */ export const parsedDocuments: Map = new Map(); +/** + * TextDocument URI's mapped to the analyzed representation of the document. + */ +export const analyzedDocuments: Map = new Map(); + +export function getAnalyzedClass(name: string): [string, ClassInfo] | null { + for (const [uri, cls] of getAnalyzedClasses()) { + if (cls.name.text === name) { + return [uri, cls]; + } + } + return null; +} + +export function* getAnalyzedClasses(): Generator<[string, ClassInfo]> { + for (const [uri, info] of analyzedDocuments) { + if (!("error" in info)) { + yield [uri, info]; + } + } +} + +export function getAnalyzedClassMember(clsName: string, memName: string): [string, ClassInfo, MemberInfo] | null { + for (const [uri, cls, mem] of getAnalyzedClassMembers(clsName)) { + if (mem.name.text === memName) { + return [uri, cls, mem]; + } + } + return null; +} + +export function* getAnalyzedClassMembers( + clsName: string, + includeExtends: boolean = true, +): Generator<[string, ClassInfo, MemberInfo]> { + const uri_cls = getAnalyzedClass(clsName); + if (!uri_cls) { + return; + } + const [uri, cls] = uri_cls; + for (const mem of cls.members) { + yield [uri, cls, mem]; + } + if (includeExtends) { + for (const sup of cls.extends) { + yield* getAnalyzedClassMembers(sup); + } + } +} + /** * Node IPC connection between the server and client. */