From 0a4a2d44d00700e356847a6c5cbdddb47a9d47fb Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Mon, 9 Dec 2019 15:39:21 +0100 Subject: [PATCH] Add sample --- semantic-tokens-sample/.gitignore | 4 + semantic-tokens-sample/.vscode/launch.json | 35 ++ semantic-tokens-sample/.vscode/settings.json | 3 + semantic-tokens-sample/.vscode/tasks.json | 20 ++ semantic-tokens-sample/.vscodeignore | 9 + semantic-tokens-sample/README.md | 21 ++ semantic-tokens-sample/demo.png | Bin 0 -> 82722 bytes semantic-tokens-sample/package-lock.json | 323 ++++++++++++++++++ semantic-tokens-sample/package.json | 40 +++ .../sample/sample.semanticLanguage | 16 + semantic-tokens-sample/src/extension.ts | 99 ++++++ semantic-tokens-sample/tsconfig.json | 11 + semantic-tokens-sample/tslint.json | 6 + semantic-tokens-sample/vscode.proposed.d.ts | 234 +++++++++++++ 14 files changed, 821 insertions(+) create mode 100644 semantic-tokens-sample/.gitignore create mode 100644 semantic-tokens-sample/.vscode/launch.json create mode 100644 semantic-tokens-sample/.vscode/settings.json create mode 100644 semantic-tokens-sample/.vscode/tasks.json create mode 100644 semantic-tokens-sample/.vscodeignore create mode 100644 semantic-tokens-sample/README.md create mode 100644 semantic-tokens-sample/demo.png create mode 100644 semantic-tokens-sample/package-lock.json create mode 100644 semantic-tokens-sample/package.json create mode 100644 semantic-tokens-sample/sample/sample.semanticLanguage create mode 100644 semantic-tokens-sample/src/extension.ts create mode 100644 semantic-tokens-sample/tsconfig.json create mode 100644 semantic-tokens-sample/tslint.json create mode 100644 semantic-tokens-sample/vscode.proposed.d.ts diff --git a/semantic-tokens-sample/.gitignore b/semantic-tokens-sample/.gitignore new file mode 100644 index 00000000..5fe00fea --- /dev/null +++ b/semantic-tokens-sample/.gitignore @@ -0,0 +1,4 @@ +out +node_modules +.vscode-test/ +*.vsix diff --git a/semantic-tokens-sample/.vscode/launch.json b/semantic-tokens-sample/.vscode/launch.json new file mode 100644 index 00000000..527cbf4b --- /dev/null +++ b/semantic-tokens-sample/.vscode/launch.json @@ -0,0 +1,35 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [{ + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "npm: watch" + }, + { + "name": "Run Extension Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test" + ], + "outFiles": [ + "${workspaceFolder}/out/test/**/*.js" + ], + "preLaunchTask": "npm: watch" + } + ] +} diff --git a/semantic-tokens-sample/.vscode/settings.json b/semantic-tokens-sample/.vscode/settings.json new file mode 100644 index 00000000..e46111f1 --- /dev/null +++ b/semantic-tokens-sample/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.insertSpaces": false +} \ No newline at end of file diff --git a/semantic-tokens-sample/.vscode/tasks.json b/semantic-tokens-sample/.vscode/tasks.json new file mode 100644 index 00000000..241aa6d9 --- /dev/null +++ b/semantic-tokens-sample/.vscode/tasks.json @@ -0,0 +1,20 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/semantic-tokens-sample/.vscodeignore b/semantic-tokens-sample/.vscodeignore new file mode 100644 index 00000000..85571789 --- /dev/null +++ b/semantic-tokens-sample/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +.vscode-test/** +out/test/** +out/**/*.map +src/** +.gitignore +tsconfig.json +vsc-extension-quickstart.md +tslint.json \ No newline at end of file diff --git a/semantic-tokens-sample/README.md b/semantic-tokens-sample/README.md new file mode 100644 index 00000000..193858e1 --- /dev/null +++ b/semantic-tokens-sample/README.md @@ -0,0 +1,21 @@ +# Semantic tokens sample + +This is an extension sample showing a very simple semantic tokens provider. This semantic tokens provider always returns all the tokens in a file. + +![Screenshot](demo.png) + +## How to run + +Launch the extension and open the file `sample/sample.semanticLanguage` and use the following settings: + +```json +"editor.tokenColorCustomizationsExperimental": { + "*.static": { + "foreground": "#ff0000", + "fontStyle": "bold" + }, + "type": { + "foreground": "#00aa00" + } +} +``` diff --git a/semantic-tokens-sample/demo.png b/semantic-tokens-sample/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..382895294a4481a38a36223f0087533d594bb631 GIT binary patch literal 82722 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 literal 0 HcmV?d00001 diff --git a/semantic-tokens-sample/package-lock.json b/semantic-tokens-sample/package-lock.json new file mode 100644 index 00000000..5c2a593e --- /dev/null +++ b/semantic-tokens-sample/package-lock.json @@ -0,0 +1,323 @@ +{ + "name": "base-sample", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@types/node": { + "version": "10.14.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.17.tgz", + "integrity": "sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ==", + "dev": true + }, + "@types/vscode": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.33.0.tgz", + "integrity": "sha512-JSmGiValbrcG5g20jjCfKakLiuWyrcjVezj+SEAEZ4klXQktE5EtowuGlkLVqbkiBK4iY5wy/4yW8OjecuHnjQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tslint": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.19.0.tgz", + "integrity": "sha512-1LwwtBxfRJZnUvoS9c0uj8XQtAnyhWr9KlNvDIdB+oXyT+VpsOAaEhEgKi1HrZ8rq0ki/AAnbGSv4KM6/AfVZw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "typescript": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz", + "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/semantic-tokens-sample/package.json b/semantic-tokens-sample/package.json new file mode 100644 index 00000000..191b7c30 --- /dev/null +++ b/semantic-tokens-sample/package.json @@ -0,0 +1,40 @@ +{ + "name": "semantic-tokens-sample", + "displayName": "semantic-tokens-sample", + "description": "Sample showing the Semantic Tokens Provider API", + "version": "0.0.1", + "publisher": "vscode-samples", + "engines": { + "vscode": "^1.41.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "onLanguage:semanticLanguage" + ], + "enableProposedApi": true, + "main": "./out/extension.js", + "contributes": { + "languages": [ + { + "id": "semanticLanguage", + "extensions": [ + ".semanticLanguage" + ] + } + ] + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./", + "lint": "tslint -p ./", + "watch": "tsc -watch -p ./" + }, + "devDependencies": { + "@types/node": "^10.14.17", + "@types/vscode": "^1.32.0", + "tslint": "^5.16.0", + "typescript": "^3.5.1" + } +} diff --git a/semantic-tokens-sample/sample/sample.semanticLanguage b/semantic-tokens-sample/sample/sample.semanticLanguage new file mode 100644 index 00000000..1c7b1265 --- /dev/null +++ b/semantic-tokens-sample/sample/sample.semanticLanguage @@ -0,0 +1,16 @@ +Available token types: + [comment] [string] [keyword] [number] [regexp] [operator] [namespace] + [type] [struct] [class] [interface] [enum] [parameterType] [function] + [macro] [variable] [constant] [parameter] [property] [label] + +Available token modifiers: + [type.declaration] [type.documentation] [type.member] [type.static] + [type.abstract] [type.deprecated] [type.modification] [type.async] + +Some examples: + [class.static.token] [type.static.abstract] + [class.static.token] [type.static] + + [struct] + + [function.private] diff --git a/semantic-tokens-sample/src/extension.ts b/semantic-tokens-sample/src/extension.ts new file mode 100644 index 00000000..eeb387bf --- /dev/null +++ b/semantic-tokens-sample/src/extension.ts @@ -0,0 +1,99 @@ +import * as vscode from 'vscode'; + +const tokenTypes = new Map(); +const tokenModifiers = new Map(); + +const legend = (function () { + const tokenTypesLegend = [ + 'comment', 'string', 'keyword', 'number', 'regexp', 'operator', 'namespace', + 'type', 'struct', 'class', 'interface', 'enum', 'parameterType', 'function', + 'macro', 'variable', 'constant', 'parameter', 'property', 'label' + ]; + tokenTypesLegend.forEach((tokenType, index) => tokenTypes.set(tokenType, index)); + + const tokenModifiersLegend = [ + 'declaration', 'documentation', 'member', 'static', 'abstract', 'deprecated', + 'modification', 'async' + ]; + tokenModifiersLegend.forEach((tokenModifier, index) => tokenModifiers.set(tokenModifier, index)); + + return new vscode.SemanticTokensLegend(tokenTypesLegend, tokenModifiersLegend); +})(); + +export function activate(context: vscode.ExtensionContext) { + context.subscriptions.push(vscode.languages.registerSemanticTokensProvider({ language: 'semanticLanguage'}, new SemanticTokensProvider(), legend)); +} + +interface IParsedToken { + line: number; + startCharacter: number; + length: number; + tokenType: string; + tokenModifiers: string[]; +} + +class SemanticTokensProvider implements vscode.SemanticTokensProvider { + async provideSemanticTokens(document: vscode.TextDocument, options: vscode.SemanticTokensRequestOptions, token: vscode.CancellationToken): Promise { + const allTokens = this._parseText(document.getText()); + const builder = new vscode.SemanticTokensBuilder(); + allTokens.forEach((token) => { + builder.push(token.line, token.startCharacter, token.length, this._encodeTokenType(token.tokenType), this._encodeTokenModifiers(token.tokenModifiers)); + }); + return new vscode.SemanticTokens(builder.build()); + } + + private _encodeTokenType(tokenType: string): number { + if (!tokenTypes.has(tokenType)) { + return 0; + } + return tokenTypes.get(tokenType)!; + } + + private _encodeTokenModifiers(strTokenModifiers: string[]): number { + let result = 0; + for (let i = 0; i < strTokenModifiers.length; i++) { + const tokenModifier = strTokenModifiers[i]; + if (tokenModifiers.has(tokenModifier)) { + result = result | (1 << tokenModifiers.get(tokenModifier)!); + } + } + return result; + } + + private _parseText(text: string): IParsedToken[] { + let r: IParsedToken[] = []; + let lines = text.split(/\r\n|\r|\n/); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + let currentOffset = 0; + do { + const openOffset = line.indexOf('[', currentOffset); + if (openOffset === -1) { + break; + } + const closeOffset = line.indexOf(']', openOffset); + if (closeOffset === -1) { + break; + } + let tokenData = this._parseTextToken(line.substring(openOffset + 1, closeOffset)); + r.push({ + line: i, + startCharacter: openOffset + 1, + length: closeOffset - openOffset - 1, + tokenType: tokenData.tokenType, + tokenModifiers: tokenData.tokenModifiers + }); + currentOffset = closeOffset; + } while (true); + } + return r; + } + + private _parseTextToken(text: string): { tokenType: string; tokenModifiers: string[]; } { + let parts = text.split('.'); + return { + tokenType: parts[0], + tokenModifiers: parts.slice(1) + }; + } +} diff --git a/semantic-tokens-sample/tsconfig.json b/semantic-tokens-sample/tsconfig.json new file mode 100644 index 00000000..aa034c3f --- /dev/null +++ b/semantic-tokens-sample/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "sourceMap": true, + "rootDir": "src", + "strict": true + }, + "exclude": ["node_modules", ".vscode-test"] +} diff --git a/semantic-tokens-sample/tslint.json b/semantic-tokens-sample/tslint.json new file mode 100644 index 00000000..0ab0ca6e --- /dev/null +++ b/semantic-tokens-sample/tslint.json @@ -0,0 +1,6 @@ +{ + "rules": { + "indent": [true, "tabs"], + "semicolon": [true, "always"] + } +} \ No newline at end of file diff --git a/semantic-tokens-sample/vscode.proposed.d.ts b/semantic-tokens-sample/vscode.proposed.d.ts new file mode 100644 index 00000000..29bcbbda --- /dev/null +++ b/semantic-tokens-sample/vscode.proposed.d.ts @@ -0,0 +1,234 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * This is the place for API experiments and proposals. + * These API are NOT stable and subject to change. They are only available in the Insiders + * distribution and CANNOT be used in published extensions. + * + * To test these API in local environment: + * - Use Insiders release of VS Code. + * - Add `"enableProposedApi": true` to your package.json. + * - Copy this file to your project. + */ + +declare module 'vscode' { + + //#region Semantic tokens: https://github.com/microsoft/vscode/issues/86415 + + export class SemanticTokensLegend { + public readonly tokenTypes: string[]; + public readonly tokenModifiers: string[]; + + constructor(tokenTypes: string[], tokenModifiers: string[]); + } + + export class SemanticTokensBuilder { + constructor(); + push(line: number, char: number, length: number, tokenType: number, tokenModifiers: number): void; + build(): Uint32Array; + } + + export class SemanticTokens { + /** + * The result id of the tokens. + * + * On a next call to `provideSemanticTokens`, if VS Code still holds in memory this result, + * the result id will be passed in as `SemanticTokensRequestOptions.previousResultId`. + */ + readonly resultId?: string; + readonly data: Uint32Array; + + constructor(data: Uint32Array, resultId?: string); + } + + export class SemanticTokensEdits { + /** + * The result id of the tokens. + * + * On a next call to `provideSemanticTokens`, if VS Code still holds in memory this result, + * the result id will be passed in as `SemanticTokensRequestOptions.previousResultId`. + */ + readonly resultId?: string; + readonly edits: SemanticTokensEdit[]; + + constructor(edits: SemanticTokensEdit[], resultId?: string); + } + + export class SemanticTokensEdit { + readonly start: number; + readonly deleteCount: number; + readonly data?: Uint32Array; + + constructor(start: number, deleteCount: number, data?: Uint32Array); + } + + export interface SemanticTokensRequestOptions { + readonly ranges?: readonly Range[]; + /** + * The previous result id that the editor still holds in memory. + * + * Only when this is set it is safe for a `SemanticTokensProvider` to return `SemanticTokensEdits`. + */ + readonly previousResultId?: string; + } + + /** + * The semantic tokens provider interface defines the contract between extensions and + * semantic tokens. + */ + export interface SemanticTokensProvider { + /** + * A file can contain many tokens, perhaps even hundreds of thousands of tokens. Therefore, to improve + * the memory consumption around describing semantic tokens, we have decided to avoid allocating an object + * for each token and we represent tokens from a file as an array of integers. Furthermore, the position + * of each token is expressed relative to the token before it because most tokens remain stable relative to + * each other when edits are made in a file. + * + * + * --- + * In short, each token takes 5 integers to represent, so a specific token `i` in the file consists of the following fields: + * - at index `5*i` - `deltaLine`: token line number, relative to the previous token + * - at index `5*i+1` - `deltaStart`: token start character, relative to the previous token (relative to 0 or the previous token's start if they are on the same line) + * - at index `5*i+2` - `length`: the length of the token. A token cannot be multiline. + * - at index `5*i+3` - `tokenType`: will be looked up in `SemanticTokensLegend.tokenTypes` + * - at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` + * + * + * + * --- + * ### How to encode tokens + * + * Here is an example for encoding a file with 3 tokens: + * ``` + * { line: 2, startChar: 5, length: 3, tokenType: "properties", tokenModifiers: ["private", "static"] }, + * { line: 2, startChar: 10, length: 4, tokenType: "types", tokenModifiers: [] }, + * { line: 5, startChar: 2, length: 7, tokenType: "classes", tokenModifiers: [] } + * ``` + * + * 1. First of all, a legend must be devised. This legend must be provided up-front and capture all possible token types. + * For this example, we will choose the following legend which must be passed in when registering the provider: + * ``` + * tokenTypes: ['properties', 'types', 'classes'], + * tokenModifiers: ['private', 'static'] + * ``` + * + * 2. The first transformation step is to encode `tokenType` and `tokenModifiers` as integers using the legend. Token types are looked + * up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Multiple token modifiers can be set by using bit flags, + * so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because + * bits 0 and 1 are set. Using this legend, the tokens now are: + * ``` + * { line: 2, startChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 }, + * { line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 }, + * { line: 5, startChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 } + * ``` + * + * 3. The next steps is to encode each token relative to the previous token in the file. In this case, the second token + * is on the same line as the first token, so the `startChar` of the second token is made relative to the `startChar` + * of the first token, so it will be `10 - 5`. The third token is on a different line than the second token, so the + * `startChar` of the third token will not be altered: + * ``` + * { deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 }, + * { deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 }, + * { deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 } + * ``` + * + * 4. Finally, the last step is to inline each of the 5 fields for a token in a single array, which is a memory friendly representation: + * ``` + * // 1st token, 2nd token, 3rd token + * [ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] + * ``` + * + * + * + * --- + * ### How tokens change when the document changes + * + * Let's look at how tokens might change. + * + * Continuing with the above example, suppose a new line was inserted at the top of the file. + * That would make all the tokens move down by one line (notice how the line has changed for each one): + * ``` + * { line: 3, startChar: 5, length: 3, tokenType: "properties", tokenModifiers: ["private", "static"] }, + * { line: 3, startChar: 10, length: 4, tokenType: "types", tokenModifiers: [] }, + * { line: 6, startChar: 2, length: 7, tokenType: "classes", tokenModifiers: [] } + * ``` + * The integer encoding of the tokens does not change substantially because of the delta-encoding of positions: + * ``` + * // 1st token, 2nd token, 3rd token + * [ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] + * ``` + * It is possible to express these new tokens in terms of an edit applied to the previous tokens: + * ``` + * [ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] + * [ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] + * + * edit: { start: 0, deleteCount: 1, data: [3] } // replace integer at offset 0 with 3 + * ``` + * + * Furthermore, let's assume that a new token has appeared on line 4: + * ``` + * { line: 3, startChar: 5, length: 3, tokenType: "properties", tokenModifiers: ["private", "static"] }, + * { line: 3, startChar: 10, length: 4, tokenType: "types", tokenModifiers: [] }, + * { line: 4, startChar: 3, length: 5, tokenType: "properties", tokenModifiers: ["static"] }, + * { line: 6, startChar: 2, length: 7, tokenType: "classes", tokenModifiers: [] } + * ``` + * The integer encoding of the tokens is: + * ``` + * // 1st token, 2nd token, 3rd token, 4th token + * [ 3,5,3,0,3, 0,5,4,1,0, 1,3,5,0,2, 2,2,7,2,0, ] + * ``` + * Again, it is possible to express these new tokens in terms of an edit applied to the previous tokens: + * ``` + * [ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] + * [ 3,5,3,0,3, 0,5,4,1,0, 1,3,5,0,2, 2,2,7,2,0, ] + * + * edit: { start: 10, deleteCount: 1, data: [1,3,5,0,2,2] } // replace integer at offset 10 with [1,3,5,0,2,2] + * ``` + * + * + * + * --- + * ### When to return `SemanticTokensEdits` + * + * When doing edits, it is possible that multiple edits occur until VS Code decides to invoke the semantic tokens provider. + * In principle, each call to `provideSemanticTokens` can return a full representations of the semantic tokens, and that would + * be a perfectly reasonable semantic tokens provider implementation. + * + * However, when having a language server running in a separate process, transferring all the tokens between processes + * might be slow, so VS Code allows to return the new tokens expressed in terms of multiple edits applied to the previous + * tokens. + * + * To clearly define what "previous tokens" means, it is possible to return a `resultId` with the semantic tokens. If the + * editor still has in memory the previous result, the editor will pass in options the previous `resultId` at + * `SemanticTokensRequestOptions.previousResultId`. Only when the editor passes in the previous `resultId`, it is allowed + * that a semantic tokens provider returns the new tokens expressed as edits to be applied to the previous result. Even in this + * case, the semantic tokens provider needs to return a new `resultId` that will identify these new tokens as a basis + * for the next request. + * + * *NOTE 1*: It is illegal to return `SemanticTokensEdits` if `options.previousResultId` is not set. + * *NOTE 2*: All edits in `SemanticTokensEdits` contain indices in the old integers array, so they all refer to the previous result state. + */ + provideSemanticTokens(document: TextDocument, options: SemanticTokensRequestOptions, token: CancellationToken): ProviderResult; + } + + export namespace languages { + /** + * Register a semantic tokens provider. + * + * Multiple providers can be registered for a language. In that case providers are sorted + * by their [score](#languages.match) and the best-matching provider is used. Failure + * of the selected provider will cause a failure of the whole operation. + * + * @param selector A selector that defines the documents this provider is applicable to. + * @param provider A semantic tokens provider. + * @return A [disposable](#Disposable) that unregisters this provider when being disposed. + */ + export function registerSemanticTokensProvider(selector: DocumentSelector, provider: SemanticTokensProvider, legend: SemanticTokensLegend): Disposable; + } + + //#endregion + +}