aboutsummaryrefslogtreecommitdiff
path: root/editors/code
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code')
-rw-r--r--editors/code/.vscodeignore3
-rw-r--r--editors/code/package-lock.json1355
-rw-r--r--editors/code/package.json246
-rw-r--r--editors/code/rollup.config.js4
-rw-r--r--editors/code/rust.tmGrammar.json686
-rw-r--r--editors/code/src/ast_inspector.ts (renamed from editors/code/src/commands/syntax_tree.ts)92
-rw-r--r--editors/code/src/cargo.ts106
-rw-r--r--editors/code/src/client.ts98
-rw-r--r--editors/code/src/color_theme.ts129
-rw-r--r--editors/code/src/commands.ts416
-rw-r--r--editors/code/src/commands/analyzer_status.ts51
-rw-r--r--editors/code/src/commands/expand_macro.ts66
-rw-r--r--editors/code/src/commands/index.ts53
-rw-r--r--editors/code/src/commands/join_lines.ts18
-rw-r--r--editors/code/src/commands/matching_brace.ts27
-rw-r--r--editors/code/src/commands/on_enter.ts34
-rw-r--r--editors/code/src/commands/parent_module.ts29
-rw-r--r--editors/code/src/commands/runnables.ts185
-rw-r--r--editors/code/src/commands/server_version.ts15
-rw-r--r--editors/code/src/commands/ssr.ts32
-rw-r--r--editors/code/src/config.ts22
-rw-r--r--editors/code/src/debug.ts147
-rw-r--r--editors/code/src/inlay_hints.ts16
-rw-r--r--editors/code/src/lsp_ext.ts86
-rw-r--r--editors/code/src/main.ts70
-rw-r--r--editors/code/src/run.ts146
-rw-r--r--editors/code/src/rust-analyzer-api.ts125
-rw-r--r--editors/code/src/snippets.ts55
-rw-r--r--editors/code/src/source_change.ts54
-rw-r--r--editors/code/src/tasks.ts7
-rw-r--r--editors/code/src/toolchain.ts174
-rw-r--r--editors/code/src/util.ts43
-rw-r--r--editors/code/tests/runTests.ts43
-rw-r--r--editors/code/tests/unit/index.ts38
-rw-r--r--editors/code/tests/unit/launch_config.test.ts52
-rw-r--r--editors/code/tsconfig.json9
36 files changed, 3408 insertions, 1324 deletions
diff --git a/editors/code/.vscodeignore b/editors/code/.vscodeignore
index ac411f8e2..7149ab799 100644
--- a/editors/code/.vscodeignore
+++ b/editors/code/.vscodeignore
@@ -1,7 +1,8 @@
1** 1**
2!out/main.js 2!out/src/main.js
3!package.json 3!package.json
4!package-lock.json 4!package-lock.json
5!ra_syntax_tree.tmGrammar.json 5!ra_syntax_tree.tmGrammar.json
6!rust.tmGrammar.json
6!icon.png 7!icon.png
7!README.md 8!README.md
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 55ba5351d..3b4a31682 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -13,21 +13,27 @@
13 "@babel/highlight": "^7.8.3" 13 "@babel/highlight": "^7.8.3"
14 } 14 }
15 }, 15 },
16 "@babel/helper-validator-identifier": {
17 "version": "7.9.5",
18 "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
19 "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
20 "dev": true
21 },
16 "@babel/highlight": { 22 "@babel/highlight": {
17 "version": "7.8.3", 23 "version": "7.9.0",
18 "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", 24 "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
19 "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", 25 "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
20 "dev": true, 26 "dev": true,
21 "requires": { 27 "requires": {
28 "@babel/helper-validator-identifier": "^7.9.0",
22 "chalk": "^2.0.0", 29 "chalk": "^2.0.0",
23 "esutils": "^2.0.2",
24 "js-tokens": "^4.0.0" 30 "js-tokens": "^4.0.0"
25 } 31 }
26 }, 32 },
27 "@rollup/plugin-commonjs": { 33 "@rollup/plugin-commonjs": {
28 "version": "11.1.0", 34 "version": "12.0.0",
29 "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz", 35 "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-12.0.0.tgz",
30 "integrity": "sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA==", 36 "integrity": "sha512-8+mDQt1QUmN+4Y9D3yCG8AJNewuTSLYPJVzKKUZ+lGeQrI+bV12Tc5HCyt2WdlnG6ihIL/DPbKRJlB40DX40mw==",
31 "dev": true, 37 "dev": true,
32 "requires": { 38 "requires": {
33 "@rollup/pluginutils": "^3.0.8", 39 "@rollup/pluginutils": "^3.0.8",
@@ -40,27 +46,29 @@
40 } 46 }
41 }, 47 },
42 "@rollup/plugin-node-resolve": { 48 "@rollup/plugin-node-resolve": {
43 "version": "7.1.3", 49 "version": "8.0.0",
44 "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", 50 "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.0.0.tgz",
45 "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", 51 "integrity": "sha512-5poJCChrkVggXXND/sQ7yNqwjUNT4fP31gpRWCnSNnlXuUXTCMHT33xZrTGxgjm5Rl18MHj7iEzlCT8rYWwQSA==",
46 "dev": true, 52 "dev": true,
47 "requires": { 53 "requires": {
48 "@rollup/pluginutils": "^3.0.8", 54 "@rollup/pluginutils": "^3.0.8",
49 "@types/resolve": "0.0.8", 55 "@types/resolve": "0.0.8",
50 "builtin-modules": "^3.1.0", 56 "builtin-modules": "^3.1.0",
57 "deep-freeze": "^0.0.1",
58 "deepmerge": "^4.2.2",
51 "is-module": "^1.0.0", 59 "is-module": "^1.0.0",
52 "resolve": "^1.14.2" 60 "resolve": "^1.14.2"
53 } 61 }
54 }, 62 },
55 "@rollup/pluginutils": { 63 "@rollup/pluginutils": {
56 "version": "3.0.9", 64 "version": "3.0.10",
57 "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.9.tgz", 65 "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.10.tgz",
58 "integrity": "sha512-TLZavlfPAZYI7v33wQh4mTP6zojne14yok3DNSLcjoG/Hirxfkonn6icP5rrNWRn8nZsirJBFFpijVOJzkUHDg==", 66 "integrity": "sha512-d44M7t+PjmMrASHbhgpSbVgtL6EFyX7J4mYxwQ/c5eoaE6N2VgCgEcWVzNnwycIloti+/MpwFr8qfw+nRw00sw==",
59 "dev": true, 67 "dev": true,
60 "requires": { 68 "requires": {
61 "@types/estree": "0.0.39", 69 "@types/estree": "0.0.39",
62 "estree-walker": "^1.0.1", 70 "estree-walker": "^1.0.1",
63 "micromatch": "^4.0.2" 71 "picomatch": "^2.2.2"
64 } 72 }
65 }, 73 },
66 "@types/color-name": { 74 "@types/color-name": {
@@ -81,22 +89,51 @@
81 "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 89 "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
82 "dev": true 90 "dev": true
83 }, 91 },
92 "@types/events": {
93 "version": "3.0.0",
94 "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
95 "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
96 "dev": true
97 },
98 "@types/glob": {
99 "version": "7.1.1",
100 "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
101 "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
102 "dev": true,
103 "requires": {
104 "@types/events": "*",
105 "@types/minimatch": "*",
106 "@types/node": "*"
107 }
108 },
84 "@types/json-schema": { 109 "@types/json-schema": {
85 "version": "7.0.4", 110 "version": "7.0.4",
86 "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", 111 "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
87 "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", 112 "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
88 "dev": true 113 "dev": true
89 }, 114 },
115 "@types/minimatch": {
116 "version": "3.0.3",
117 "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
118 "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
119 "dev": true
120 },
121 "@types/mocha": {
122 "version": "7.0.2",
123 "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz",
124 "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==",
125 "dev": true
126 },
90 "@types/node": { 127 "@types/node": {
91 "version": "12.12.37", 128 "version": "14.0.5",
92 "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz", 129 "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
93 "integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg==", 130 "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
94 "dev": true 131 "dev": true
95 }, 132 },
96 "@types/node-fetch": { 133 "@types/node-fetch": {
97 "version": "2.5.6", 134 "version": "2.5.7",
98 "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.6.tgz", 135 "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz",
99 "integrity": "sha512-2w0NTwMWF1d3NJMK0Uiq2UNN8htVCyOWOD0jIPjPgC5Ph/YP4dVhs9YxxcMcuLuwAslz0dVEcZQUaqkLs3IzOQ==", 136 "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==",
100 "dev": true, 137 "dev": true,
101 "requires": { 138 "requires": {
102 "@types/node": "*", 139 "@types/node": "*",
@@ -113,62 +150,60 @@
113 } 150 }
114 }, 151 },
115 "@types/vscode": { 152 "@types/vscode": {
116 "version": "1.44.0", 153 "version": "1.45.0",
117 "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.44.0.tgz", 154 "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.45.0.tgz",
118 "integrity": "sha512-WJZtZlinE3meRdH+I7wTsIhpz/GLhqEQwmPGeh4s1irWLwMzCeTV8WZ+pgPTwrDXoafVUWwo1LiZ9HJVHFlJSQ==", 155 "integrity": "sha512-b0Gyir7sPBCqiKLygAhn/AYVfzWD+SMPkWltBrIuPEyTOxSU1wVApWY/FcxYO2EWTRacoubTl4+gvZf86RkecA==",
119 "dev": true 156 "dev": true
120 }, 157 },
121 "@typescript-eslint/eslint-plugin": { 158 "@typescript-eslint/eslint-plugin": {
122 "version": "2.29.0", 159 "version": "3.0.0",
123 "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.29.0.tgz", 160 "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.0.0.tgz",
124 "integrity": "sha512-X/YAY7azKirENm4QRpT7OVmzok02cSkqeIcLmdz6gXUQG4Hk0Fi9oBAynSAyNXeGdMRuZvjBa0c1Lu0dn/u6VA==", 161 "integrity": "sha512-lcZ0M6jD4cqGccYOERKdMtg+VWpoq3NSnWVxpc/AwAy0zhkUYVioOUZmfNqiNH8/eBNGhCn6HXd6mKIGRgNc1Q==",
125 "dev": true, 162 "dev": true,
126 "requires": { 163 "requires": {
127 "@typescript-eslint/experimental-utils": "2.29.0", 164 "@typescript-eslint/experimental-utils": "3.0.0",
128 "functional-red-black-tree": "^1.0.1", 165 "functional-red-black-tree": "^1.0.1",
129 "regexpp": "^3.0.0", 166 "regexpp": "^3.0.0",
167 "semver": "^7.3.2",
130 "tsutils": "^3.17.1" 168 "tsutils": "^3.17.1"
169 },
170 "dependencies": {
171 "semver": {
172 "version": "7.3.2",
173 "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
174 "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
175 "dev": true
176 }
131 } 177 }
132 }, 178 },
133 "@typescript-eslint/experimental-utils": { 179 "@typescript-eslint/experimental-utils": {
134 "version": "2.29.0", 180 "version": "3.0.0",
135 "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.29.0.tgz", 181 "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.0.0.tgz",
136 "integrity": "sha512-H/6VJr6eWYstyqjWXBP2Nn1hQJyvJoFdDtsHxGiD+lEP7piGnGpb/ZQd+z1ZSB1F7dN+WsxUDh8+S4LwI+f3jw==", 182 "integrity": "sha512-BN0vmr9N79M9s2ctITtChRuP1+Dls0x/wlg0RXW1yQ7WJKPurg6X3Xirv61J2sjPif4F8SLsFMs5Nzte0WYoTQ==",
137 "dev": true, 183 "dev": true,
138 "requires": { 184 "requires": {
139 "@types/json-schema": "^7.0.3", 185 "@types/json-schema": "^7.0.3",
140 "@typescript-eslint/typescript-estree": "2.29.0", 186 "@typescript-eslint/typescript-estree": "3.0.0",
141 "eslint-scope": "^5.0.0", 187 "eslint-scope": "^5.0.0",
142 "eslint-utils": "^2.0.0" 188 "eslint-utils": "^2.0.0"
143 },
144 "dependencies": {
145 "eslint-utils": {
146 "version": "2.0.0",
147 "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
148 "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
149 "dev": true,
150 "requires": {
151 "eslint-visitor-keys": "^1.1.0"
152 }
153 }
154 } 189 }
155 }, 190 },
156 "@typescript-eslint/parser": { 191 "@typescript-eslint/parser": {
157 "version": "2.29.0", 192 "version": "3.0.0",
158 "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.29.0.tgz", 193 "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.0.0.tgz",
159 "integrity": "sha512-H78M+jcu5Tf6m/5N8iiFblUUv+HJDguMSdFfzwa6vSg9lKR8Mk9BsgeSjO8l2EshKnJKcbv0e8IDDOvSNjl0EA==", 194 "integrity": "sha512-8RRCA9KLxoFNO0mQlrLZA0reGPd/MsobxZS/yPFj+0/XgMdS8+mO8mF3BDj2ZYQj03rkayhSJtF1HAohQ3iylw==",
160 "dev": true, 195 "dev": true,
161 "requires": { 196 "requires": {
162 "@types/eslint-visitor-keys": "^1.0.0", 197 "@types/eslint-visitor-keys": "^1.0.0",
163 "@typescript-eslint/experimental-utils": "2.29.0", 198 "@typescript-eslint/experimental-utils": "3.0.0",
164 "@typescript-eslint/typescript-estree": "2.29.0", 199 "@typescript-eslint/typescript-estree": "3.0.0",
165 "eslint-visitor-keys": "^1.1.0" 200 "eslint-visitor-keys": "^1.1.0"
166 } 201 }
167 }, 202 },
168 "@typescript-eslint/typescript-estree": { 203 "@typescript-eslint/typescript-estree": {
169 "version": "2.29.0", 204 "version": "3.0.0",
170 "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.29.0.tgz", 205 "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.0.0.tgz",
171 "integrity": "sha512-3YGbtnWy4az16Egy5Fj5CckkVlpIh0MADtAQza+jiMADRSKkjdpzZp/5WuvwK/Qib3Z0HtzrDFeWanS99dNhnA==", 206 "integrity": "sha512-nevQvHyNghsfLrrByzVIH4ZG3NROgJ8LZlfh3ddwPPH4CH7W4GAiSx5qu+xHuX5pWsq6q/eqMc1io840ZhAnUg==",
172 "dev": true, 207 "dev": true,
173 "requires": { 208 "requires": {
174 "debug": "^4.1.1", 209 "debug": "^4.1.1",
@@ -176,14 +211,22 @@
176 "glob": "^7.1.6", 211 "glob": "^7.1.6",
177 "is-glob": "^4.0.1", 212 "is-glob": "^4.0.1",
178 "lodash": "^4.17.15", 213 "lodash": "^4.17.15",
179 "semver": "^6.3.0", 214 "semver": "^7.3.2",
180 "tsutils": "^3.17.1" 215 "tsutils": "^3.17.1"
216 },
217 "dependencies": {
218 "semver": {
219 "version": "7.3.2",
220 "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
221 "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
222 "dev": true
223 }
181 } 224 }
182 }, 225 },
183 "acorn": { 226 "acorn": {
184 "version": "7.1.1", 227 "version": "7.2.0",
185 "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", 228 "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
186 "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", 229 "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
187 "dev": true 230 "dev": true
188 }, 231 },
189 "acorn-jsx": { 232 "acorn-jsx": {
@@ -192,10 +235,19 @@
192 "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", 235 "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
193 "dev": true 236 "dev": true
194 }, 237 },
238 "agent-base": {
239 "version": "4.3.0",
240 "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
241 "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
242 "dev": true,
243 "requires": {
244 "es6-promisify": "^5.0.0"
245 }
246 },
195 "ajv": { 247 "ajv": {
196 "version": "6.12.0", 248 "version": "6.12.2",
197 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", 249 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
198 "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", 250 "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
199 "dev": true, 251 "dev": true,
200 "requires": { 252 "requires": {
201 "fast-deep-equal": "^3.1.1", 253 "fast-deep-equal": "^3.1.1",
@@ -204,6 +256,12 @@
204 "uri-js": "^4.2.2" 256 "uri-js": "^4.2.2"
205 } 257 }
206 }, 258 },
259 "ansi-colors": {
260 "version": "3.2.3",
261 "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
262 "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
263 "dev": true
264 },
207 "ansi-escapes": { 265 "ansi-escapes": {
208 "version": "4.3.1", 266 "version": "4.3.1",
209 "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", 267 "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
@@ -236,6 +294,16 @@
236 "color-convert": "^1.9.0" 294 "color-convert": "^1.9.0"
237 } 295 }
238 }, 296 },
297 "anymatch": {
298 "version": "3.1.1",
299 "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
300 "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
301 "dev": true,
302 "requires": {
303 "normalize-path": "^3.0.0",
304 "picomatch": "^2.0.4"
305 }
306 },
239 "argparse": { 307 "argparse": {
240 "version": "1.0.10", 308 "version": "1.0.10",
241 "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 309 "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -275,6 +343,12 @@
275 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 343 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
276 "dev": true 344 "dev": true
277 }, 345 },
346 "binary-extensions": {
347 "version": "2.0.0",
348 "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
349 "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
350 "dev": true
351 },
278 "boolbase": { 352 "boolbase": {
279 "version": "1.0.0", 353 "version": "1.0.0",
280 "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 354 "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -300,6 +374,12 @@
300 "fill-range": "^7.0.1" 374 "fill-range": "^7.0.1"
301 } 375 }
302 }, 376 },
377 "browser-stdout": {
378 "version": "1.3.1",
379 "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
380 "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
381 "dev": true
382 },
303 "buffer-crc32": { 383 "buffer-crc32": {
304 "version": "0.2.13", 384 "version": "0.2.13",
305 "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 385 "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@@ -318,6 +398,12 @@
318 "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 398 "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
319 "dev": true 399 "dev": true
320 }, 400 },
401 "camelcase": {
402 "version": "5.3.1",
403 "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
404 "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
405 "dev": true
406 },
321 "chalk": { 407 "chalk": {
322 "version": "2.4.2", 408 "version": "2.4.2",
323 "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 409 "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -349,6 +435,22 @@
349 "parse5": "^3.0.1" 435 "parse5": "^3.0.1"
350 } 436 }
351 }, 437 },
438 "chokidar": {
439 "version": "3.3.0",
440 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
441 "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
442 "dev": true,
443 "requires": {
444 "anymatch": "~3.1.1",
445 "braces": "~3.0.2",
446 "fsevents": "~2.1.1",
447 "glob-parent": "~5.1.0",
448 "is-binary-path": "~2.1.0",
449 "is-glob": "~4.0.1",
450 "normalize-path": "~3.0.0",
451 "readdirp": "~3.2.0"
452 }
453 },
352 "cli-cursor": { 454 "cli-cursor": {
353 "version": "3.1.0", 455 "version": "3.1.0",
354 "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 456 "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -359,11 +461,62 @@
359 } 461 }
360 }, 462 },
361 "cli-width": { 463 "cli-width": {
362 "version": "2.2.0", 464 "version": "2.2.1",
363 "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 465 "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
364 "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 466 "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
365 "dev": true 467 "dev": true
366 }, 468 },
469 "cliui": {
470 "version": "5.0.0",
471 "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
472 "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
473 "dev": true,
474 "requires": {
475 "string-width": "^3.1.0",
476 "strip-ansi": "^5.2.0",
477 "wrap-ansi": "^5.1.0"
478 },
479 "dependencies": {
480 "ansi-regex": {
481 "version": "4.1.0",
482 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
483 "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
484 "dev": true
485 },
486 "emoji-regex": {
487 "version": "7.0.3",
488 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
489 "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
490 "dev": true
491 },
492 "is-fullwidth-code-point": {
493 "version": "2.0.0",
494 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
495 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
496 "dev": true
497 },
498 "string-width": {
499 "version": "3.1.0",
500 "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
501 "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
502 "dev": true,
503 "requires": {
504 "emoji-regex": "^7.0.1",
505 "is-fullwidth-code-point": "^2.0.0",
506 "strip-ansi": "^5.1.0"
507 }
508 },
509 "strip-ansi": {
510 "version": "5.2.0",
511 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
512 "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
513 "dev": true,
514 "requires": {
515 "ansi-regex": "^4.1.0"
516 }
517 }
518 }
519 },
367 "color-convert": { 520 "color-convert": {
368 "version": "1.9.3", 521 "version": "1.9.3",
369 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 522 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -413,24 +566,14 @@
413 "dev": true 566 "dev": true
414 }, 567 },
415 "cross-spawn": { 568 "cross-spawn": {
416 "version": "6.0.5", 569 "version": "7.0.2",
417 "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 570 "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
418 "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 571 "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
419 "dev": true, 572 "dev": true,
420 "requires": { 573 "requires": {
421 "nice-try": "^1.0.4", 574 "path-key": "^3.1.0",
422 "path-key": "^2.0.1", 575 "shebang-command": "^2.0.0",
423 "semver": "^5.5.0", 576 "which": "^2.0.1"
424 "shebang-command": "^1.2.0",
425 "which": "^1.2.9"
426 },
427 "dependencies": {
428 "semver": {
429 "version": "5.7.1",
430 "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
431 "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
432 "dev": true
433 }
434 } 577 }
435 }, 578 },
436 "css-select": { 579 "css-select": {
@@ -460,12 +603,39 @@
460 "ms": "^2.1.1" 603 "ms": "^2.1.1"
461 } 604 }
462 }, 605 },
606 "decamelize": {
607 "version": "1.2.0",
608 "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
609 "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
610 "dev": true
611 },
612 "deep-freeze": {
613 "version": "0.0.1",
614 "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz",
615 "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=",
616 "dev": true
617 },
463 "deep-is": { 618 "deep-is": {
464 "version": "0.1.3", 619 "version": "0.1.3",
465 "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 620 "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
466 "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 621 "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
467 "dev": true 622 "dev": true
468 }, 623 },
624 "deepmerge": {
625 "version": "4.2.2",
626 "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
627 "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
628 "dev": true
629 },
630 "define-properties": {
631 "version": "1.1.3",
632 "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
633 "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
634 "dev": true,
635 "requires": {
636 "object-keys": "^1.0.12"
637 }
638 },
469 "delayed-stream": { 639 "delayed-stream": {
470 "version": "1.0.0", 640 "version": "1.0.0",
471 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 641 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -478,6 +648,12 @@
478 "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", 648 "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=",
479 "dev": true 649 "dev": true
480 }, 650 },
651 "diff": {
652 "version": "3.5.0",
653 "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
654 "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
655 "dev": true
656 },
481 "doctrine": { 657 "doctrine": {
482 "version": "3.0.0", 658 "version": "3.0.0",
483 "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 659 "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -554,6 +730,51 @@
554 "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", 730 "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
555 "dev": true 731 "dev": true
556 }, 732 },
733 "es-abstract": {
734 "version": "1.17.5",
735 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
736 "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
737 "dev": true,
738 "requires": {
739 "es-to-primitive": "^1.2.1",
740 "function-bind": "^1.1.1",
741 "has": "^1.0.3",
742 "has-symbols": "^1.0.1",
743 "is-callable": "^1.1.5",
744 "is-regex": "^1.0.5",
745 "object-inspect": "^1.7.0",
746 "object-keys": "^1.1.1",
747 "object.assign": "^4.1.0",
748 "string.prototype.trimleft": "^2.1.1",
749 "string.prototype.trimright": "^2.1.1"
750 }
751 },
752 "es-to-primitive": {
753 "version": "1.2.1",
754 "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
755 "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
756 "dev": true,
757 "requires": {
758 "is-callable": "^1.1.4",
759 "is-date-object": "^1.0.1",
760 "is-symbol": "^1.0.2"
761 }
762 },
763 "es6-promise": {
764 "version": "4.2.8",
765 "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
766 "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
767 "dev": true
768 },
769 "es6-promisify": {
770 "version": "5.0.0",
771 "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
772 "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
773 "dev": true,
774 "requires": {
775 "es6-promise": "^4.0.3"
776 }
777 },
557 "escape-string-regexp": { 778 "escape-string-regexp": {
558 "version": "1.0.5", 779 "version": "1.0.5",
559 "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 780 "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -561,22 +782,22 @@
561 "dev": true 782 "dev": true
562 }, 783 },
563 "eslint": { 784 "eslint": {
564 "version": "6.8.0", 785 "version": "7.1.0",
565 "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 786 "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.1.0.tgz",
566 "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 787 "integrity": "sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==",
567 "dev": true, 788 "dev": true,
568 "requires": { 789 "requires": {
569 "@babel/code-frame": "^7.0.0", 790 "@babel/code-frame": "^7.0.0",
570 "ajv": "^6.10.0", 791 "ajv": "^6.10.0",
571 "chalk": "^2.1.0", 792 "chalk": "^4.0.0",
572 "cross-spawn": "^6.0.5", 793 "cross-spawn": "^7.0.2",
573 "debug": "^4.0.1", 794 "debug": "^4.0.1",
574 "doctrine": "^3.0.0", 795 "doctrine": "^3.0.0",
575 "eslint-scope": "^5.0.0", 796 "eslint-scope": "^5.0.0",
576 "eslint-utils": "^1.4.3", 797 "eslint-utils": "^2.0.0",
577 "eslint-visitor-keys": "^1.1.0", 798 "eslint-visitor-keys": "^1.1.0",
578 "espree": "^6.1.2", 799 "espree": "^7.0.0",
579 "esquery": "^1.0.1", 800 "esquery": "^1.2.0",
580 "esutils": "^2.0.2", 801 "esutils": "^2.0.2",
581 "file-entry-cache": "^5.0.1", 802 "file-entry-cache": "^5.0.1",
582 "functional-red-black-tree": "^1.0.1", 803 "functional-red-black-tree": "^1.0.1",
@@ -589,27 +810,76 @@
589 "is-glob": "^4.0.0", 810 "is-glob": "^4.0.0",
590 "js-yaml": "^3.13.1", 811 "js-yaml": "^3.13.1",
591 "json-stable-stringify-without-jsonify": "^1.0.1", 812 "json-stable-stringify-without-jsonify": "^1.0.1",
592 "levn": "^0.3.0", 813 "levn": "^0.4.1",
593 "lodash": "^4.17.14", 814 "lodash": "^4.17.14",
594 "minimatch": "^3.0.4", 815 "minimatch": "^3.0.4",
595 "mkdirp": "^0.5.1",
596 "natural-compare": "^1.4.0", 816 "natural-compare": "^1.4.0",
597 "optionator": "^0.8.3", 817 "optionator": "^0.9.1",
598 "progress": "^2.0.0", 818 "progress": "^2.0.0",
599 "regexpp": "^2.0.1", 819 "regexpp": "^3.1.0",
600 "semver": "^6.1.2", 820 "semver": "^7.2.1",
601 "strip-ansi": "^5.2.0", 821 "strip-ansi": "^6.0.0",
602 "strip-json-comments": "^3.0.1", 822 "strip-json-comments": "^3.1.0",
603 "table": "^5.2.3", 823 "table": "^5.2.3",
604 "text-table": "^0.2.0", 824 "text-table": "^0.2.0",
605 "v8-compile-cache": "^2.0.3" 825 "v8-compile-cache": "^2.0.3"
606 }, 826 },
607 "dependencies": { 827 "dependencies": {
608 "regexpp": { 828 "ansi-styles": {
829 "version": "4.2.1",
830 "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
831 "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
832 "dev": true,
833 "requires": {
834 "@types/color-name": "^1.1.1",
835 "color-convert": "^2.0.1"
836 }
837 },
838 "chalk": {
839 "version": "4.0.0",
840 "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
841 "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
842 "dev": true,
843 "requires": {
844 "ansi-styles": "^4.1.0",
845 "supports-color": "^7.1.0"
846 }
847 },
848 "color-convert": {
609 "version": "2.0.1", 849 "version": "2.0.1",
610 "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 850 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
611 "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 851 "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
852 "dev": true,
853 "requires": {
854 "color-name": "~1.1.4"
855 }
856 },
857 "color-name": {
858 "version": "1.1.4",
859 "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
860 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
612 "dev": true 861 "dev": true
862 },
863 "has-flag": {
864 "version": "4.0.0",
865 "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
866 "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
867 "dev": true
868 },
869 "semver": {
870 "version": "7.3.2",
871 "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
872 "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
873 "dev": true
874 },
875 "supports-color": {
876 "version": "7.1.0",
877 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
878 "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
879 "dev": true,
880 "requires": {
881 "has-flag": "^4.0.0"
882 }
613 } 883 }
614 } 884 }
615 }, 885 },
@@ -624,9 +894,9 @@
624 } 894 }
625 }, 895 },
626 "eslint-utils": { 896 "eslint-utils": {
627 "version": "1.4.3", 897 "version": "2.0.0",
628 "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 898 "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
629 "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 899 "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
630 "dev": true, 900 "dev": true,
631 "requires": { 901 "requires": {
632 "eslint-visitor-keys": "^1.1.0" 902 "eslint-visitor-keys": "^1.1.0"
@@ -639,9 +909,9 @@
639 "dev": true 909 "dev": true
640 }, 910 },
641 "espree": { 911 "espree": {
642 "version": "6.2.1", 912 "version": "7.0.0",
643 "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", 913 "resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz",
644 "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", 914 "integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==",
645 "dev": true, 915 "dev": true,
646 "requires": { 916 "requires": {
647 "acorn": "^7.1.1", 917 "acorn": "^7.1.1",
@@ -656,12 +926,20 @@
656 "dev": true 926 "dev": true
657 }, 927 },
658 "esquery": { 928 "esquery": {
659 "version": "1.1.0", 929 "version": "1.3.1",
660 "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", 930 "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
661 "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", 931 "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
662 "dev": true, 932 "dev": true,
663 "requires": { 933 "requires": {
664 "estraverse": "^4.0.0" 934 "estraverse": "^5.1.0"
935 },
936 "dependencies": {
937 "estraverse": {
938 "version": "5.1.0",
939 "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
940 "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
941 "dev": true
942 }
665 } 943 }
666 }, 944 },
667 "esrecurse": { 945 "esrecurse": {
@@ -756,6 +1034,24 @@
756 "to-regex-range": "^5.0.1" 1034 "to-regex-range": "^5.0.1"
757 } 1035 }
758 }, 1036 },
1037 "find-up": {
1038 "version": "3.0.0",
1039 "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
1040 "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
1041 "dev": true,
1042 "requires": {
1043 "locate-path": "^3.0.0"
1044 }
1045 },
1046 "flat": {
1047 "version": "4.1.0",
1048 "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
1049 "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
1050 "dev": true,
1051 "requires": {
1052 "is-buffer": "~2.0.3"
1053 }
1054 },
759 "flat-cache": { 1055 "flat-cache": {
760 "version": "2.0.1", 1056 "version": "2.0.1",
761 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 1057 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
@@ -768,9 +1064,9 @@
768 } 1064 }
769 }, 1065 },
770 "flatted": { 1066 "flatted": {
771 "version": "2.0.1", 1067 "version": "2.0.2",
772 "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 1068 "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
773 "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 1069 "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
774 "dev": true 1070 "dev": true
775 }, 1071 },
776 "form-data": { 1072 "form-data": {
@@ -797,12 +1093,24 @@
797 "dev": true, 1093 "dev": true,
798 "optional": true 1094 "optional": true
799 }, 1095 },
1096 "function-bind": {
1097 "version": "1.1.1",
1098 "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1099 "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
1100 "dev": true
1101 },
800 "functional-red-black-tree": { 1102 "functional-red-black-tree": {
801 "version": "1.0.1", 1103 "version": "1.0.1",
802 "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1104 "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
803 "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 1105 "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
804 "dev": true 1106 "dev": true
805 }, 1107 },
1108 "get-caller-file": {
1109 "version": "2.0.5",
1110 "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
1111 "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
1112 "dev": true
1113 },
806 "glob": { 1114 "glob": {
807 "version": "7.1.6", 1115 "version": "7.1.6",
808 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1116 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -818,9 +1126,9 @@
818 } 1126 }
819 }, 1127 },
820 "glob-parent": { 1128 "glob-parent": {
821 "version": "5.1.0", 1129 "version": "5.1.1",
822 "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 1130 "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
823 "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 1131 "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
824 "dev": true, 1132 "dev": true,
825 "requires": { 1133 "requires": {
826 "is-glob": "^4.0.1" 1134 "is-glob": "^4.0.1"
@@ -835,12 +1143,39 @@
835 "type-fest": "^0.8.1" 1143 "type-fest": "^0.8.1"
836 } 1144 }
837 }, 1145 },
1146 "growl": {
1147 "version": "1.10.5",
1148 "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
1149 "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
1150 "dev": true
1151 },
1152 "has": {
1153 "version": "1.0.3",
1154 "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1155 "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1156 "dev": true,
1157 "requires": {
1158 "function-bind": "^1.1.1"
1159 }
1160 },
838 "has-flag": { 1161 "has-flag": {
839 "version": "3.0.0", 1162 "version": "3.0.0",
840 "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1163 "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
841 "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1164 "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
842 "dev": true 1165 "dev": true
843 }, 1166 },
1167 "has-symbols": {
1168 "version": "1.0.1",
1169 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
1170 "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
1171 "dev": true
1172 },
1173 "he": {
1174 "version": "1.2.0",
1175 "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
1176 "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
1177 "dev": true
1178 },
844 "htmlparser2": { 1179 "htmlparser2": {
845 "version": "3.10.1", 1180 "version": "3.10.1",
846 "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", 1181 "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
@@ -855,6 +1190,54 @@
855 "readable-stream": "^3.1.1" 1190 "readable-stream": "^3.1.1"
856 } 1191 }
857 }, 1192 },
1193 "http-proxy-agent": {
1194 "version": "2.1.0",
1195 "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
1196 "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
1197 "dev": true,
1198 "requires": {
1199 "agent-base": "4",
1200 "debug": "3.1.0"
1201 },
1202 "dependencies": {
1203 "debug": {
1204 "version": "3.1.0",
1205 "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
1206 "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
1207 "dev": true,
1208 "requires": {
1209 "ms": "2.0.0"
1210 }
1211 },
1212 "ms": {
1213 "version": "2.0.0",
1214 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1215 "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
1216 "dev": true
1217 }
1218 }
1219 },
1220 "https-proxy-agent": {
1221 "version": "2.2.4",
1222 "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
1223 "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
1224 "dev": true,
1225 "requires": {
1226 "agent-base": "^4.3.0",
1227 "debug": "^3.1.0"
1228 },
1229 "dependencies": {
1230 "debug": {
1231 "version": "3.2.6",
1232 "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
1233 "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
1234 "dev": true,
1235 "requires": {
1236 "ms": "^2.1.1"
1237 }
1238 }
1239 }
1240 },
858 "iconv-lite": { 1241 "iconv-lite": {
859 "version": "0.4.24", 1242 "version": "0.4.24",
860 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1243 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -964,15 +1347,6 @@
964 "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1347 "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
965 "dev": true 1348 "dev": true
966 }, 1349 },
967 "strip-ansi": {
968 "version": "6.0.0",
969 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
970 "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
971 "dev": true,
972 "requires": {
973 "ansi-regex": "^5.0.0"
974 }
975 },
976 "supports-color": { 1350 "supports-color": {
977 "version": "7.1.0", 1351 "version": "7.1.0",
978 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 1352 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
@@ -984,6 +1358,33 @@
984 } 1358 }
985 } 1359 }
986 }, 1360 },
1361 "is-binary-path": {
1362 "version": "2.1.0",
1363 "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1364 "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1365 "dev": true,
1366 "requires": {
1367 "binary-extensions": "^2.0.0"
1368 }
1369 },
1370 "is-buffer": {
1371 "version": "2.0.4",
1372 "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
1373 "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
1374 "dev": true
1375 },
1376 "is-callable": {
1377 "version": "1.1.5",
1378 "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
1379 "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
1380 "dev": true
1381 },
1382 "is-date-object": {
1383 "version": "1.0.2",
1384 "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
1385 "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
1386 "dev": true
1387 },
987 "is-extglob": { 1388 "is-extglob": {
988 "version": "2.1.1", 1389 "version": "2.1.1",
989 "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1390 "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1017,12 +1418,6 @@
1017 "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1418 "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1018 "dev": true 1419 "dev": true
1019 }, 1420 },
1020 "is-promise": {
1021 "version": "2.1.0",
1022 "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
1023 "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
1024 "dev": true
1025 },
1026 "is-reference": { 1421 "is-reference": {
1027 "version": "1.1.4", 1422 "version": "1.1.4",
1028 "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", 1423 "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
@@ -1032,6 +1427,24 @@
1032 "@types/estree": "0.0.39" 1427 "@types/estree": "0.0.39"
1033 } 1428 }
1034 }, 1429 },
1430 "is-regex": {
1431 "version": "1.0.5",
1432 "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
1433 "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
1434 "dev": true,
1435 "requires": {
1436 "has": "^1.0.3"
1437 }
1438 },
1439 "is-symbol": {
1440 "version": "1.0.3",
1441 "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
1442 "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
1443 "dev": true,
1444 "requires": {
1445 "has-symbols": "^1.0.1"
1446 }
1447 },
1035 "isexe": { 1448 "isexe": {
1036 "version": "2.0.0", 1449 "version": "2.0.0",
1037 "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1450 "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1045,9 +1458,9 @@
1045 "dev": true 1458 "dev": true
1046 }, 1459 },
1047 "js-yaml": { 1460 "js-yaml": {
1048 "version": "3.13.1", 1461 "version": "3.14.0",
1049 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1462 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
1050 "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1463 "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
1051 "dev": true, 1464 "dev": true,
1052 "requires": { 1465 "requires": {
1053 "argparse": "^1.0.7", 1466 "argparse": "^1.0.7",
@@ -1066,11 +1479,6 @@
1066 "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1479 "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
1067 "dev": true 1480 "dev": true
1068 }, 1481 },
1069 "jsonc-parser": {
1070 "version": "2.2.1",
1071 "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz",
1072 "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="
1073 },
1074 "leven": { 1482 "leven": {
1075 "version": "3.1.0", 1483 "version": "3.1.0",
1076 "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", 1484 "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -1078,13 +1486,13 @@
1078 "dev": true 1486 "dev": true
1079 }, 1487 },
1080 "levn": { 1488 "levn": {
1081 "version": "0.3.0", 1489 "version": "0.4.1",
1082 "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1490 "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
1083 "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1491 "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
1084 "dev": true, 1492 "dev": true,
1085 "requires": { 1493 "requires": {
1086 "prelude-ls": "~1.1.2", 1494 "prelude-ls": "^1.2.1",
1087 "type-check": "~0.3.2" 1495 "type-check": "~0.4.0"
1088 } 1496 }
1089 }, 1497 },
1090 "linkify-it": { 1498 "linkify-it": {
@@ -1096,12 +1504,31 @@
1096 "uc.micro": "^1.0.1" 1504 "uc.micro": "^1.0.1"
1097 } 1505 }
1098 }, 1506 },
1507 "locate-path": {
1508 "version": "3.0.0",
1509 "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
1510 "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
1511 "dev": true,
1512 "requires": {
1513 "p-locate": "^3.0.0",
1514 "path-exists": "^3.0.0"
1515 }
1516 },
1099 "lodash": { 1517 "lodash": {
1100 "version": "4.17.15", 1518 "version": "4.17.15",
1101 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1519 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
1102 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 1520 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
1103 "dev": true 1521 "dev": true
1104 }, 1522 },
1523 "log-symbols": {
1524 "version": "3.0.0",
1525 "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
1526 "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
1527 "dev": true,
1528 "requires": {
1529 "chalk": "^2.4.2"
1530 }
1531 },
1105 "lru-cache": { 1532 "lru-cache": {
1106 "version": "4.1.5", 1533 "version": "4.1.5",
1107 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 1534 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -1148,16 +1575,6 @@
1148 "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", 1575 "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
1149 "dev": true 1576 "dev": true
1150 }, 1577 },
1151 "micromatch": {
1152 "version": "4.0.2",
1153 "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
1154 "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
1155 "dev": true,
1156 "requires": {
1157 "braces": "^3.0.1",
1158 "picomatch": "^2.0.5"
1159 }
1160 },
1161 "mime": { 1578 "mime": {
1162 "version": "1.6.0", 1579 "version": "1.6.0",
1163 "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1580 "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -1165,18 +1582,18 @@
1165 "dev": true 1582 "dev": true
1166 }, 1583 },
1167 "mime-db": { 1584 "mime-db": {
1168 "version": "1.43.0", 1585 "version": "1.44.0",
1169 "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", 1586 "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
1170 "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", 1587 "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
1171 "dev": true 1588 "dev": true
1172 }, 1589 },
1173 "mime-types": { 1590 "mime-types": {
1174 "version": "2.1.26", 1591 "version": "2.1.27",
1175 "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", 1592 "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
1176 "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", 1593 "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
1177 "dev": true, 1594 "dev": true,
1178 "requires": { 1595 "requires": {
1179 "mime-db": "1.43.0" 1596 "mime-db": "1.44.0"
1180 } 1597 }
1181 }, 1598 },
1182 "mimic-fn": { 1599 "mimic-fn": {
@@ -1201,14 +1618,111 @@
1201 "dev": true 1618 "dev": true
1202 }, 1619 },
1203 "mkdirp": { 1620 "mkdirp": {
1204 "version": "0.5.3", 1621 "version": "0.5.5",
1205 "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", 1622 "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
1206 "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", 1623 "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1207 "dev": true, 1624 "dev": true,
1208 "requires": { 1625 "requires": {
1209 "minimist": "^1.2.5" 1626 "minimist": "^1.2.5"
1210 } 1627 }
1211 }, 1628 },
1629 "mocha": {
1630 "version": "7.2.0",
1631 "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz",
1632 "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==",
1633 "dev": true,
1634 "requires": {
1635 "ansi-colors": "3.2.3",
1636 "browser-stdout": "1.3.1",
1637 "chokidar": "3.3.0",
1638 "debug": "3.2.6",
1639 "diff": "3.5.0",
1640 "escape-string-regexp": "1.0.5",
1641 "find-up": "3.0.0",
1642 "glob": "7.1.3",
1643 "growl": "1.10.5",
1644 "he": "1.2.0",
1645 "js-yaml": "3.13.1",
1646 "log-symbols": "3.0.0",
1647 "minimatch": "3.0.4",
1648 "mkdirp": "0.5.5",
1649 "ms": "2.1.1",
1650 "node-environment-flags": "1.0.6",
1651 "object.assign": "4.1.0",
1652 "strip-json-comments": "2.0.1",
1653 "supports-color": "6.0.0",
1654 "which": "1.3.1",
1655 "wide-align": "1.1.3",
1656 "yargs": "13.3.2",
1657 "yargs-parser": "13.1.2",
1658 "yargs-unparser": "1.6.0"
1659 },
1660 "dependencies": {
1661 "debug": {
1662 "version": "3.2.6",
1663 "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
1664 "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
1665 "dev": true,
1666 "requires": {
1667 "ms": "^2.1.1"
1668 }
1669 },
1670 "glob": {
1671 "version": "7.1.3",
1672 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
1673 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
1674 "dev": true,
1675 "requires": {
1676 "fs.realpath": "^1.0.0",
1677 "inflight": "^1.0.4",
1678 "inherits": "2",
1679 "minimatch": "^3.0.4",
1680 "once": "^1.3.0",
1681 "path-is-absolute": "^1.0.0"
1682 }
1683 },
1684 "js-yaml": {
1685 "version": "3.13.1",
1686 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1687 "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1688 "dev": true,
1689 "requires": {
1690 "argparse": "^1.0.7",
1691 "esprima": "^4.0.0"
1692 }
1693 },
1694 "ms": {
1695 "version": "2.1.1",
1696 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1697 "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
1698 "dev": true
1699 },
1700 "strip-json-comments": {
1701 "version": "2.0.1",
1702 "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1703 "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1704 "dev": true
1705 },
1706 "supports-color": {
1707 "version": "6.0.0",
1708 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
1709 "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
1710 "dev": true,
1711 "requires": {
1712 "has-flag": "^3.0.0"
1713 }
1714 },
1715 "which": {
1716 "version": "1.3.1",
1717 "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1718 "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1719 "dev": true,
1720 "requires": {
1721 "isexe": "^2.0.0"
1722 }
1723 }
1724 }
1725 },
1212 "ms": { 1726 "ms": {
1213 "version": "2.1.2", 1727 "version": "2.1.2",
1214 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1728 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -1227,17 +1741,35 @@
1227 "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1741 "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
1228 "dev": true 1742 "dev": true
1229 }, 1743 },
1230 "nice-try": { 1744 "node-environment-flags": {
1231 "version": "1.0.5", 1745 "version": "1.0.6",
1232 "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1746 "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
1233 "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 1747 "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
1234 "dev": true 1748 "dev": true,
1749 "requires": {
1750 "object.getownpropertydescriptors": "^2.0.3",
1751 "semver": "^5.7.0"
1752 },
1753 "dependencies": {
1754 "semver": {
1755 "version": "5.7.1",
1756 "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1757 "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1758 "dev": true
1759 }
1760 }
1235 }, 1761 },
1236 "node-fetch": { 1762 "node-fetch": {
1237 "version": "2.6.0", 1763 "version": "2.6.0",
1238 "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", 1764 "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
1239 "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" 1765 "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
1240 }, 1766 },
1767 "normalize-path": {
1768 "version": "3.0.0",
1769 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1770 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1771 "dev": true
1772 },
1241 "nth-check": { 1773 "nth-check": {
1242 "version": "1.0.2", 1774 "version": "1.0.2",
1243 "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", 1775 "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
@@ -1247,6 +1779,40 @@
1247 "boolbase": "~1.0.0" 1779 "boolbase": "~1.0.0"
1248 } 1780 }
1249 }, 1781 },
1782 "object-inspect": {
1783 "version": "1.7.0",
1784 "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
1785 "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
1786 "dev": true
1787 },
1788 "object-keys": {
1789 "version": "1.1.1",
1790 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
1791 "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
1792 "dev": true
1793 },
1794 "object.assign": {
1795 "version": "4.1.0",
1796 "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
1797 "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
1798 "dev": true,
1799 "requires": {
1800 "define-properties": "^1.1.2",
1801 "function-bind": "^1.1.1",
1802 "has-symbols": "^1.0.0",
1803 "object-keys": "^1.0.11"
1804 }
1805 },
1806 "object.getownpropertydescriptors": {
1807 "version": "2.1.0",
1808 "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
1809 "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
1810 "dev": true,
1811 "requires": {
1812 "define-properties": "^1.1.3",
1813 "es-abstract": "^1.17.0-next.1"
1814 }
1815 },
1250 "once": { 1816 "once": {
1251 "version": "1.4.0", 1817 "version": "1.4.0",
1252 "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1818 "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -1266,17 +1832,17 @@
1266 } 1832 }
1267 }, 1833 },
1268 "optionator": { 1834 "optionator": {
1269 "version": "0.8.3", 1835 "version": "0.9.1",
1270 "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1836 "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
1271 "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1837 "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
1272 "dev": true, 1838 "dev": true,
1273 "requires": { 1839 "requires": {
1274 "deep-is": "~0.1.3", 1840 "deep-is": "^0.1.3",
1275 "fast-levenshtein": "~2.0.6", 1841 "fast-levenshtein": "^2.0.6",
1276 "levn": "~0.3.0", 1842 "levn": "^0.4.1",
1277 "prelude-ls": "~1.1.2", 1843 "prelude-ls": "^1.2.1",
1278 "type-check": "~0.3.2", 1844 "type-check": "^0.4.0",
1279 "word-wrap": "~1.2.3" 1845 "word-wrap": "^1.2.3"
1280 } 1846 }
1281 }, 1847 },
1282 "os": { 1848 "os": {
@@ -1307,6 +1873,30 @@
1307 "os-tmpdir": "^1.0.0" 1873 "os-tmpdir": "^1.0.0"
1308 } 1874 }
1309 }, 1875 },
1876 "p-limit": {
1877 "version": "2.3.0",
1878 "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
1879 "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
1880 "dev": true,
1881 "requires": {
1882 "p-try": "^2.0.0"
1883 }
1884 },
1885 "p-locate": {
1886 "version": "3.0.0",
1887 "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
1888 "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
1889 "dev": true,
1890 "requires": {
1891 "p-limit": "^2.0.0"
1892 }
1893 },
1894 "p-try": {
1895 "version": "2.2.0",
1896 "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1897 "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1898 "dev": true
1899 },
1310 "parent-module": { 1900 "parent-module": {
1311 "version": "1.0.1", 1901 "version": "1.0.1",
1312 "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1902 "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -1342,6 +1932,12 @@
1342 "@types/node": "*" 1932 "@types/node": "*"
1343 } 1933 }
1344 }, 1934 },
1935 "path-exists": {
1936 "version": "3.0.0",
1937 "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1938 "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
1939 "dev": true
1940 },
1345 "path-is-absolute": { 1941 "path-is-absolute": {
1346 "version": "1.0.1", 1942 "version": "1.0.1",
1347 "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1943 "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1349,9 +1945,9 @@
1349 "dev": true 1945 "dev": true
1350 }, 1946 },
1351 "path-key": { 1947 "path-key": {
1352 "version": "2.0.1", 1948 "version": "3.1.1",
1353 "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1949 "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1354 "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 1950 "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1355 "dev": true 1951 "dev": true
1356 }, 1952 },
1357 "path-parse": { 1953 "path-parse": {
@@ -1373,9 +1969,9 @@
1373 "dev": true 1969 "dev": true
1374 }, 1970 },
1375 "prelude-ls": { 1971 "prelude-ls": {
1376 "version": "1.1.2", 1972 "version": "1.2.1",
1377 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1973 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
1378 "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1974 "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
1379 "dev": true 1975 "dev": true
1380 }, 1976 },
1381 "progress": { 1977 "progress": {
@@ -1416,16 +2012,37 @@
1416 "util-deprecate": "^1.0.1" 2012 "util-deprecate": "^1.0.1"
1417 } 2013 }
1418 }, 2014 },
2015 "readdirp": {
2016 "version": "3.2.0",
2017 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
2018 "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
2019 "dev": true,
2020 "requires": {
2021 "picomatch": "^2.0.4"
2022 }
2023 },
1419 "regexpp": { 2024 "regexpp": {
1420 "version": "3.1.0", 2025 "version": "3.1.0",
1421 "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 2026 "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
1422 "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 2027 "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
1423 "dev": true 2028 "dev": true
1424 }, 2029 },
2030 "require-directory": {
2031 "version": "2.1.1",
2032 "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2033 "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
2034 "dev": true
2035 },
2036 "require-main-filename": {
2037 "version": "2.0.0",
2038 "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
2039 "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
2040 "dev": true
2041 },
1425 "resolve": { 2042 "resolve": {
1426 "version": "1.16.1", 2043 "version": "1.17.0",
1427 "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz", 2044 "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
1428 "integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==", 2045 "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
1429 "dev": true, 2046 "dev": true,
1430 "requires": { 2047 "requires": {
1431 "path-parse": "^1.0.6" 2048 "path-parse": "^1.0.6"
@@ -1457,30 +2074,35 @@
1457 } 2074 }
1458 }, 2075 },
1459 "rollup": { 2076 "rollup": {
1460 "version": "2.7.1", 2077 "version": "2.10.9",
1461 "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.7.1.tgz", 2078 "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.10.9.tgz",
1462 "integrity": "sha512-c1FCjY8HK1nAq0bTZHaR72ZknpP7p0EjxbcVc6BcmtOosurK//P5jtwxX+f/4fgtbrjczqf0uvR+EdtxpriE8g==", 2079 "integrity": "sha512-dY/EbjiWC17ZCUSyk14hkxATAMAShkMsD43XmZGWjLrgFj15M3Dw2kEkA9ns64BiLFm9PKN6vTQw8neHwK74eg==",
1463 "dev": true, 2080 "dev": true,
1464 "requires": { 2081 "requires": {
1465 "fsevents": "~2.1.2" 2082 "fsevents": "~2.1.2"
1466 } 2083 }
1467 }, 2084 },
1468 "run-async": { 2085 "run-async": {
1469 "version": "2.4.0", 2086 "version": "2.4.1",
1470 "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", 2087 "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
1471 "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", 2088 "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
1472 "dev": true, 2089 "dev": true
1473 "requires": {
1474 "is-promise": "^2.1.0"
1475 }
1476 }, 2090 },
1477 "rxjs": { 2091 "rxjs": {
1478 "version": "6.5.4", 2092 "version": "6.5.5",
1479 "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 2093 "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
1480 "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 2094 "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
1481 "dev": true, 2095 "dev": true,
1482 "requires": { 2096 "requires": {
1483 "tslib": "^1.9.0" 2097 "tslib": "^1.9.0"
2098 },
2099 "dependencies": {
2100 "tslib": {
2101 "version": "1.13.0",
2102 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
2103 "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
2104 "dev": true
2105 }
1484 } 2106 }
1485 }, 2107 },
1486 "safe-buffer": { 2108 "safe-buffer": {
@@ -1500,19 +2122,25 @@
1500 "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2122 "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1501 "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 2123 "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
1502 }, 2124 },
2125 "set-blocking": {
2126 "version": "2.0.0",
2127 "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
2128 "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
2129 "dev": true
2130 },
1503 "shebang-command": { 2131 "shebang-command": {
1504 "version": "1.2.0", 2132 "version": "2.0.0",
1505 "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2133 "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1506 "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2134 "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1507 "dev": true, 2135 "dev": true,
1508 "requires": { 2136 "requires": {
1509 "shebang-regex": "^1.0.0" 2137 "shebang-regex": "^3.0.0"
1510 } 2138 }
1511 }, 2139 },
1512 "shebang-regex": { 2140 "shebang-regex": {
1513 "version": "1.0.0", 2141 "version": "3.0.0",
1514 "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2142 "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1515 "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 2143 "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1516 "dev": true 2144 "dev": true
1517 }, 2145 },
1518 "sigmund": { 2146 "sigmund": {
@@ -1522,9 +2150,9 @@
1522 "dev": true 2150 "dev": true
1523 }, 2151 },
1524 "signal-exit": { 2152 "signal-exit": {
1525 "version": "3.0.2", 2153 "version": "3.0.3",
1526 "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 2154 "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
1527 "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 2155 "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
1528 "dev": true 2156 "dev": true
1529 }, 2157 },
1530 "slice-ansi": { 2158 "slice-ansi": {
@@ -1567,17 +2195,48 @@
1567 "emoji-regex": "^8.0.0", 2195 "emoji-regex": "^8.0.0",
1568 "is-fullwidth-code-point": "^3.0.0", 2196 "is-fullwidth-code-point": "^3.0.0",
1569 "strip-ansi": "^6.0.0" 2197 "strip-ansi": "^6.0.0"
1570 }, 2198 }
1571 "dependencies": { 2199 },
1572 "strip-ansi": { 2200 "string.prototype.trimend": {
1573 "version": "6.0.0", 2201 "version": "1.0.1",
1574 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 2202 "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
1575 "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 2203 "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
1576 "dev": true, 2204 "dev": true,
1577 "requires": { 2205 "requires": {
1578 "ansi-regex": "^5.0.0" 2206 "define-properties": "^1.1.3",
1579 } 2207 "es-abstract": "^1.17.5"
1580 } 2208 }
2209 },
2210 "string.prototype.trimleft": {
2211 "version": "2.1.2",
2212 "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
2213 "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
2214 "dev": true,
2215 "requires": {
2216 "define-properties": "^1.1.3",
2217 "es-abstract": "^1.17.5",
2218 "string.prototype.trimstart": "^1.0.0"
2219 }
2220 },
2221 "string.prototype.trimright": {
2222 "version": "2.1.2",
2223 "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
2224 "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
2225 "dev": true,
2226 "requires": {
2227 "define-properties": "^1.1.3",
2228 "es-abstract": "^1.17.5",
2229 "string.prototype.trimend": "^1.0.0"
2230 }
2231 },
2232 "string.prototype.trimstart": {
2233 "version": "1.0.1",
2234 "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
2235 "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
2236 "dev": true,
2237 "requires": {
2238 "define-properties": "^1.1.3",
2239 "es-abstract": "^1.17.5"
1581 } 2240 }
1582 }, 2241 },
1583 "string_decoder": { 2242 "string_decoder": {
@@ -1590,26 +2249,18 @@
1590 } 2249 }
1591 }, 2250 },
1592 "strip-ansi": { 2251 "strip-ansi": {
1593 "version": "5.2.0", 2252 "version": "6.0.0",
1594 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 2253 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
1595 "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 2254 "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
1596 "dev": true, 2255 "dev": true,
1597 "requires": { 2256 "requires": {
1598 "ansi-regex": "^4.1.0" 2257 "ansi-regex": "^5.0.0"
1599 },
1600 "dependencies": {
1601 "ansi-regex": {
1602 "version": "4.1.0",
1603 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1604 "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1605 "dev": true
1606 }
1607 } 2258 }
1608 }, 2259 },
1609 "strip-json-comments": { 2260 "strip-json-comments": {
1610 "version": "3.0.1", 2261 "version": "3.1.0",
1611 "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 2262 "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
1612 "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 2263 "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
1613 "dev": true 2264 "dev": true
1614 }, 2265 },
1615 "supports-color": { 2266 "supports-color": {
@@ -1633,6 +2284,12 @@
1633 "string-width": "^3.0.0" 2284 "string-width": "^3.0.0"
1634 }, 2285 },
1635 "dependencies": { 2286 "dependencies": {
2287 "ansi-regex": {
2288 "version": "4.1.0",
2289 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2290 "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2291 "dev": true
2292 },
1636 "emoji-regex": { 2293 "emoji-regex": {
1637 "version": "7.0.3", 2294 "version": "7.0.3",
1638 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2295 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@@ -1655,6 +2312,15 @@
1655 "is-fullwidth-code-point": "^2.0.0", 2312 "is-fullwidth-code-point": "^2.0.0",
1656 "strip-ansi": "^5.1.0" 2313 "strip-ansi": "^5.1.0"
1657 } 2314 }
2315 },
2316 "strip-ansi": {
2317 "version": "5.2.0",
2318 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2319 "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2320 "dev": true,
2321 "requires": {
2322 "ansi-regex": "^4.1.0"
2323 }
1658 } 2324 }
1659 } 2325 }
1660 }, 2326 },
@@ -1689,9 +2355,9 @@
1689 } 2355 }
1690 }, 2356 },
1691 "tslib": { 2357 "tslib": {
1692 "version": "1.11.1", 2358 "version": "2.0.0",
1693 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", 2359 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz",
1694 "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", 2360 "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==",
1695 "dev": true 2361 "dev": true
1696 }, 2362 },
1697 "tsutils": { 2363 "tsutils": {
@@ -1701,6 +2367,14 @@
1701 "dev": true, 2367 "dev": true,
1702 "requires": { 2368 "requires": {
1703 "tslib": "^1.8.1" 2369 "tslib": "^1.8.1"
2370 },
2371 "dependencies": {
2372 "tslib": {
2373 "version": "1.13.0",
2374 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
2375 "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
2376 "dev": true
2377 }
1704 } 2378 }
1705 }, 2379 },
1706 "tunnel": { 2380 "tunnel": {
@@ -1710,12 +2384,12 @@
1710 "dev": true 2384 "dev": true
1711 }, 2385 },
1712 "type-check": { 2386 "type-check": {
1713 "version": "0.3.2", 2387 "version": "0.4.0",
1714 "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2388 "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
1715 "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2389 "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
1716 "dev": true, 2390 "dev": true,
1717 "requires": { 2391 "requires": {
1718 "prelude-ls": "~1.1.2" 2392 "prelude-ls": "^1.2.1"
1719 } 2393 }
1720 }, 2394 },
1721 "type-fest": { 2395 "type-fest": {
@@ -1735,9 +2409,9 @@
1735 } 2409 }
1736 }, 2410 },
1737 "typescript": { 2411 "typescript": {
1738 "version": "3.8.3", 2412 "version": "3.9.3",
1739 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", 2413 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz",
1740 "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", 2414 "integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==",
1741 "dev": true 2415 "dev": true
1742 }, 2416 },
1743 "typescript-formatter": { 2417 "typescript-formatter": {
@@ -1862,21 +2536,131 @@
1862 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.1.tgz", 2536 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.1.tgz",
1863 "integrity": "sha512-tZFUSbyjUcrh+qQf13ALX4QDdOfDX0cVaBFgy7ktJ0VwS7AW/yRKgGPSxVqqP9OCMNPdqP57O5q47w2pEwfaUg==" 2537 "integrity": "sha512-tZFUSbyjUcrh+qQf13ALX4QDdOfDX0cVaBFgy7ktJ0VwS7AW/yRKgGPSxVqqP9OCMNPdqP57O5q47w2pEwfaUg=="
1864 }, 2538 },
2539 "vscode-test": {
2540 "version": "1.3.0",
2541 "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.3.0.tgz",
2542 "integrity": "sha512-LddukcBiSU2FVTDr3c1D8lwkiOvwlJdDL2hqVbn6gIz+rpTqUCkMZSKYm94Y1v0WXlHSDQBsXyY+tchWQgGVsw==",
2543 "dev": true,
2544 "requires": {
2545 "http-proxy-agent": "^2.1.0",
2546 "https-proxy-agent": "^2.2.4",
2547 "rimraf": "^2.6.3"
2548 }
2549 },
1865 "which": { 2550 "which": {
1866 "version": "1.3.1", 2551 "version": "2.0.2",
1867 "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2552 "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1868 "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2553 "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1869 "dev": true, 2554 "dev": true,
1870 "requires": { 2555 "requires": {
1871 "isexe": "^2.0.0" 2556 "isexe": "^2.0.0"
1872 } 2557 }
1873 }, 2558 },
2559 "which-module": {
2560 "version": "2.0.0",
2561 "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
2562 "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
2563 "dev": true
2564 },
2565 "wide-align": {
2566 "version": "1.1.3",
2567 "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
2568 "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
2569 "dev": true,
2570 "requires": {
2571 "string-width": "^1.0.2 || 2"
2572 },
2573 "dependencies": {
2574 "ansi-regex": {
2575 "version": "3.0.0",
2576 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
2577 "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
2578 "dev": true
2579 },
2580 "is-fullwidth-code-point": {
2581 "version": "2.0.0",
2582 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2583 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2584 "dev": true
2585 },
2586 "string-width": {
2587 "version": "2.1.1",
2588 "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
2589 "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
2590 "dev": true,
2591 "requires": {
2592 "is-fullwidth-code-point": "^2.0.0",
2593 "strip-ansi": "^4.0.0"
2594 }
2595 },
2596 "strip-ansi": {
2597 "version": "4.0.0",
2598 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
2599 "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
2600 "dev": true,
2601 "requires": {
2602 "ansi-regex": "^3.0.0"
2603 }
2604 }
2605 }
2606 },
1874 "word-wrap": { 2607 "word-wrap": {
1875 "version": "1.2.3", 2608 "version": "1.2.3",
1876 "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2609 "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
1877 "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2610 "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
1878 "dev": true 2611 "dev": true
1879 }, 2612 },
2613 "wrap-ansi": {
2614 "version": "5.1.0",
2615 "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
2616 "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
2617 "dev": true,
2618 "requires": {
2619 "ansi-styles": "^3.2.0",
2620 "string-width": "^3.0.0",
2621 "strip-ansi": "^5.0.0"
2622 },
2623 "dependencies": {
2624 "ansi-regex": {
2625 "version": "4.1.0",
2626 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2627 "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2628 "dev": true
2629 },
2630 "emoji-regex": {
2631 "version": "7.0.3",
2632 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
2633 "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
2634 "dev": true
2635 },
2636 "is-fullwidth-code-point": {
2637 "version": "2.0.0",
2638 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2639 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2640 "dev": true
2641 },
2642 "string-width": {
2643 "version": "3.1.0",
2644 "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2645 "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2646 "dev": true,
2647 "requires": {
2648 "emoji-regex": "^7.0.1",
2649 "is-fullwidth-code-point": "^2.0.0",
2650 "strip-ansi": "^5.1.0"
2651 }
2652 },
2653 "strip-ansi": {
2654 "version": "5.2.0",
2655 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2656 "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2657 "dev": true,
2658 "requires": {
2659 "ansi-regex": "^4.1.0"
2660 }
2661 }
2662 }
2663 },
1880 "wrappy": { 2664 "wrappy": {
1881 "version": "1.0.2", 2665 "version": "1.0.2",
1882 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2666 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -1892,12 +2676,97 @@
1892 "mkdirp": "^0.5.1" 2676 "mkdirp": "^0.5.1"
1893 } 2677 }
1894 }, 2678 },
2679 "y18n": {
2680 "version": "4.0.0",
2681 "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
2682 "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
2683 "dev": true
2684 },
1895 "yallist": { 2685 "yallist": {
1896 "version": "2.1.2", 2686 "version": "2.1.2",
1897 "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2687 "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
1898 "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 2688 "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
1899 "dev": true 2689 "dev": true
1900 }, 2690 },
2691 "yargs": {
2692 "version": "13.3.2",
2693 "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
2694 "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
2695 "dev": true,
2696 "requires": {
2697 "cliui": "^5.0.0",
2698 "find-up": "^3.0.0",
2699 "get-caller-file": "^2.0.1",
2700 "require-directory": "^2.1.1",
2701 "require-main-filename": "^2.0.0",
2702 "set-blocking": "^2.0.0",
2703 "string-width": "^3.0.0",
2704 "which-module": "^2.0.0",
2705 "y18n": "^4.0.0",
2706 "yargs-parser": "^13.1.2"
2707 },
2708 "dependencies": {
2709 "ansi-regex": {
2710 "version": "4.1.0",
2711 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2712 "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2713 "dev": true
2714 },
2715 "emoji-regex": {
2716 "version": "7.0.3",
2717 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
2718 "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
2719 "dev": true
2720 },
2721 "is-fullwidth-code-point": {
2722 "version": "2.0.0",
2723 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2724 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2725 "dev": true
2726 },
2727 "string-width": {
2728 "version": "3.1.0",
2729 "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2730 "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2731 "dev": true,
2732 "requires": {
2733 "emoji-regex": "^7.0.1",
2734 "is-fullwidth-code-point": "^2.0.0",
2735 "strip-ansi": "^5.1.0"
2736 }
2737 },
2738 "strip-ansi": {
2739 "version": "5.2.0",
2740 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2741 "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2742 "dev": true,
2743 "requires": {
2744 "ansi-regex": "^4.1.0"
2745 }
2746 }
2747 }
2748 },
2749 "yargs-parser": {
2750 "version": "13.1.2",
2751 "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
2752 "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
2753 "dev": true,
2754 "requires": {
2755 "camelcase": "^5.0.0",
2756 "decamelize": "^1.2.0"
2757 }
2758 },
2759 "yargs-unparser": {
2760 "version": "1.6.0",
2761 "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
2762 "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
2763 "dev": true,
2764 "requires": {
2765 "flat": "^4.1.0",
2766 "lodash": "^4.17.15",
2767 "yargs": "^13.3.0"
2768 }
2769 },
1901 "yauzl": { 2770 "yauzl": {
1902 "version": "2.10.0", 2771 "version": "2.10.0",
1903 "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 2772 "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
diff --git a/editors/code/package.json b/editors/code/package.json
index d30673791..d8f4287fd 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -21,7 +21,7 @@
21 "Programming Languages" 21 "Programming Languages"
22 ], 22 ],
23 "engines": { 23 "engines": {
24 "vscode": "^1.44.0" 24 "vscode": "^1.44.1"
25 }, 25 },
26 "enableProposedApi": true, 26 "enableProposedApi": true,
27 "scripts": { 27 "scripts": {
@@ -29,28 +29,34 @@
29 "package": "vsce package -o rust-analyzer.vsix", 29 "package": "vsce package -o rust-analyzer.vsix",
30 "build": "tsc", 30 "build": "tsc",
31 "watch": "tsc --watch", 31 "watch": "tsc --watch",
32 "lint": "tsfmt --verify && eslint -c .eslintrc.js --ext ts ./src", 32 "lint": "tsfmt --verify && eslint -c .eslintrc.js --ext ts ./src ./tests",
33 "fix": " tsfmt -r && eslint -c .eslintrc.js --ext ts ./src --fix" 33 "fix": " tsfmt -r && eslint -c .eslintrc.js --ext ts ./src ./tests --fix",
34 "pretest": "npm run build",
35 "test": "node ./out/tests/runTests.js"
34 }, 36 },
35 "dependencies": { 37 "dependencies": {
36 "jsonc-parser": "^2.2.1",
37 "node-fetch": "^2.6.0", 38 "node-fetch": "^2.6.0",
38 "vscode-languageclient": "7.0.0-next.1" 39 "vscode-languageclient": "7.0.0-next.1"
39 }, 40 },
40 "devDependencies": { 41 "devDependencies": {
41 "@rollup/plugin-commonjs": "^11.1.0", 42 "@rollup/plugin-commonjs": "^12.0.0",
42 "@rollup/plugin-node-resolve": "^7.1.3", 43 "@rollup/plugin-node-resolve": "^8.0.0",
43 "@types/node": "^12.12.37", 44 "@types/glob": "^7.1.1",
44 "@types/node-fetch": "^2.5.6", 45 "@types/mocha": "^7.0.2",
45 "@types/vscode": "^1.44.0", 46 "@types/node": "^14.0.5",
46 "@typescript-eslint/eslint-plugin": "^2.29.0", 47 "@types/node-fetch": "^2.5.7",
47 "@typescript-eslint/parser": "^2.29.0", 48 "@types/vscode": "^1.44.1",
48 "eslint": "^6.8.0", 49 "@typescript-eslint/eslint-plugin": "^3.0.0",
49 "rollup": "^2.7.1", 50 "@typescript-eslint/parser": "^3.0.0",
50 "tslib": "^1.11.1", 51 "eslint": "^7.0.0",
51 "typescript": "^3.8.3", 52 "glob": "^7.1.6",
53 "mocha": "^7.1.2",
54 "rollup": "^2.10.7",
55 "tslib": "^2.0.0",
56 "typescript": "^3.9.3",
52 "typescript-formatter": "^7.2.2", 57 "typescript-formatter": "^7.2.2",
53 "vsce": "^1.75.0" 58 "vsce": "^1.75.0",
59 "vscode-test": "^1.3.0"
54 }, 60 },
55 "activationEvents": [ 61 "activationEvents": [
56 "onLanguage:rust", 62 "onLanguage:rust",
@@ -58,7 +64,7 @@
58 "onCommand:rust-analyzer.collectGarbage", 64 "onCommand:rust-analyzer.collectGarbage",
59 "workspaceContains:**/Cargo.toml" 65 "workspaceContains:**/Cargo.toml"
60 ], 66 ],
61 "main": "./out/main", 67 "main": "./out/src/main",
62 "contributes": { 68 "contributes": {
63 "taskDefinitions": [ 69 "taskDefinitions": [
64 { 70 {
@@ -122,6 +128,16 @@
122 "category": "Rust Analyzer" 128 "category": "Rust Analyzer"
123 }, 129 },
124 { 130 {
131 "command": "rust-analyzer.debug",
132 "title": "Debug",
133 "category": "Rust Analyzer"
134 },
135 {
136 "command": "rust-analyzer.newDebugConfig",
137 "title": "Generate launch configuration",
138 "category": "Rust Analyzer"
139 },
140 {
125 "command": "rust-analyzer.analyzerStatus", 141 "command": "rust-analyzer.analyzerStatus",
126 "title": "Status", 142 "title": "Status",
127 "category": "Rust Analyzer" 143 "category": "Rust Analyzer"
@@ -150,6 +166,11 @@
150 "command": "rust-analyzer.serverVersion", 166 "command": "rust-analyzer.serverVersion",
151 "title": "Show RA Version", 167 "title": "Show RA Version",
152 "category": "Rust Analyzer" 168 "category": "Rust Analyzer"
169 },
170 {
171 "command": "rust-analyzer.toggleInlayHints",
172 "title": "Toggle inlay hints",
173 "category": "Rust Analyzer"
153 } 174 }
154 ], 175 ],
155 "keybindings": [ 176 "keybindings": [
@@ -205,11 +226,6 @@
205 "default": [], 226 "default": [],
206 "description": "Paths to exclude from analysis." 227 "description": "Paths to exclude from analysis."
207 }, 228 },
208 "rust-analyzer.notifications.workspaceLoaded": {
209 "type": "boolean",
210 "default": true,
211 "markdownDescription": "Whether to show `workspace loaded` message."
212 },
213 "rust-analyzer.notifications.cargoTomlNotFound": { 229 "rust-analyzer.notifications.cargoTomlNotFound": {
214 "type": "boolean", 230 "type": "boolean",
215 "default": true, 231 "default": true,
@@ -222,7 +238,7 @@
222 }, 238 },
223 "rust-analyzer.cargo.allFeatures": { 239 "rust-analyzer.cargo.allFeatures": {
224 "type": "boolean", 240 "type": "boolean",
225 "default": true, 241 "default": false,
226 "description": "Activate all available features" 242 "description": "Activate all available features"
227 }, 243 },
228 "rust-analyzer.cargo.features": { 244 "rust-analyzer.cargo.features": {
@@ -238,6 +254,14 @@
238 "default": false, 254 "default": false,
239 "markdownDescription": "Run `cargo check` on startup to get the correct value for package OUT_DIRs" 255 "markdownDescription": "Run `cargo check` on startup to get the correct value for package OUT_DIRs"
240 }, 256 },
257 "rust-analyzer.cargo.target": {
258 "type": [
259 "null",
260 "string"
261 ],
262 "default": null,
263 "description": "Specify the compilation target"
264 },
241 "rust-analyzer.rustfmt.extraArgs": { 265 "rust-analyzer.rustfmt.extraArgs": {
242 "type": "array", 266 "type": "array",
243 "items": { 267 "items": {
@@ -286,27 +310,37 @@
286 "minItems": 1 310 "minItems": 1
287 }, 311 },
288 "default": null, 312 "default": null,
289 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for checking. The command should include `--message=format=json` or similar option." 313 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for checking. The command should include `--message-format=json` or similar option."
290 }, 314 },
291 "rust-analyzer.checkOnSave.allTargets": { 315 "rust-analyzer.checkOnSave.allTargets": {
292 "type": "boolean", 316 "type": "boolean",
293 "default": true, 317 "default": true,
294 "markdownDescription": "Check all targets and tests (will be passed as `--all-targets`)" 318 "markdownDescription": "Check all targets and tests (will be passed as `--all-targets`)"
295 }, 319 },
320 "rust-analyzer.checkOnSave.allFeatures": {
321 "type": "boolean",
322 "default": false,
323 "markdownDescription": "Check with all features (will be passed as `--all-features`)"
324 },
325 "rust-analyzer.inlayHints.enable": {
326 "type": "boolean",
327 "default": true,
328 "description": "Whether to show inlay hints"
329 },
296 "rust-analyzer.inlayHints.typeHints": { 330 "rust-analyzer.inlayHints.typeHints": {
297 "type": "boolean", 331 "type": "boolean",
298 "default": true, 332 "default": true,
299 "description": "Whether to show inlay type hints" 333 "description": "Whether to show inlay type hints for variables."
300 }, 334 },
301 "rust-analyzer.inlayHints.chainingHints": { 335 "rust-analyzer.inlayHints.chainingHints": {
302 "type": "boolean", 336 "type": "boolean",
303 "default": true, 337 "default": true,
304 "description": "Whether to show inlay type hints for method chains" 338 "description": "Whether to show inlay type hints for method chains."
305 }, 339 },
306 "rust-analyzer.inlayHints.parameterHints": { 340 "rust-analyzer.inlayHints.parameterHints": {
307 "type": "boolean", 341 "type": "boolean",
308 "default": true, 342 "default": true,
309 "description": "Whether to show function parameter name inlay hints at the call site" 343 "description": "Whether to show function parameter name inlay hints at the call site."
310 }, 344 },
311 "rust-analyzer.inlayHints.maxLength": { 345 "rust-analyzer.inlayHints.maxLength": {
312 "type": [ 346 "type": [
@@ -398,7 +432,7 @@
398 "ms-vscode.cpptools" 432 "ms-vscode.cpptools"
399 ], 433 ],
400 "default": "auto", 434 "default": "auto",
401 "description": "Preffered debug engine.", 435 "description": "Preferred debug engine.",
402 "markdownEnumDescriptions": [ 436 "markdownEnumDescriptions": [
403 "First try to use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb), if it's not installed try to use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).", 437 "First try to use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb), if it's not installed try to use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).",
404 "Use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)", 438 "Use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)",
@@ -411,6 +445,36 @@
411 "default": { 445 "default": {
412 "/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust" 446 "/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust"
413 } 447 }
448 },
449 "rust-analyzer.debug.openDebugPane": {
450 "description": "Whether to open up the Debug Pane on debugging start.",
451 "type": "boolean",
452 "default": false
453 },
454 "rust-analyzer.debug.engineSettings": {
455 "type": "object",
456 "default": {},
457 "description": "Optional settings passed to the debug engine. Example:\n{ \"lldb\": { \"terminal\":\"external\"} }"
458 },
459 "rust-analyzer.lens.enable": {
460 "description": "Whether to show CodeLens in Rust files.",
461 "type": "boolean",
462 "default": true
463 },
464 "rust-analyzer.lens.run": {
465 "markdownDescription": "Whether to show Run lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
466 "type": "boolean",
467 "default": true
468 },
469 "rust-analyzer.lens.debug": {
470 "markdownDescription": "Whether to show Debug lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
471 "type": "boolean",
472 "default": true
473 },
474 "rust-analyzer.lens.implementations": {
475 "markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
476 "type": "boolean",
477 "default": true
414 } 478 }
415 } 479 }
416 }, 480 },
@@ -457,6 +521,11 @@
457 ], 521 ],
458 "grammars": [ 522 "grammars": [
459 { 523 {
524 "language": "rust",
525 "scopeName": "source.rust",
526 "path": "rust.tmGrammar.json"
527 },
528 {
460 "language": "ra_syntax_tree", 529 "language": "ra_syntax_tree",
461 "scopeName": "source.ra_syntax_tree", 530 "scopeName": "source.ra_syntax_tree",
462 "path": "ra_syntax_tree.tmGrammar.json" 531 "path": "ra_syntax_tree.tmGrammar.json"
@@ -518,6 +587,11 @@
518 "description": "Style for attributes" 587 "description": "Style for attributes"
519 }, 588 },
520 { 589 {
590 "id": "boolean",
591 "description": "Style for boolean literals",
592 "superType": "keyword"
593 },
594 {
521 "id": "builtinType", 595 "id": "builtinType",
522 "description": "Style for builtin types", 596 "description": "Style for builtin types",
523 "superType": "type" 597 "superType": "type"
@@ -527,6 +601,11 @@
527 "description": "Style for lifetimes" 601 "description": "Style for lifetimes"
528 }, 602 },
529 { 603 {
604 "id": "selfKeyword",
605 "description": "Style for the self keyword",
606 "superType": "keyword"
607 },
608 {
530 "id": "typeAlias", 609 "id": "typeAlias",
531 "description": "Style for type aliases", 610 "description": "Style for type aliases",
532 "superType": "type" 611 "superType": "type"
@@ -539,10 +618,18 @@
539 { 618 {
540 "id": "unresolvedReference", 619 "id": "unresolvedReference",
541 "description": "Style for names which can not be resolved due to compilation errors" 620 "description": "Style for names which can not be resolved due to compilation errors"
621 },
622 {
623 "id": "formatSpecifier",
624 "description": "Style for {} placeholders in format strings"
542 } 625 }
543 ], 626 ],
544 "semanticTokenModifiers": [ 627 "semanticTokenModifiers": [
545 { 628 {
629 "id": "attribute",
630 "description": "Style for elements within attributes"
631 },
632 {
546 "id": "constant", 633 "id": "constant",
547 "description": "Style for compile-time constants" 634 "description": "Style for compile-time constants"
548 }, 635 },
@@ -563,29 +650,114 @@
563 { 650 {
564 "language": "rust", 651 "language": "rust",
565 "scopes": { 652 "scopes": {
653 "macro": [
654 "entity.name.function.macro.rust"
655 ],
566 "attribute": [ 656 "attribute": [
567 "meta.attribute" 657 "meta.attribute.rust"
658 ],
659 "function.attribute": [
660 "entity.name.function.attribute.rust"
661 ],
662 "boolean": [
663 "constant.language.boolean.rust"
568 ], 664 ],
569 "builtinType": [ 665 "builtinType": [
570 "support.type.primitive" 666 "support.type.primitive.rust"
571 ], 667 ],
572 "lifetime": [ 668 "lifetime": [
573 "entity.name.lifetime.rust" 669 "storage.modifier.lifetime.rust"
574 ], 670 ],
575 "typeAlias": [ 671 "typeAlias": [
576 "entity.name.typeAlias" 672 "entity.name.type.typeAlias.rust"
577 ], 673 ],
578 "union": [ 674 "union": [
579 "entity.name.union" 675 "entity.name.type.union.rust"
676 ],
677 "struct": [
678 "entity.name.type.struct.rust"
580 ], 679 ],
581 "keyword.unsafe": [ 680 "keyword": [
582 "keyword.other.unsafe" 681 "keyword.other.rust"
682 ],
683 "keyword.controlFlow": [
684 "keyword.control.rust"
583 ], 685 ],
584 "variable.constant": [ 686 "variable.constant": [
585 "entity.name.constant" 687 "variable.other.constant.rust"
688 ],
689 "formatSpecifier": [
690 "punctuation.section.embedded.rust"
691 ],
692 "*.mutable": [
693 "markup.underline"
586 ] 694 ]
587 } 695 }
588 } 696 }
589 ] 697 ],
698 "menus": {
699 "commandPalette": [
700 {
701 "command": "rust-analyzer.syntaxTree",
702 "when": "inRustProject"
703 },
704 {
705 "command": "rust-analyzer.expandMacro",
706 "when": "inRustProject"
707 },
708 {
709 "command": "rust-analyzer.matchingBrace",
710 "when": "inRustProject"
711 },
712 {
713 "command": "rust-analyzer.parentModule",
714 "when": "inRustProject"
715 },
716 {
717 "command": "rust-analyzer.joinLines",
718 "when": "inRustProject"
719 },
720 {
721 "command": "rust-analyzer.run",
722 "when": "inRustProject"
723 },
724 {
725 "command": "rust-analyzer.debug",
726 "when": "inRustProject"
727 },
728 {
729 "command": "rust-analyzer.newDebugConfig",
730 "when": "inRustProject"
731 },
732 {
733 "command": "rust-analyzer.analyzerStatus",
734 "when": "inRustProject"
735 },
736 {
737 "command": "rust-analyzer.collectGarbage",
738 "when": "inRustProject"
739 },
740 {
741 "command": "rust-analyzer.reload",
742 "when": "inRustProject"
743 },
744 {
745 "command": "rust-analyzer.onEnter",
746 "when": "inRustProject"
747 },
748 {
749 "command": "rust-analyzer.ssr",
750 "when": "inRustProject"
751 },
752 {
753 "command": "rust-analyzer.serverVersion",
754 "when": "inRustProject"
755 },
756 {
757 "command": "rust-analyzer.toggleInlayHints",
758 "when": "inRustProject"
759 }
760 ]
761 }
590 } 762 }
591} 763}
diff --git a/editors/code/rollup.config.js b/editors/code/rollup.config.js
index 2ca27694d..58360eabb 100644
--- a/editors/code/rollup.config.js
+++ b/editors/code/rollup.config.js
@@ -6,7 +6,7 @@ import nodeBuiltins from 'builtin-modules';
6 6
7/** @type { import('rollup').RollupOptions } */ 7/** @type { import('rollup').RollupOptions } */
8export default { 8export default {
9 input: 'out/main.js', 9 input: 'out/src/main.js',
10 plugins: [ 10 plugins: [
11 resolve({ 11 resolve({
12 preferBuiltins: true 12 preferBuiltins: true
@@ -20,7 +20,7 @@ export default {
20 ], 20 ],
21 external: [...nodeBuiltins, 'vscode'], 21 external: [...nodeBuiltins, 'vscode'],
22 output: { 22 output: {
23 file: './out/main.js', 23 file: './out/src/main.js',
24 format: 'cjs', 24 format: 'cjs',
25 exports: 'named' 25 exports: 'named'
26 } 26 }
diff --git a/editors/code/rust.tmGrammar.json b/editors/code/rust.tmGrammar.json
new file mode 100644
index 000000000..ab87cd39f
--- /dev/null
+++ b/editors/code/rust.tmGrammar.json
@@ -0,0 +1,686 @@
1{
2 "name": "Rust",
3 "scopeName": "source.rust",
4 "patterns": [
5 {
6 "comment": "Implementation",
7 "begin": "\\b(impl)\\b",
8 "end": "\\{",
9 "beginCaptures": {
10 "1": {
11 "name": "storage.type.rust"
12 }
13 },
14 "patterns": [
15 {
16 "include": "#block_comment"
17 },
18 {
19 "include": "#line_comment"
20 },
21 {
22 "include": "#sigils"
23 },
24 {
25 "include": "#mut"
26 },
27 {
28 "include": "#dyn"
29 },
30 {
31 "include": "#ref_lifetime"
32 },
33 {
34 "include": "#core_types"
35 },
36 {
37 "include": "#core_marker"
38 },
39 {
40 "include": "#core_traits"
41 },
42 {
43 "include": "#std_types"
44 },
45 {
46 "include": "#std_traits"
47 },
48 {
49 "include": "#type_params"
50 },
51 {
52 "include": "#where"
53 },
54 {
55 "name": "storage.type.rust",
56 "match": "\\bfor\\b"
57 },
58 {
59 "include": "#type"
60 }
61 ]
62 },
63 {
64 "include": "#block_doc_comment"
65 },
66 {
67 "include": "#block_comment"
68 },
69 {
70 "include": "#line_doc_comment"
71 },
72 {
73 "include": "#line_comment"
74 },
75 {
76 "comment": "Attribute",
77 "name": "meta.attribute.rust",
78 "begin": "#\\!?\\[(\\w*)",
79 "end": "\\]",
80 "captures": {
81 "1": {
82 "name": "entity.name.function.attribute.rust"
83 }
84 },
85 "patterns": [
86 {
87 "include": "#string_literal"
88 },
89 {
90 "include": "#block_doc_comment"
91 },
92 {
93 "include": "#block_comment"
94 },
95 {
96 "include": "#line_doc_comment"
97 },
98 {
99 "include": "#line_comment"
100 }
101 ]
102 },
103 {
104 "comment": "Single-quote string literal (character)",
105 "name": "string.quoted.single.rust",
106 "match": "b?'([^'\\\\]|\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.))'"
107 },
108 {
109 "include": "#string_literal"
110 },
111 {
112 "include": "#raw_string_literal"
113 },
114 {
115 "comment": "Floating point literal (fraction)",
116 "name": "constant.numeric.float.rust",
117 "match": "\\b[0-9][0-9_]*\\.[0-9][0-9_]*([eE][+-]?[0-9_]+)?(f32|f64)?\\b"
118 },
119 {
120 "comment": "Floating point literal (exponent)",
121 "name": "constant.numeric.float.rust",
122 "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?[eE][+-]?[0-9_]+(f32|f64)?\\b"
123 },
124 {
125 "comment": "Floating point literal (typed)",
126 "name": "constant.numeric.float.rust",
127 "match": "\\b[0-9][0-9_]*(\\.[0-9][0-9_]*)?([eE][+-]?[0-9_]+)?(f32|f64)\\b"
128 },
129 {
130 "comment": "Integer literal (decimal)",
131 "name": "constant.numeric.integer.decimal.rust",
132 "match": "\\b[0-9][0-9_]*([ui](8|16|32|64|128|s|size))?\\b"
133 },
134 {
135 "comment": "Integer literal (hexadecimal)",
136 "name": "constant.numeric.integer.hexadecimal.rust",
137 "match": "\\b0x[a-fA-F0-9_]+([ui](8|16|32|64|128|s|size))?\\b"
138 },
139 {
140 "comment": "Integer literal (octal)",
141 "name": "constant.numeric.integer.octal.rust",
142 "match": "\\b0o[0-7_]+([ui](8|16|32|64|128|s|size))?\\b"
143 },
144 {
145 "comment": "Integer literal (binary)",
146 "name": "constant.numeric.integer.binary.rust",
147 "match": "\\b0b[01_]+([ui](8|16|32|64|128|s|size))?\\b"
148 },
149 {
150 "comment": "Static storage modifier",
151 "name": "storage.modifier.static.rust",
152 "match": "\\bstatic\\b"
153 },
154 {
155 "comment": "Boolean constant",
156 "name": "constant.language.boolean.rust",
157 "match": "\\b(true|false)\\b"
158 },
159 {
160 "comment": "Control keyword",
161 "name": "keyword.control.rust",
162 "match": "\\b(async|await|break|continue|else|if|in|for|loop|match|return|try|while)\\b"
163 },
164 {
165 "comment": "Keyword",
166 "name": "keyword.other.rust",
167 "match": "\\b(crate|extern|mod|let|ref|use|super|move|as)\\b"
168 },
169 {
170 "comment": "Reserved keyword",
171 "name": "invalid.deprecated.rust",
172 "match": "\\b(abstract|alignof|become|do|final|macro|offsetof|override|priv|proc|pure|sizeof|typeof|virtual|yield)\\b"
173 },
174 {
175 "include": "#unsafe"
176 },
177 {
178 "include": "#sigils"
179 },
180 {
181 "include": "#self"
182 },
183 {
184 "include": "#mut"
185 },
186 {
187 "include": "#dyn"
188 },
189 {
190 "include": "#impl"
191 },
192 {
193 "include": "#box"
194 },
195 {
196 "include": "#lifetime"
197 },
198 {
199 "include": "#ref_lifetime"
200 },
201 {
202 "include": "#const"
203 },
204 {
205 "include": "#pub"
206 },
207 {
208 "comment": "Miscellaneous operator",
209 "name": "keyword.operator.misc.rust",
210 "match": "(=>|::|\\?)"
211 },
212 {
213 "comment": "Comparison operator",
214 "name": "keyword.operator.comparison.rust",
215 "match": "(&&|\\|\\||==|!=)"
216 },
217 {
218 "comment": "Assignment operator",
219 "name": "keyword.operator.assignment.rust",
220 "match": "(\\+=|-=|/=|\\*=|%=|\\^=|&=|\\|=|<<=|>>=|=)"
221 },
222 {
223 "comment": "Arithmetic operator",
224 "name": "keyword.operator.arithmetic.rust",
225 "match": "(!|\\+|-|/|\\*|%|\\^|&|\\||<<|>>)"
226 },
227 {
228 "comment": "Comparison operator (second group because of regex precedence)",
229 "name": "keyword.operator.comparison.rust",
230 "match": "(<=|>=|<|>)"
231 },
232 {
233 "include": "#core_types"
234 },
235 {
236 "include": "#core_vars"
237 },
238 {
239 "include": "#core_marker"
240 },
241 {
242 "include": "#core_traits"
243 },
244 {
245 "include": "#std_types"
246 },
247 {
248 "include": "#std_traits"
249 },
250 {
251 "comment": "Built-in macro",
252 "name": "support.function.builtin.rust",
253 "match": "\\b(macro_rules|compile_error|format_args|env|option_env|concat_idents|concat|line|column|file|stringify|include|include_str|include_bytes|module_path|cfg)!"
254 },
255 {
256 "comment": "Core macro",
257 "name": "support.function.core.rust",
258 "match": "\\b(panic|assert|assert_eq|assert_ne|debug_assert|debug_assert_eq|debug_assert_ne|try|write|writeln|unreachable|unimplemented)!"
259 },
260 {
261 "comment": "Standard library macro",
262 "name": "support.function.std.rust",
263 "match": "\\b(format|print|println|eprint|eprintln|select|vec)!"
264 },
265 {
266 "comment": "Logging macro",
267 "name": "support.function.log.rust",
268 "match": "\\b(log|error|warn|info|debug|trace|log_enabled)!"
269 },
270 {
271 "comment": "Invokation of a macro",
272 "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*\\!)\\s*[({\\[]",
273 "captures": {
274 "1": {
275 "name": "entity.name.function.macro.rust"
276 }
277 }
278 },
279 {
280 "comment": "Function call",
281 "match": "\\b([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)\\s*\\(",
282 "captures": {
283 "1": {
284 "name": "entity.name.function.rust"
285 }
286 }
287 },
288 {
289 "comment": "Function call with type parameters",
290 "begin": "\\b([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)\\s*(::)(?=\\s*<.*>\\s*\\()",
291 "end": "\\(",
292 "captures": {
293 "1": {
294 "name": "entity.name.function.rust"
295 },
296 "2": {
297 "name": "keyword.operator.misc.rust"
298 }
299 },
300 "patterns": [
301 {
302 "include": "#type_params"
303 }
304 ]
305 },
306 {
307 "comment": "Function definition",
308 "begin": "\\b(fn)\\s+([A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+)",
309 "end": "[\\{;]",
310 "beginCaptures": {
311 "1": {
312 "name": "keyword.other.fn.rust"
313 },
314 "2": {
315 "name": "entity.name.function.rust"
316 }
317 },
318 "patterns": [
319 {
320 "include": "#block_comment"
321 },
322 {
323 "include": "#line_comment"
324 },
325 {
326 "include": "#sigils"
327 },
328 {
329 "include": "#self"
330 },
331 {
332 "include": "#mut"
333 },
334 {
335 "include": "#dyn"
336 },
337 {
338 "include": "#impl"
339 },
340 {
341 "include": "#ref_lifetime"
342 },
343 {
344 "include": "#core_types"
345 },
346 {
347 "include": "#core_marker"
348 },
349 {
350 "include": "#core_traits"
351 },
352 {
353 "include": "#std_types"
354 },
355 {
356 "include": "#std_traits"
357 },
358 {
359 "include": "#type_params"
360 },
361 {
362 "include": "#const"
363 },
364 {
365 "include": "#where"
366 },
367 {
368 "include": "#unsafe"
369 },
370 {
371 "comment": "Function arguments",
372 "match": "\bfn\b",
373 "name": "keyword.other.fn.rust"
374 }
375 ]
376 },
377 {
378 "comment": "Type declaration",
379 "begin": "\\b(enum|struct|trait|union)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
380 "end": "[\\{\\(;]",
381 "beginCaptures": {
382 "1": {
383 "name": "storage.type.rust"
384 },
385 "2": {
386 "name": "entity.name.type.rust"
387 }
388 },
389 "patterns": [
390 {
391 "include": "#block_comment"
392 },
393 {
394 "include": "#line_comment"
395 },
396 {
397 "include": "#core_traits"
398 },
399 {
400 "include": "#std_traits"
401 },
402 {
403 "include": "#type_params"
404 },
405 {
406 "include": "#core_types"
407 },
408 {
409 "include": "#pub"
410 },
411 {
412 "include": "#where"
413 }
414 ]
415 },
416 {
417 "comment": "Type alias",
418 "begin": "\\b(type)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
419 "end": ";",
420 "beginCaptures": {
421 "1": {
422 "name": "storage.type.rust"
423 },
424 "2": {
425 "name": "entity.name.type.rust"
426 }
427 },
428 "patterns": [
429 {
430 "include": "#block_comment"
431 },
432 {
433 "include": "#line_comment"
434 },
435 {
436 "include": "#sigils"
437 },
438 {
439 "include": "#mut"
440 },
441 {
442 "include": "#dyn"
443 },
444 {
445 "include": "#impl"
446 },
447 {
448 "include": "#lifetime"
449 },
450 {
451 "include": "#ref_lifetime"
452 },
453 {
454 "include": "#core_types"
455 },
456 {
457 "include": "#core_marker"
458 },
459 {
460 "include": "#core_traits"
461 },
462 {
463 "include": "#std_types"
464 },
465 {
466 "include": "#std_traits"
467 },
468 {
469 "include": "#type_params"
470 }
471 ]
472 }
473 ],
474 "repository": {
475 "block_doc_comment": {
476 "comment": "Block documentation comment",
477 "name": "comment.block.documentation.rust",
478 "begin": "/\\*[\\*!](?![\\*/])",
479 "end": "\\*/",
480 "patterns": [
481 {
482 "include": "#block_doc_comment"
483 },
484 {
485 "include": "#block_comment"
486 }
487 ]
488 },
489 "block_comment": {
490 "comment": "Block comment",
491 "name": "comment.block.rust",
492 "begin": "/\\*",
493 "end": "\\*/",
494 "patterns": [
495 {
496 "include": "#block_doc_comment"
497 },
498 {
499 "include": "#block_comment"
500 }
501 ]
502 },
503 "line_doc_comment": {
504 "comment": "Single-line documentation comment",
505 "name": "comment.line.documentation.rust",
506 "begin": "//[!/](?=[^/])",
507 "end": "$"
508 },
509 "line_comment": {
510 "comment": "Single-line comment",
511 "name": "comment.line.double-slash.rust",
512 "begin": "//",
513 "end": "$"
514 },
515 "escaped_character": {
516 "name": "constant.character.escape.rust",
517 "match": "\\\\(x[0-9A-Fa-f]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)"
518 },
519 "string_literal": {
520 "comment": "Double-quote string literal",
521 "name": "string.quoted.double.rust",
522 "begin": "b?\"",
523 "end": "\"",
524 "patterns": [
525 {
526 "include": "#escaped_character"
527 }
528 ]
529 },
530 "raw_string_literal": {
531 "comment": "Raw double-quote string literal",
532 "name": "string.quoted.double.raw.rust",
533 "begin": "b?r(#*)\"",
534 "end": "\"\\1"
535 },
536 "sigils": {
537 "comment": "Sigil",
538 "name": "keyword.operator.sigil.rust",
539 "match": "[&*](?=[a-zA-Z0-9_\\(\\[\\|\\\"]+)"
540 },
541 "self": {
542 "comment": "Self variable",
543 "name": "variable.language.rust",
544 "match": "\\bself\\b"
545 },
546 "mut": {
547 "comment": "Mutable storage modifier",
548 "name": "storage.modifier.mut.rust",
549 "match": "\\bmut\\b"
550 },
551 "dyn": {
552 "comment": "Dynamic modifier",
553 "name": "storage.modifier.dyn.rust",
554 "match": "\\bdyn\\b"
555 },
556 "impl": {
557 "comment": "Existential type modifier",
558 "name": "storage.modifier.impl.rust",
559 "match": "\\bimpl\\b"
560 },
561 "box": {
562 "comment": "Box storage modifier",
563 "name": "storage.modifier.box.rust",
564 "match": "\\bbox\\b"
565 },
566 "const": {
567 "comment": "Const storage modifier",
568 "name": "storage.modifier.const.rust",
569 "match": "\\bconst\\b"
570 },
571 "pub": {
572 "comment": "Visibility modifier",
573 "name": "storage.modifier.visibility.rust",
574 "match": "\\bpub\\b"
575 },
576 "unsafe": {
577 "comment": "Unsafe code keyword",
578 "name": "keyword.other.unsafe.rust",
579 "match": "\\bunsafe\\b"
580 },
581 "where": {
582 "comment": "Generic where clause",
583 "name": "keyword.other.where.rust",
584 "match": "\\bwhere\\b"
585 },
586 "lifetime": {
587 "comment": "Named lifetime",
588 "name": "storage.modifier.lifetime.rust",
589 "match": "'([a-zA-Z_][a-zA-Z0-9_]*)\\b"
590 },
591 "ref_lifetime": {
592 "comment": "Reference with named lifetime",
593 "match": "(&)('[a-zA-Z_][a-zA-Z0-9_]*)\\b",
594 "captures": {
595 "1": {
596 "name": "keyword.operator.sigil.rust"
597 },
598 "2": {
599 "name": "storage.modifier.lifetime.rust"
600 }
601 }
602 },
603 "core_types": {
604 "comment": "Built-in/core type",
605 "name": "support.type.primitive.rust",
606 "match": "\\b(bool|char|usize|isize|u8|u16|u32|u64|u128|i8|i16|i32|i64|i128|f32|f64|str|Self)\\b"
607 },
608 "core_vars": {
609 "comment": "Core type variant",
610 "name": "support.constant.core.rust",
611 "match": "\\b(Some|None|Ok|Err)\\b"
612 },
613 "core_marker": {
614 "comment": "Core trait (marker)",
615 "name": "entity.name.type.marker.rust",
616 "match": "\\b(Copy|Send|Sized|Sync)\\b"
617 },
618 "core_traits": {
619 "comment": "Core trait",
620 "name": "entity.name.type.core.rust",
621 "match": "\\b(Drop|Fn|FnMut|FnOnce|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator)\\b"
622 },
623 "std_types": {
624 "comment": "Standard library type",
625 "name": "entity.name.type.class.std.rust",
626 "match": "\\b(Box|String|Vec|Path|PathBuf|Option|Result)\\b"
627 },
628 "std_traits": {
629 "comment": "Standard library trait",
630 "name": "entity.name.type.std.rust",
631 "match": "\\b(ToOwned|ToString)\\b"
632 },
633 "type": {
634 "comment": "A type",
635 "name": "entity.name.type.rust",
636 "match": "\\b([A-Za-z][_A-Za-z0-9]*|_[_A-Za-z0-9]+)\\b"
637 },
638 "type_params": {
639 "comment": "Type parameters",
640 "name": "meta.type_params.rust",
641 "begin": "<(?![=<])",
642 "end": "(?<![-])>",
643 "patterns": [
644 {
645 "include": "#block_comment"
646 },
647 {
648 "include": "#line_comment"
649 },
650 {
651 "include": "#sigils"
652 },
653 {
654 "include": "#mut"
655 },
656 {
657 "include": "#dyn"
658 },
659 {
660 "include": "#impl"
661 },
662 {
663 "include": "#lifetime"
664 },
665 {
666 "include": "#core_types"
667 },
668 {
669 "include": "#core_marker"
670 },
671 {
672 "include": "#core_traits"
673 },
674 {
675 "include": "#std_types"
676 },
677 {
678 "include": "#std_traits"
679 },
680 {
681 "include": "#type_params"
682 }
683 ]
684 }
685 }
686} \ No newline at end of file
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/ast_inspector.ts
index cfcf47b2f..4fdd167bd 100644
--- a/editors/code/src/commands/syntax_tree.ts
+++ b/editors/code/src/ast_inspector.ts
@@ -1,93 +1,15 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { Ctx, Cmd, Disposable } from '../ctx';
5import { isRustDocument, RustEditor, isRustEditor, sleep } from '../util';
6
7const AST_FILE_SCHEME = "rust-analyzer";
8
9// Opens the virtual file that will show the syntax tree
10//
11// The contents of the file come from the `TextDocumentContentProvider`
12export function syntaxTree(ctx: Ctx): Cmd {
13 const tdcp = new TextDocumentContentProvider(ctx);
14
15 void new AstInspector(ctx);
16
17 ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider(AST_FILE_SCHEME, tdcp));
18 ctx.pushCleanup(vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
19 brackets: [["[", ")"]],
20 }));
21
22 return async () => {
23 const editor = vscode.window.activeTextEditor;
24 const rangeEnabled = !!editor && !editor.selection.isEmpty;
25
26 const uri = rangeEnabled
27 ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`)
28 : tdcp.uri;
29
30 const document = await vscode.workspace.openTextDocument(uri);
31
32 tdcp.eventEmitter.fire(uri);
33
34 void await vscode.window.showTextDocument(document, {
35 viewColumn: vscode.ViewColumn.Two,
36 preserveFocus: true
37 });
38 };
39}
40
41class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
42 readonly uri = vscode.Uri.parse('rust-analyzer://syntaxtree/tree.rast');
43 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
44
45
46 constructor(private readonly ctx: Ctx) {
47 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
48 vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
49 }
50
51 private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
52 if (isRustDocument(event.document)) {
53 // We need to order this after language server updates, but there's no API for that.
54 // Hence, good old sleep().
55 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
56 }
57 }
58 private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
59 if (editor && isRustEditor(editor)) {
60 this.eventEmitter.fire(this.uri);
61 }
62 }
63
64 provideTextDocumentContent(uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
65 const rustEditor = this.ctx.activeRustEditor;
66 if (!rustEditor) return '';
67
68 // When the range based query is enabled we take the range of the selection
69 const range = uri.query === 'range=true' && !rustEditor.selection.isEmpty
70 ? this.ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
71 : null;
72
73 const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range, };
74 return this.ctx.client.sendRequest(ra.syntaxTree, params, ct);
75 }
76
77 get onDidChange(): vscode.Event<vscode.Uri> {
78 return this.eventEmitter.event;
79 }
80}
81 2
3import { Ctx, Disposable } from './ctx';
4import { RustEditor, isRustEditor } from './util';
82 5
83// FIXME: consider implementing this via the Tree View API? 6// FIXME: consider implementing this via the Tree View API?
84// https://code.visualstudio.com/api/extension-guides/tree-view 7// https://code.visualstudio.com/api/extension-guides/tree-view
85class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, Disposable { 8export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, Disposable {
86 private readonly astDecorationType = vscode.window.createTextEditorDecorationType({ 9 private readonly astDecorationType = vscode.window.createTextEditorDecorationType({
87 borderColor: new vscode.ThemeColor('rust_analyzer.syntaxTreeBorder'), 10 borderColor: new vscode.ThemeColor('rust_analyzer.syntaxTreeBorder'),
88 borderStyle: "solid", 11 borderStyle: "solid",
89 borderWidth: "2px", 12 borderWidth: "2px",
90
91 }); 13 });
92 private rustEditor: undefined | RustEditor; 14 private rustEditor: undefined | RustEditor;
93 15
@@ -113,7 +35,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
113 }); 35 });
114 36
115 constructor(ctx: Ctx) { 37 constructor(ctx: Ctx) {
116 ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: AST_FILE_SCHEME }, this)); 38 ctx.pushCleanup(vscode.languages.registerHoverProvider({ scheme: 'rust-analyzer' }, this));
117 ctx.pushCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this)); 39 ctx.pushCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this));
118 vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, ctx.subscriptions); 40 vscode.workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, ctx.subscriptions);
119 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions); 41 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
@@ -146,7 +68,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
146 } 68 }
147 69
148 private findAstTextEditor(): undefined | vscode.TextEditor { 70 private findAstTextEditor(): undefined | vscode.TextEditor {
149 return vscode.window.visibleTextEditors.find(it => it.document.uri.scheme === AST_FILE_SCHEME); 71 return vscode.window.visibleTextEditors.find(it => it.document.uri.scheme === 'rust-analyzer');
150 } 72 }
151 73
152 private setRustEditor(newRustEditor: undefined | RustEditor) { 74 private setRustEditor(newRustEditor: undefined | RustEditor) {
@@ -206,7 +128,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
206 } 128 }
207 129
208 private parseRustTextRange(doc: vscode.TextDocument, astLine: string): undefined | vscode.Range { 130 private parseRustTextRange(doc: vscode.TextDocument, astLine: string): undefined | vscode.Range {
209 const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine); 131 const parsedRange = /(\d+)\.\.(\d+)/.exec(astLine);
210 if (!parsedRange) return; 132 if (!parsedRange) return;
211 133
212 const [begin, end] = parsedRange 134 const [begin, end] = parsedRange
@@ -225,7 +147,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
225 return doc.positionAt(targetOffset); 147 return doc.positionAt(targetOffset);
226 } 148 }
227 149
228 // Shitty workaround for crlf line endings 150 // Dirty workaround for crlf line endings
229 // We are still in this prehistoric era of carriage returns here... 151 // We are still in this prehistoric era of carriage returns here...
230 152
231 let line = 0; 153 let line = 0;
diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts
deleted file mode 100644
index a328ba9bd..000000000
--- a/editors/code/src/cargo.ts
+++ /dev/null
@@ -1,106 +0,0 @@
1import * as cp from 'child_process';
2import * as readline from 'readline';
3import { OutputChannel } from 'vscode';
4
5interface CompilationArtifact {
6 fileName: string;
7 name: string;
8 kind: string;
9 isTest: boolean;
10}
11
12export class Cargo {
13 rootFolder: string;
14 env?: Record<string, string>;
15 output: OutputChannel;
16
17 public constructor(cargoTomlFolder: string, output: OutputChannel, env: Record<string, string> | undefined = undefined) {
18 this.rootFolder = cargoTomlFolder;
19 this.output = output;
20 this.env = env;
21 }
22
23 public async artifactsFromArgs(cargoArgs: string[]): Promise<CompilationArtifact[]> {
24 const artifacts: CompilationArtifact[] = [];
25
26 try {
27 await this.runCargo(cargoArgs,
28 message => {
29 if (message.reason === 'compiler-artifact' && message.executable) {
30 const isBinary = message.target.crate_types.includes('bin');
31 const isBuildScript = message.target.kind.includes('custom-build');
32 if ((isBinary && !isBuildScript) || message.profile.test) {
33 artifacts.push({
34 fileName: message.executable,
35 name: message.target.name,
36 kind: message.target.kind[0],
37 isTest: message.profile.test
38 });
39 }
40 }
41 else if (message.reason === 'compiler-message') {
42 this.output.append(message.message.rendered);
43 }
44 },
45 stderr => {
46 this.output.append(stderr);
47 }
48 );
49 }
50 catch (err) {
51 this.output.show(true);
52 throw new Error(`Cargo invocation has failed: ${err}`);
53 }
54
55 return artifacts;
56 }
57
58 public async executableFromArgs(args: string[]): Promise<string> {
59 const cargoArgs = [...args]; // to remain args unchanged
60 cargoArgs.push("--message-format=json");
61
62 const artifacts = await this.artifactsFromArgs(cargoArgs);
63
64 if (artifacts.length === 0) {
65 throw new Error('No compilation artifacts');
66 } else if (artifacts.length > 1) {
67 throw new Error('Multiple compilation artifacts are not supported.');
68 }
69
70 return artifacts[0].fileName;
71 }
72
73 runCargo(
74 cargoArgs: string[],
75 onStdoutJson: (obj: any) => void,
76 onStderrString: (data: string) => void
77 ): Promise<number> {
78 return new Promise<number>((resolve, reject) => {
79 const cargo = cp.spawn('cargo', cargoArgs, {
80 stdio: ['ignore', 'pipe', 'pipe'],
81 cwd: this.rootFolder,
82 env: this.env,
83 });
84
85 cargo.on('error', err => {
86 reject(new Error(`could not launch cargo: ${err}`));
87 });
88 cargo.stderr.on('data', chunk => {
89 onStderrString(chunk.toString());
90 });
91
92 const rl = readline.createInterface({ input: cargo.stdout });
93 rl.on('line', line => {
94 const message = JSON.parse(line);
95 onStdoutJson(message);
96 });
97
98 cargo.on('exit', (exitCode, _) => {
99 if (exitCode === 0)
100 resolve(exitCode);
101 else
102 reject(new Error(`exit code: ${exitCode}.`));
103 });
104 });
105 }
106} \ No newline at end of file
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index cffdcf11a..d64f9a3f9 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -31,24 +31,112 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
31 const res = await next(document, token); 31 const res = await next(document, token);
32 if (res === undefined) throw new Error('busy'); 32 if (res === undefined) throw new Error('busy');
33 return res; 33 return res;
34 },
35 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
36 const params: lc.CodeActionParams = {
37 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
38 range: client.code2ProtocolConverter.asRange(range),
39 context: client.code2ProtocolConverter.asCodeActionContext(context)
40 };
41 return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => {
42 if (values === null) return undefined;
43 const result: (vscode.CodeAction | vscode.Command)[] = [];
44 const groups = new Map<string, { index: number; items: vscode.CodeAction[] }>();
45 for (const item of values) {
46 if (lc.CodeAction.is(item)) {
47 const action = client.protocol2CodeConverter.asCodeAction(item);
48 const group = actionGroup(item);
49 if (isSnippetEdit(item) || group) {
50 action.command = {
51 command: "rust-analyzer.applySnippetWorkspaceEdit",
52 title: "",
53 arguments: [action.edit],
54 };
55 action.edit = undefined;
56 }
57
58 if (group) {
59 let entry = groups.get(group);
60 if (!entry) {
61 entry = { index: result.length, items: [] };
62 groups.set(group, entry);
63 result.push(action);
64 }
65 entry.items.push(action);
66 } else {
67 result.push(action);
68 }
69 } else {
70 const command = client.protocol2CodeConverter.asCommand(item);
71 result.push(command);
72 }
73 }
74 for (const [group, { index, items }] of groups) {
75 if (items.length === 1) {
76 result[index] = items[0];
77 } else {
78 const action = new vscode.CodeAction(group);
79 action.command = {
80 command: "rust-analyzer.applyActionGroup",
81 title: "",
82 arguments: [items.map((item) => {
83 return { label: item.title, edit: item.command!!.arguments!![0] };
84 })],
85 };
86 result[index] = action;
87 }
88 }
89 return result;
90 },
91 (_error) => undefined
92 );
34 } 93 }
94
35 } as any 95 } as any
36 }; 96 };
37 97
38 const res = new lc.LanguageClient( 98 const client = new lc.LanguageClient(
39 'rust-analyzer', 99 'rust-analyzer',
40 'Rust Analyzer Language Server', 100 'Rust Analyzer Language Server',
41 serverOptions, 101 serverOptions,
42 clientOptions, 102 clientOptions,
43 ); 103 );
44 104
45 // To turn on all proposed features use: res.registerProposedFeatures(); 105 // To turn on all proposed features use: client.registerProposedFeatures();
46 // Here we want to enable CallHierarchyFeature and SemanticTokensFeature 106 // Here we want to enable CallHierarchyFeature and SemanticTokensFeature
47 // since they are available on stable. 107 // since they are available on stable.
48 // Note that while these features are stable in vscode their LSP protocol 108 // Note that while these features are stable in vscode their LSP protocol
49 // implementations are still in the "proposed" category for 3.16. 109 // implementations are still in the "proposed" category for 3.16.
50 res.registerFeature(new CallHierarchyFeature(res)); 110 client.registerFeature(new CallHierarchyFeature(client));
51 res.registerFeature(new SemanticTokensFeature(res)); 111 client.registerFeature(new SemanticTokensFeature(client));
112 client.registerFeature(new ExperimentalFeatures());
113
114 return client;
115}
116
117class ExperimentalFeatures implements lc.StaticFeature {
118 fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
119 const caps: any = capabilities.experimental ?? {};
120 caps.snippetTextEdit = true;
121 caps.codeActionGroup = true;
122 capabilities.experimental = caps;
123 }
124 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
125 }
126}
127
128function isSnippetEdit(action: lc.CodeAction): boolean {
129 const documentChanges = action.edit?.documentChanges ?? [];
130 for (const edit of documentChanges) {
131 if (lc.TextDocumentEdit.is(edit)) {
132 if (edit.edits.some((indel) => (indel as any).insertTextFormat === lc.InsertTextFormat.Snippet)) {
133 return true;
134 }
135 }
136 }
137 return false;
138}
52 139
53 return res; 140function actionGroup(action: lc.CodeAction): string | undefined {
141 return (action as any).group;
54} 142}
diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts
deleted file mode 100644
index 5b9327b28..000000000
--- a/editors/code/src/color_theme.ts
+++ /dev/null
@@ -1,129 +0,0 @@
1import * as fs from 'fs';
2import * as jsonc from 'jsonc-parser';
3import * as path from 'path';
4import * as vscode from 'vscode';
5
6export interface TextMateRuleSettings {
7 foreground?: string;
8 background?: string;
9 fontStyle?: string;
10}
11
12export class ColorTheme {
13 private rules: Map<string, TextMateRuleSettings> = new Map();
14
15 static load(): ColorTheme {
16 // Find out current color theme
17 const themeName = vscode.workspace
18 .getConfiguration('workbench')
19 .get('colorTheme');
20
21 if (typeof themeName !== 'string') {
22 // console.warn('workbench.colorTheme is', themeName)
23 return new ColorTheme();
24 }
25 return loadThemeNamed(themeName);
26 }
27
28 static fromRules(rules: TextMateRule[]): ColorTheme {
29 const res = new ColorTheme();
30 for (const rule of rules) {
31 const scopes = typeof rule.scope === 'undefined'
32 ? []
33 : typeof rule.scope === 'string'
34 ? [rule.scope]
35 : rule.scope;
36
37 for (const scope of scopes) {
38 res.rules.set(scope, rule.settings);
39 }
40 }
41 return res;
42 }
43
44 lookup(scopes: string[]): TextMateRuleSettings {
45 let res: TextMateRuleSettings = {};
46 for (const scope of scopes) {
47 this.rules.forEach((value, key) => {
48 if (scope.startsWith(key)) {
49 res = mergeRuleSettings(res, value);
50 }
51 });
52 }
53 return res;
54 }
55
56 mergeFrom(other: ColorTheme) {
57 other.rules.forEach((value, key) => {
58 const merged = mergeRuleSettings(this.rules.get(key), value);
59 this.rules.set(key, merged);
60 });
61 }
62}
63
64function loadThemeNamed(themeName: string): ColorTheme {
65 function isTheme(extension: vscode.Extension<unknown>): boolean {
66 return (
67 extension.extensionKind === vscode.ExtensionKind.UI &&
68 extension.packageJSON.contributes &&
69 extension.packageJSON.contributes.themes
70 );
71 }
72
73 const themePaths: string[] = vscode.extensions.all
74 .filter(isTheme)
75 .flatMap(
76 ext => ext.packageJSON.contributes.themes
77 .filter((it: any) => (it.id || it.label) === themeName)
78 .map((it: any) => path.join(ext.extensionPath, it.path))
79 );
80
81 const res = new ColorTheme();
82 for (const themePath of themePaths) {
83 res.mergeFrom(loadThemeFile(themePath));
84 }
85
86 const globalCustomizations: any = vscode.workspace.getConfiguration('editor').get('tokenColorCustomizations');
87 res.mergeFrom(ColorTheme.fromRules(globalCustomizations?.textMateRules ?? []));
88
89 const themeCustomizations: any = vscode.workspace.getConfiguration('editor.tokenColorCustomizations').get(`[${themeName}]`);
90 res.mergeFrom(ColorTheme.fromRules(themeCustomizations?.textMateRules ?? []));
91
92
93 return res;
94}
95
96function loadThemeFile(themePath: string): ColorTheme {
97 let text;
98 try {
99 text = fs.readFileSync(themePath, 'utf8');
100 } catch {
101 return new ColorTheme();
102 }
103 const obj = jsonc.parse(text);
104 const tokenColors: TextMateRule[] = obj?.tokenColors ?? [];
105 const res = ColorTheme.fromRules(tokenColors);
106
107 for (const include of obj?.include ?? []) {
108 const includePath = path.join(path.dirname(themePath), include);
109 res.mergeFrom(loadThemeFile(includePath));
110 }
111
112 return res;
113}
114
115interface TextMateRule {
116 scope: string | string[];
117 settings: TextMateRuleSettings;
118}
119
120function mergeRuleSettings(
121 defaultSetting: TextMateRuleSettings | undefined,
122 override: TextMateRuleSettings,
123): TextMateRuleSettings {
124 return {
125 foreground: override.foreground ?? defaultSetting?.foreground,
126 background: override.background ?? defaultSetting?.background,
127 fontStyle: override.fontStyle ?? defaultSetting?.fontStyle,
128 };
129}
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
new file mode 100644
index 000000000..534d2a984
--- /dev/null
+++ b/editors/code/src/commands.ts
@@ -0,0 +1,416 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3import * as ra from './lsp_ext';
4
5import { Ctx, Cmd } from './ctx';
6import { applySnippetWorkspaceEdit, applySnippetTextEdits } from './snippets';
7import { spawnSync } from 'child_process';
8import { RunnableQuickPick, selectRunnable, createTask } from './run';
9import { AstInspector } from './ast_inspector';
10import { isRustDocument, sleep, isRustEditor } from './util';
11import { startDebugSession, makeDebugConfig } from './debug';
12
13export * from './ast_inspector';
14export * from './run';
15
16export function analyzerStatus(ctx: Ctx): Cmd {
17 const tdcp = new class implements vscode.TextDocumentContentProvider {
18 readonly uri = vscode.Uri.parse('rust-analyzer-status://status');
19 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
20
21 provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
22 if (!vscode.window.activeTextEditor) return '';
23
24 return ctx.client.sendRequest(ra.analyzerStatus, null);
25 }
26
27 get onDidChange(): vscode.Event<vscode.Uri> {
28 return this.eventEmitter.event;
29 }
30 }();
31
32 let poller: NodeJS.Timer | undefined = undefined;
33
34 ctx.pushCleanup(
35 vscode.workspace.registerTextDocumentContentProvider(
36 'rust-analyzer-status',
37 tdcp,
38 ),
39 );
40
41 ctx.pushCleanup({
42 dispose() {
43 if (poller !== undefined) {
44 clearInterval(poller);
45 }
46 },
47 });
48
49 return async () => {
50 if (poller === undefined) {
51 poller = setInterval(() => tdcp.eventEmitter.fire(tdcp.uri), 1000);
52 }
53 const document = await vscode.workspace.openTextDocument(tdcp.uri);
54 return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true);
55 };
56}
57
58export function matchingBrace(ctx: Ctx): Cmd {
59 return async () => {
60 const editor = ctx.activeRustEditor;
61 const client = ctx.client;
62 if (!editor || !client) return;
63
64 const response = await client.sendRequest(ra.matchingBrace, {
65 textDocument: { uri: editor.document.uri.toString() },
66 positions: editor.selections.map(s =>
67 client.code2ProtocolConverter.asPosition(s.active),
68 ),
69 });
70 editor.selections = editor.selections.map((sel, idx) => {
71 const active = client.protocol2CodeConverter.asPosition(
72 response[idx],
73 );
74 const anchor = sel.isEmpty ? active : sel.anchor;
75 return new vscode.Selection(anchor, active);
76 });
77 editor.revealRange(editor.selection);
78 };
79}
80
81export function joinLines(ctx: Ctx): Cmd {
82 return async () => {
83 const editor = ctx.activeRustEditor;
84 const client = ctx.client;
85 if (!editor || !client) return;
86
87 const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
88 ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
89 textDocument: { uri: editor.document.uri.toString() },
90 });
91 editor.edit((builder) => {
92 client.protocol2CodeConverter.asTextEdits(items).forEach((edit) => {
93 builder.replace(edit.range, edit.newText);
94 });
95 });
96 };
97}
98
99export function onEnter(ctx: Ctx): Cmd {
100 async function handleKeypress() {
101 const editor = ctx.activeRustEditor;
102 const client = ctx.client;
103
104 if (!editor || !client) return false;
105
106 const lcEdits = await client.sendRequest(ra.onEnter, {
107 textDocument: { uri: editor.document.uri.toString() },
108 position: client.code2ProtocolConverter.asPosition(
109 editor.selection.active,
110 ),
111 }).catch(_error => {
112 // client.logFailedRequest(OnEnterRequest.type, error);
113 return null;
114 });
115 if (!lcEdits) return false;
116
117 const edits = client.protocol2CodeConverter.asTextEdits(lcEdits);
118 await applySnippetTextEdits(editor, edits);
119 return true;
120 }
121
122 return async () => {
123 if (await handleKeypress()) return;
124
125 await vscode.commands.executeCommand('default:type', { text: '\n' });
126 };
127}
128
129export function parentModule(ctx: Ctx): Cmd {
130 return async () => {
131 const editor = ctx.activeRustEditor;
132 const client = ctx.client;
133 if (!editor || !client) return;
134
135 const response = await client.sendRequest(ra.parentModule, {
136 textDocument: { uri: editor.document.uri.toString() },
137 position: client.code2ProtocolConverter.asPosition(
138 editor.selection.active,
139 ),
140 });
141 const loc = response[0];
142 if (!loc) return;
143
144 const uri = client.protocol2CodeConverter.asUri(loc.targetUri);
145 const range = client.protocol2CodeConverter.asRange(loc.targetRange);
146
147 const doc = await vscode.workspace.openTextDocument(uri);
148 const e = await vscode.window.showTextDocument(doc);
149 e.selection = new vscode.Selection(range.start, range.start);
150 e.revealRange(range, vscode.TextEditorRevealType.InCenter);
151 };
152}
153
154export function ssr(ctx: Ctx): Cmd {
155 return async () => {
156 const client = ctx.client;
157 if (!client) return;
158
159 const options: vscode.InputBoxOptions = {
160 value: "() ==>> ()",
161 prompt: "Enter request, for example 'Foo($a:expr) ==> Foo::new($a)' ",
162 validateInput: async (x: string) => {
163 try {
164 await client.sendRequest(ra.ssr, { query: x, parseOnly: true });
165 } catch (e) {
166 return e.toString();
167 }
168 return null;
169 }
170 };
171 const request = await vscode.window.showInputBox(options);
172 if (!request) return;
173
174 const edit = await client.sendRequest(ra.ssr, { query: request, parseOnly: false });
175
176 await vscode.workspace.applyEdit(client.protocol2CodeConverter.asWorkspaceEdit(edit));
177 };
178}
179
180export function serverVersion(ctx: Ctx): Cmd {
181 return async () => {
182 const { stdout } = spawnSync(ctx.serverPath, ["--version"], { encoding: "utf8" });
183 const commitHash = stdout.slice(`rust-analyzer `.length).trim();
184 const { releaseTag } = ctx.config.package;
185
186 void vscode.window.showInformationMessage(
187 `rust-analyzer version: ${releaseTag ?? "unreleased"} (${commitHash})`
188 );
189 };
190}
191
192export function toggleInlayHints(ctx: Ctx): Cmd {
193 return async () => {
194 await vscode
195 .workspace
196 .getConfiguration(`${ctx.config.rootSection}.inlayHints`)
197 .update('enable', !ctx.config.inlayHints.enable, vscode.ConfigurationTarget.Workspace);
198 };
199}
200
201// Opens the virtual file that will show the syntax tree
202//
203// The contents of the file come from the `TextDocumentContentProvider`
204export function syntaxTree(ctx: Ctx): Cmd {
205 const tdcp = new class implements vscode.TextDocumentContentProvider {
206 readonly uri = vscode.Uri.parse('rust-analyzer://syntaxtree/tree.rast');
207 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
208 constructor() {
209 vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
210 vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
211 }
212
213 private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
214 if (isRustDocument(event.document)) {
215 // We need to order this after language server updates, but there's no API for that.
216 // Hence, good old sleep().
217 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
218 }
219 }
220 private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
221 if (editor && isRustEditor(editor)) {
222 this.eventEmitter.fire(this.uri);
223 }
224 }
225
226 provideTextDocumentContent(uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
227 const rustEditor = ctx.activeRustEditor;
228 if (!rustEditor) return '';
229
230 // When the range based query is enabled we take the range of the selection
231 const range = uri.query === 'range=true' && !rustEditor.selection.isEmpty
232 ? ctx.client.code2ProtocolConverter.asRange(rustEditor.selection)
233 : null;
234
235 const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range, };
236 return ctx.client.sendRequest(ra.syntaxTree, params, ct);
237 }
238
239 get onDidChange(): vscode.Event<vscode.Uri> {
240 return this.eventEmitter.event;
241 }
242 };
243
244 void new AstInspector(ctx);
245
246 ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
247 ctx.pushCleanup(vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
248 brackets: [["[", ")"]],
249 }));
250
251 return async () => {
252 const editor = vscode.window.activeTextEditor;
253 const rangeEnabled = !!editor && !editor.selection.isEmpty;
254
255 const uri = rangeEnabled
256 ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`)
257 : tdcp.uri;
258
259 const document = await vscode.workspace.openTextDocument(uri);
260
261 tdcp.eventEmitter.fire(uri);
262
263 void await vscode.window.showTextDocument(document, {
264 viewColumn: vscode.ViewColumn.Two,
265 preserveFocus: true
266 });
267 };
268}
269
270
271// Opens the virtual file that will show the syntax tree
272//
273// The contents of the file come from the `TextDocumentContentProvider`
274export function expandMacro(ctx: Ctx): Cmd {
275 function codeFormat(expanded: ra.ExpandedMacro): string {
276 let result = `// Recursive expansion of ${expanded.name}! macro\n`;
277 result += '// ' + '='.repeat(result.length - 3);
278 result += '\n\n';
279 result += expanded.expansion;
280
281 return result;
282 }
283
284 const tdcp = new class implements vscode.TextDocumentContentProvider {
285 uri = vscode.Uri.parse('rust-analyzer://expandMacro/[EXPANSION].rs');
286 eventEmitter = new vscode.EventEmitter<vscode.Uri>();
287 async provideTextDocumentContent(_uri: vscode.Uri): Promise<string> {
288 const editor = vscode.window.activeTextEditor;
289 const client = ctx.client;
290 if (!editor || !client) return '';
291
292 const position = editor.selection.active;
293
294 const expanded = await client.sendRequest(ra.expandMacro, {
295 textDocument: { uri: editor.document.uri.toString() },
296 position,
297 });
298
299 if (expanded == null) return 'Not available';
300
301 return codeFormat(expanded);
302 }
303
304 get onDidChange(): vscode.Event<vscode.Uri> {
305 return this.eventEmitter.event;
306 }
307 }();
308
309 ctx.pushCleanup(
310 vscode.workspace.registerTextDocumentContentProvider(
311 'rust-analyzer',
312 tdcp,
313 ),
314 );
315
316 return async () => {
317 const document = await vscode.workspace.openTextDocument(tdcp.uri);
318 tdcp.eventEmitter.fire(tdcp.uri);
319 return vscode.window.showTextDocument(
320 document,
321 vscode.ViewColumn.Two,
322 true,
323 );
324 };
325}
326
327export function collectGarbage(ctx: Ctx): Cmd {
328 return async () => ctx.client.sendRequest(ra.collectGarbage, null);
329}
330
331export function showReferences(ctx: Ctx): Cmd {
332 return (uri: string, position: lc.Position, locations: lc.Location[]) => {
333 const client = ctx.client;
334 if (client) {
335 vscode.commands.executeCommand(
336 'editor.action.showReferences',
337 vscode.Uri.parse(uri),
338 client.protocol2CodeConverter.asPosition(position),
339 locations.map(client.protocol2CodeConverter.asLocation),
340 );
341 }
342 };
343}
344
345export function applyActionGroup(_ctx: Ctx): Cmd {
346 return async (actions: { label: string; edit: vscode.WorkspaceEdit }[]) => {
347 const selectedAction = await vscode.window.showQuickPick(actions);
348 if (!selectedAction) return;
349 await applySnippetWorkspaceEdit(selectedAction.edit);
350 };
351}
352
353export function applySnippetWorkspaceEditCommand(_ctx: Ctx): Cmd {
354 return async (edit: vscode.WorkspaceEdit) => {
355 await applySnippetWorkspaceEdit(edit);
356 };
357}
358
359export function run(ctx: Ctx): Cmd {
360 let prevRunnable: RunnableQuickPick | undefined;
361
362 return async () => {
363 const item = await selectRunnable(ctx, prevRunnable);
364 if (!item) return;
365
366 item.detail = 'rerun';
367 prevRunnable = item;
368 const task = createTask(item.runnable);
369 return await vscode.tasks.executeTask(task);
370 };
371}
372
373export function runSingle(ctx: Ctx): Cmd {
374 return async (runnable: ra.Runnable) => {
375 const editor = ctx.activeRustEditor;
376 if (!editor) return;
377
378 const task = createTask(runnable);
379 task.group = vscode.TaskGroup.Build;
380 task.presentationOptions = {
381 reveal: vscode.TaskRevealKind.Always,
382 panel: vscode.TaskPanelKind.Dedicated,
383 clear: true,
384 };
385
386 return vscode.tasks.executeTask(task);
387 };
388}
389
390export function debug(ctx: Ctx): Cmd {
391 let prevDebuggee: RunnableQuickPick | undefined;
392
393 return async () => {
394 const item = await selectRunnable(ctx, prevDebuggee, true);
395 if (!item) return;
396
397 item.detail = 'restart';
398 prevDebuggee = item;
399 return await startDebugSession(ctx, item.runnable);
400 };
401}
402
403export function debugSingle(ctx: Ctx): Cmd {
404 return async (config: ra.Runnable) => {
405 await startDebugSession(ctx, config);
406 };
407}
408
409export function newDebugConfig(ctx: Ctx): Cmd {
410 return async () => {
411 const item = await selectRunnable(ctx, undefined, true, false);
412 if (!item) return;
413
414 await makeDebugConfig(ctx, item.runnable);
415 };
416}
diff --git a/editors/code/src/commands/analyzer_status.ts b/editors/code/src/commands/analyzer_status.ts
deleted file mode 100644
index 09daa3402..000000000
--- a/editors/code/src/commands/analyzer_status.ts
+++ /dev/null
@@ -1,51 +0,0 @@
1import * as vscode from 'vscode';
2
3import * as ra from '../rust-analyzer-api';
4import { Ctx, Cmd } from '../ctx';
5
6// Shows status of rust-analyzer (for debugging)
7export function analyzerStatus(ctx: Ctx): Cmd {
8 let poller: NodeJS.Timer | undefined = undefined;
9 const tdcp = new TextDocumentContentProvider(ctx);
10
11 ctx.pushCleanup(
12 vscode.workspace.registerTextDocumentContentProvider(
13 'rust-analyzer-status',
14 tdcp,
15 ),
16 );
17
18 ctx.pushCleanup({
19 dispose() {
20 if (poller !== undefined) {
21 clearInterval(poller);
22 }
23 },
24 });
25
26 return async () => {
27 if (poller === undefined) {
28 poller = setInterval(() => tdcp.eventEmitter.fire(tdcp.uri), 1000);
29 }
30 const document = await vscode.workspace.openTextDocument(tdcp.uri);
31 return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true);
32 };
33}
34
35class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
36 readonly uri = vscode.Uri.parse('rust-analyzer-status://status');
37 readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
38
39 constructor(private readonly ctx: Ctx) {
40 }
41
42 provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
43 if (!vscode.window.activeTextEditor) return '';
44
45 return this.ctx.client.sendRequest(ra.analyzerStatus, null);
46 }
47
48 get onDidChange(): vscode.Event<vscode.Uri> {
49 return this.eventEmitter.event;
50 }
51}
diff --git a/editors/code/src/commands/expand_macro.ts b/editors/code/src/commands/expand_macro.ts
deleted file mode 100644
index 23f2ef1d5..000000000
--- a/editors/code/src/commands/expand_macro.ts
+++ /dev/null
@@ -1,66 +0,0 @@
1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { Ctx, Cmd } from '../ctx';
5
6// Opens the virtual file that will show the syntax tree
7//
8// The contents of the file come from the `TextDocumentContentProvider`
9export function expandMacro(ctx: Ctx): Cmd {
10 const tdcp = new TextDocumentContentProvider(ctx);
11 ctx.pushCleanup(
12 vscode.workspace.registerTextDocumentContentProvider(
13 'rust-analyzer',
14 tdcp,
15 ),
16 );
17
18 return async () => {
19 const document = await vscode.workspace.openTextDocument(tdcp.uri);
20 tdcp.eventEmitter.fire(tdcp.uri);
21 return vscode.window.showTextDocument(
22 document,
23 vscode.ViewColumn.Two,
24 true,
25 );
26 };
27}
28
29function codeFormat(expanded: ra.ExpandedMacro): string {
30 let result = `// Recursive expansion of ${expanded.name}! macro\n`;
31 result += '// ' + '='.repeat(result.length - 3);
32 result += '\n\n';
33 result += expanded.expansion;
34
35 return result;
36}
37
38class TextDocumentContentProvider
39 implements vscode.TextDocumentContentProvider {
40 uri = vscode.Uri.parse('rust-analyzer://expandMacro/[EXPANSION].rs');
41 eventEmitter = new vscode.EventEmitter<vscode.Uri>();
42
43 constructor(private readonly ctx: Ctx) {
44 }
45
46 async provideTextDocumentContent(_uri: vscode.Uri): Promise<string> {
47 const editor = vscode.window.activeTextEditor;
48 const client = this.ctx.client;
49 if (!editor || !client) return '';
50
51 const position = editor.selection.active;
52
53 const expanded = await client.sendRequest(ra.expandMacro, {
54 textDocument: { uri: editor.document.uri.toString() },
55 position,
56 });
57
58 if (expanded == null) return 'Not available';
59
60 return codeFormat(expanded);
61 }
62
63 get onDidChange(): vscode.Event<vscode.Uri> {
64 return this.eventEmitter.event;
65 }
66}
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts
deleted file mode 100644
index bdb7fc3b0..000000000
--- a/editors/code/src/commands/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3import * as ra from '../rust-analyzer-api';
4
5import { Ctx, Cmd } from '../ctx';
6import * as sourceChange from '../source_change';
7
8export * from './analyzer_status';
9export * from './matching_brace';
10export * from './join_lines';
11export * from './on_enter';
12export * from './parent_module';
13export * from './syntax_tree';
14export * from './expand_macro';
15export * from './runnables';
16export * from './ssr';
17export * from './server_version';
18
19export function collectGarbage(ctx: Ctx): Cmd {
20 return async () => ctx.client.sendRequest(ra.collectGarbage, null);
21}
22
23export function showReferences(ctx: Ctx): Cmd {
24 return (uri: string, position: lc.Position, locations: lc.Location[]) => {
25 const client = ctx.client;
26 if (client) {
27 vscode.commands.executeCommand(
28 'editor.action.showReferences',
29 vscode.Uri.parse(uri),
30 client.protocol2CodeConverter.asPosition(position),
31 locations.map(client.protocol2CodeConverter.asLocation),
32 );
33 }
34 };
35}
36
37export function applySourceChange(ctx: Ctx): Cmd {
38 return async (change: ra.SourceChange) => {
39 await sourceChange.applySourceChange(ctx, change);
40 };
41}
42
43export function selectAndApplySourceChange(ctx: Ctx): Cmd {
44 return async (changes: ra.SourceChange[]) => {
45 if (changes.length === 1) {
46 await sourceChange.applySourceChange(ctx, changes[0]);
47 } else if (changes.length > 0) {
48 const selectedChange = await vscode.window.showQuickPick(changes);
49 if (!selectedChange) return;
50 await sourceChange.applySourceChange(ctx, selectedChange);
51 }
52 };
53}
diff --git a/editors/code/src/commands/join_lines.ts b/editors/code/src/commands/join_lines.ts
deleted file mode 100644
index de0614653..000000000
--- a/editors/code/src/commands/join_lines.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1import * as ra from '../rust-analyzer-api';
2
3import { Ctx, Cmd } from '../ctx';
4import { applySourceChange } from '../source_change';
5
6export function joinLines(ctx: Ctx): Cmd {
7 return async () => {
8 const editor = ctx.activeRustEditor;
9 const client = ctx.client;
10 if (!editor || !client) return;
11
12 const change = await client.sendRequest(ra.joinLines, {
13 range: client.code2ProtocolConverter.asRange(editor.selection),
14 textDocument: { uri: editor.document.uri.toString() },
15 });
16 await applySourceChange(ctx, change);
17 };
18}
diff --git a/editors/code/src/commands/matching_brace.ts b/editors/code/src/commands/matching_brace.ts
deleted file mode 100644
index a60776e2d..000000000
--- a/editors/code/src/commands/matching_brace.ts
+++ /dev/null
@@ -1,27 +0,0 @@
1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { Ctx, Cmd } from '../ctx';
5
6export function matchingBrace(ctx: Ctx): Cmd {
7 return async () => {
8 const editor = ctx.activeRustEditor;
9 const client = ctx.client;
10 if (!editor || !client) return;
11
12 const response = await client.sendRequest(ra.findMatchingBrace, {
13 textDocument: { uri: editor.document.uri.toString() },
14 offsets: editor.selections.map(s =>
15 client.code2ProtocolConverter.asPosition(s.active),
16 ),
17 });
18 editor.selections = editor.selections.map((sel, idx) => {
19 const active = client.protocol2CodeConverter.asPosition(
20 response[idx],
21 );
22 const anchor = sel.isEmpty ? active : sel.anchor;
23 return new vscode.Selection(anchor, active);
24 });
25 editor.revealRange(editor.selection);
26 };
27}
diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts
deleted file mode 100644
index 285849db7..000000000
--- a/editors/code/src/commands/on_enter.ts
+++ /dev/null
@@ -1,34 +0,0 @@
1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { applySourceChange } from '../source_change';
5import { Cmd, Ctx } from '../ctx';
6
7async function handleKeypress(ctx: Ctx) {
8 const editor = ctx.activeRustEditor;
9 const client = ctx.client;
10
11 if (!editor || !client) return false;
12
13 const change = await client.sendRequest(ra.onEnter, {
14 textDocument: { uri: editor.document.uri.toString() },
15 position: client.code2ProtocolConverter.asPosition(
16 editor.selection.active,
17 ),
18 }).catch(_error => {
19 // client.logFailedRequest(OnEnterRequest.type, error);
20 return null;
21 });
22 if (!change) return false;
23
24 await applySourceChange(ctx, change);
25 return true;
26}
27
28export function onEnter(ctx: Ctx): Cmd {
29 return async () => {
30 if (await handleKeypress(ctx)) return;
31
32 await vscode.commands.executeCommand('default:type', { text: '\n' });
33 };
34}
diff --git a/editors/code/src/commands/parent_module.ts b/editors/code/src/commands/parent_module.ts
deleted file mode 100644
index 8f78ddd71..000000000
--- a/editors/code/src/commands/parent_module.ts
+++ /dev/null
@@ -1,29 +0,0 @@
1import * as vscode from 'vscode';
2import * as ra from '../rust-analyzer-api';
3
4import { Ctx, Cmd } from '../ctx';
5
6export function parentModule(ctx: Ctx): Cmd {
7 return async () => {
8 const editor = ctx.activeRustEditor;
9 const client = ctx.client;
10 if (!editor || !client) return;
11
12 const response = await client.sendRequest(ra.parentModule, {
13 textDocument: { uri: editor.document.uri.toString() },
14 position: client.code2ProtocolConverter.asPosition(
15 editor.selection.active,
16 ),
17 });
18 const loc = response[0];
19 if (loc == null) return;
20
21 const uri = client.protocol2CodeConverter.asUri(loc.uri);
22 const range = client.protocol2CodeConverter.asRange(loc.range);
23
24 const doc = await vscode.workspace.openTextDocument(uri);
25 const e = await vscode.window.showTextDocument(doc);
26 e.selection = new vscode.Selection(range.start, range.start);
27 e.revealRange(range, vscode.TextEditorRevealType.InCenter);
28 };
29}
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts
deleted file mode 100644
index d77e8188c..000000000
--- a/editors/code/src/commands/runnables.ts
+++ /dev/null
@@ -1,185 +0,0 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3import * as ra from '../rust-analyzer-api';
4import * as os from "os";
5
6import { Ctx, Cmd } from '../ctx';
7import { Cargo } from '../cargo';
8
9export function run(ctx: Ctx): Cmd {
10 let prevRunnable: RunnableQuickPick | undefined;
11
12 return async () => {
13 const editor = ctx.activeRustEditor;
14 const client = ctx.client;
15 if (!editor || !client) return;
16
17 const textDocument: lc.TextDocumentIdentifier = {
18 uri: editor.document.uri.toString(),
19 };
20
21 const runnables = await client.sendRequest(ra.runnables, {
22 textDocument,
23 position: client.code2ProtocolConverter.asPosition(
24 editor.selection.active,
25 ),
26 });
27 const items: RunnableQuickPick[] = [];
28 if (prevRunnable) {
29 items.push(prevRunnable);
30 }
31 for (const r of runnables) {
32 if (
33 prevRunnable &&
34 JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
35 ) {
36 continue;
37 }
38 items.push(new RunnableQuickPick(r));
39 }
40 const item = await vscode.window.showQuickPick(items);
41 if (!item) return;
42
43 item.detail = 'rerun';
44 prevRunnable = item;
45 const task = createTask(item.runnable);
46 return await vscode.tasks.executeTask(task);
47 };
48}
49
50export function runSingle(ctx: Ctx): Cmd {
51 return async (runnable: ra.Runnable) => {
52 const editor = ctx.activeRustEditor;
53 if (!editor) return;
54
55 const task = createTask(runnable);
56 task.group = vscode.TaskGroup.Build;
57 task.presentationOptions = {
58 reveal: vscode.TaskRevealKind.Always,
59 panel: vscode.TaskPanelKind.Dedicated,
60 clear: true,
61 };
62
63 return vscode.tasks.executeTask(task);
64 };
65}
66
67function getLldbDebugConfig(config: ra.Runnable, sourceFileMap: Record<string, string>): vscode.DebugConfiguration {
68 return {
69 type: "lldb",
70 request: "launch",
71 name: config.label,
72 cargo: {
73 args: config.args,
74 },
75 args: config.extraArgs,
76 cwd: config.cwd,
77 sourceMap: sourceFileMap
78 };
79}
80
81const debugOutput = vscode.window.createOutputChannel("Debug");
82
83async function getCppvsDebugConfig(config: ra.Runnable, sourceFileMap: Record<string, string>): Promise<vscode.DebugConfiguration> {
84 debugOutput.clear();
85
86 const cargo = new Cargo(config.cwd || '.', debugOutput);
87 const executable = await cargo.executableFromArgs(config.args);
88
89 // if we are here, there were no compilation errors.
90 return {
91 type: (os.platform() === "win32") ? "cppvsdbg" : 'cppdbg',
92 request: "launch",
93 name: config.label,
94 program: executable,
95 args: config.extraArgs,
96 cwd: config.cwd,
97 sourceFileMap: sourceFileMap,
98 };
99}
100
101export function debugSingle(ctx: Ctx): Cmd {
102 return async (config: ra.Runnable) => {
103 const editor = ctx.activeRustEditor;
104 if (!editor) return;
105
106 const lldbId = "vadimcn.vscode-lldb";
107 const cpptoolsId = "ms-vscode.cpptools";
108
109 const debugEngineId = ctx.config.debug.engine;
110 let debugEngine = null;
111 if (debugEngineId === "auto") {
112 debugEngine = vscode.extensions.getExtension(lldbId);
113 if (!debugEngine) {
114 debugEngine = vscode.extensions.getExtension(cpptoolsId);
115 }
116 }
117 else {
118 debugEngine = vscode.extensions.getExtension(debugEngineId);
119 }
120
121 if (!debugEngine) {
122 vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=${lldbId})`
123 + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=${cpptoolsId}) extension for debugging.`);
124 return;
125 }
126
127 const debugConfig = lldbId === debugEngine.id
128 ? getLldbDebugConfig(config, ctx.config.debug.sourceFileMap)
129 : await getCppvsDebugConfig(config, ctx.config.debug.sourceFileMap);
130
131 return vscode.debug.startDebugging(undefined, debugConfig);
132 };
133}
134
135class RunnableQuickPick implements vscode.QuickPickItem {
136 public label: string;
137 public description?: string | undefined;
138 public detail?: string | undefined;
139 public picked?: boolean | undefined;
140
141 constructor(public runnable: ra.Runnable) {
142 this.label = runnable.label;
143 }
144}
145
146interface CargoTaskDefinition extends vscode.TaskDefinition {
147 type: 'cargo';
148 label: string;
149 command: string;
150 args: string[];
151 env?: { [key: string]: string };
152}
153
154function createTask(spec: ra.Runnable): vscode.Task {
155 const TASK_SOURCE = 'Rust';
156 const definition: CargoTaskDefinition = {
157 type: 'cargo',
158 label: spec.label,
159 command: spec.bin,
160 args: spec.extraArgs ? [...spec.args, '--', ...spec.extraArgs] : spec.args,
161 env: spec.env,
162 };
163
164 const execOption: vscode.ShellExecutionOptions = {
165 cwd: spec.cwd || '.',
166 env: definition.env,
167 };
168 const exec = new vscode.ShellExecution(
169 definition.command,
170 definition.args,
171 execOption,
172 );
173
174 const f = vscode.workspace.workspaceFolders![0];
175 const t = new vscode.Task(
176 definition,
177 f,
178 definition.label,
179 TASK_SOURCE,
180 exec,
181 ['$rustc'],
182 );
183 t.presentationOptions.clear = true;
184 return t;
185}
diff --git a/editors/code/src/commands/server_version.ts b/editors/code/src/commands/server_version.ts
deleted file mode 100644
index d64ac726e..000000000
--- a/editors/code/src/commands/server_version.ts
+++ /dev/null
@@ -1,15 +0,0 @@
1import * as vscode from "vscode";
2import { spawnSync } from "child_process";
3import { Ctx, Cmd } from '../ctx';
4
5export function serverVersion(ctx: Ctx): Cmd {
6 return async () => {
7 const { stdout } = spawnSync(ctx.serverPath, ["--version"], { encoding: "utf8" });
8 const commitHash = stdout.slice(`rust-analyzer `.length).trim();
9 const { releaseTag } = ctx.config.package;
10
11 void vscode.window.showInformationMessage(
12 `rust-analyzer version: ${releaseTag ?? "unreleased"} (${commitHash})`
13 );
14 };
15}
diff --git a/editors/code/src/commands/ssr.ts b/editors/code/src/commands/ssr.ts
deleted file mode 100644
index 6fee051fd..000000000
--- a/editors/code/src/commands/ssr.ts
+++ /dev/null
@@ -1,32 +0,0 @@
1import * as vscode from 'vscode';
2import * as ra from "../rust-analyzer-api";
3
4import { Ctx, Cmd } from '../ctx';
5import { applySourceChange } from '../source_change';
6
7export function ssr(ctx: Ctx): Cmd {
8 return async () => {
9 const client = ctx.client;
10 if (!client) return;
11
12 const options: vscode.InputBoxOptions = {
13 value: "() ==>> ()",
14 prompt: "EnteR request, for example 'Foo($a:expr) ==> Foo::new($a)' ",
15 validateInput: async (x: string) => {
16 try {
17 await client.sendRequest(ra.ssr, { query: x, parseOnly: true });
18 } catch (e) {
19 return e.toString();
20 }
21 return null;
22 }
23 };
24 const request = await vscode.window.showInputBox(options);
25
26 if (!request) return;
27
28 const change = await client.sendRequest(ra.ssr, { query: request, parseOnly: false });
29
30 await applySourceChange(ctx, change);
31 };
32}
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 110e54180..e8abf8284 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -8,7 +8,7 @@ export const NIGHTLY_TAG = "nightly";
8export class Config { 8export class Config {
9 readonly extensionId = "matklad.rust-analyzer"; 9 readonly extensionId = "matklad.rust-analyzer";
10 10
11 private readonly rootSection = "rust-analyzer"; 11 readonly rootSection = "rust-analyzer";
12 private readonly requiresReloadOpts = [ 12 private readonly requiresReloadOpts = [
13 "serverPath", 13 "serverPath",
14 "cargo", 14 "cargo",
@@ -16,6 +16,10 @@ export class Config {
16 "files", 16 "files",
17 "highlighting", 17 "highlighting",
18 "updates.channel", 18 "updates.channel",
19 "lens.enable",
20 "lens.run",
21 "lens.debug",
22 "lens.implementations",
19 ] 23 ]
20 .map(opt => `${this.rootSection}.${opt}`); 24 .map(opt => `${this.rootSection}.${opt}`);
21 25
@@ -94,6 +98,7 @@ export class Config {
94 98
95 get inlayHints() { 99 get inlayHints() {
96 return { 100 return {
101 enable: this.get<boolean>("inlayHints.enable"),
97 typeHints: this.get<boolean>("inlayHints.typeHints"), 102 typeHints: this.get<boolean>("inlayHints.typeHints"),
98 parameterHints: this.get<boolean>("inlayHints.parameterHints"), 103 parameterHints: this.get<boolean>("inlayHints.parameterHints"),
99 chainingHints: this.get<boolean>("inlayHints.chainingHints"), 104 chainingHints: this.get<boolean>("inlayHints.chainingHints"),
@@ -108,10 +113,23 @@ export class Config {
108 } 113 }
109 114
110 get debug() { 115 get debug() {
116 // "/rustc/<id>" used by suggestions only.
117 const { ["/rustc/<id>"]: _, ...sourceFileMap } = this.get<Record<string, string>>("debug.sourceFileMap");
118
111 return { 119 return {
112 engine: this.get<string>("debug.engine"), 120 engine: this.get<string>("debug.engine"),
113 sourceFileMap: this.get<Record<string, string>>("debug.sourceFileMap"), 121 engineSettings: this.get<object>("debug.engineSettings"),
122 openUpDebugPane: this.get<boolean>("debug.openUpDebugPane"),
123 sourceFileMap: sourceFileMap
114 }; 124 };
115 } 125 }
116 126
127 get lens() {
128 return {
129 enable: this.get<boolean>("lens.enable"),
130 run: this.get<boolean>("lens.run"),
131 debug: this.get<boolean>("lens.debug"),
132 implementations: this.get<boolean>("lens.implementations"),
133 };
134 }
117} 135}
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
new file mode 100644
index 000000000..a0c9b3ab2
--- /dev/null
+++ b/editors/code/src/debug.ts
@@ -0,0 +1,147 @@
1import * as os from "os";
2import * as vscode from 'vscode';
3import * as path from 'path';
4import * as ra from './lsp_ext';
5
6import { Cargo } from './toolchain';
7import { Ctx } from "./ctx";
8
9const debugOutput = vscode.window.createOutputChannel("Debug");
10type DebugConfigProvider = (config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>) => vscode.DebugConfiguration;
11
12export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<void> {
13 const scope = ctx.activeRustEditor?.document.uri;
14 if (!scope) return;
15
16 const debugConfig = await getDebugConfiguration(ctx, runnable);
17 if (!debugConfig) return;
18
19 const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope);
20 const configurations = wsLaunchSection.get<any[]>("configurations") || [];
21
22 const index = configurations.findIndex(c => c.name === debugConfig.name);
23 if (index !== -1) {
24 const answer = await vscode.window.showErrorMessage(`Launch configuration '${debugConfig.name}' already exists!`, 'Cancel', 'Update');
25 if (answer === "Cancel") return;
26
27 configurations[index] = debugConfig;
28 } else {
29 configurations.push(debugConfig);
30 }
31
32 await wsLaunchSection.update("configurations", configurations);
33}
34
35export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promise<boolean> {
36 let debugConfig: vscode.DebugConfiguration | undefined = undefined;
37 let message = "";
38
39 const wsLaunchSection = vscode.workspace.getConfiguration("launch");
40 const configurations = wsLaunchSection.get<any[]>("configurations") || [];
41
42 const index = configurations.findIndex(c => c.name === runnable.label);
43 if (-1 !== index) {
44 debugConfig = configurations[index];
45 message = " (from launch.json)";
46 debugOutput.clear();
47 } else {
48 debugConfig = await getDebugConfiguration(ctx, runnable);
49 }
50
51 if (!debugConfig) return false;
52
53 debugOutput.appendLine(`Launching debug configuration${message}:`);
54 debugOutput.appendLine(JSON.stringify(debugConfig, null, 2));
55 return vscode.debug.startDebugging(undefined, debugConfig);
56}
57
58async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<vscode.DebugConfiguration | undefined> {
59 const editor = ctx.activeRustEditor;
60 if (!editor) return;
61
62 const knownEngines: Record<string, DebugConfigProvider> = {
63 "vadimcn.vscode-lldb": getLldbDebugConfig,
64 "ms-vscode.cpptools": getCppvsDebugConfig
65 };
66 const debugOptions = ctx.config.debug;
67
68 let debugEngine = null;
69 if (debugOptions.engine === "auto") {
70 for (var engineId in knownEngines) {
71 debugEngine = vscode.extensions.getExtension(engineId);
72 if (debugEngine) break;
73 }
74 } else {
75 debugEngine = vscode.extensions.getExtension(debugOptions.engine);
76 }
77
78 if (!debugEngine) {
79 vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
80 + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
81 return;
82 }
83
84 debugOutput.clear();
85 if (ctx.config.debug.openUpDebugPane) {
86 debugOutput.show(true);
87 }
88
89 const wsFolder = path.normalize(vscode.workspace.workspaceFolders![0].uri.fsPath); // folder exists or RA is not active.
90 function simplifyPath(p: string): string {
91 return path.normalize(p).replace(wsFolder, '${workspaceRoot}');
92 }
93
94 const executable = await getDebugExecutable(runnable);
95 const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), debugOptions.sourceFileMap);
96 if (debugConfig.type in debugOptions.engineSettings) {
97 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
98 for (var key in settingsMap) {
99 debugConfig[key] = settingsMap[key];
100 }
101 }
102
103 if (debugConfig.name === "run binary") {
104 // The LSP side: crates\rust-analyzer\src\main_loop\handlers.rs,
105 // fn to_lsp_runnable(...) with RunnableKind::Bin
106 debugConfig.name = `run ${path.basename(executable)}`;
107 }
108
109 if (debugConfig.cwd) {
110 debugConfig.cwd = simplifyPath(debugConfig.cwd);
111 }
112
113 return debugConfig;
114}
115
116async function getDebugExecutable(runnable: ra.Runnable): Promise<string> {
117 const cargo = new Cargo(runnable.args.workspaceRoot || '.', debugOutput);
118 const executable = await cargo.executableFromArgs(runnable.args.cargoArgs);
119
120 // if we are here, there were no compilation errors.
121 return executable;
122}
123
124function getLldbDebugConfig(runnable: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
125 return {
126 type: "lldb",
127 request: "launch",
128 name: runnable.label,
129 program: executable,
130 args: runnable.args.executableArgs,
131 cwd: runnable.args.workspaceRoot,
132 sourceMap: sourceFileMap,
133 sourceLanguages: ["rust"]
134 };
135}
136
137function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
138 return {
139 type: (os.platform() === "win32") ? "cppvsdbg" : "cppdbg",
140 request: "launch",
141 name: runnable.label,
142 program: executable,
143 args: runnable.args.executableArgs,
144 cwd: runnable.args.workspaceRoot,
145 sourceFileMap: sourceFileMap,
146 };
147}
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index a09531797..9e6d6045f 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -1,6 +1,6 @@
1import * as lc from "vscode-languageclient"; 1import * as lc from "vscode-languageclient";
2import * as vscode from 'vscode'; 2import * as vscode from 'vscode';
3import * as ra from './rust-analyzer-api'; 3import * as ra from './lsp_ext';
4 4
5import { Ctx, Disposable } from './ctx'; 5import { Ctx, Disposable } from './ctx';
6import { sendRequestWithRetry, isRustDocument, RustDocument, RustEditor, sleep } from './util'; 6import { sendRequestWithRetry, isRustDocument, RustDocument, RustEditor, sleep } from './util';
@@ -10,13 +10,13 @@ export function activateInlayHints(ctx: Ctx) {
10 const maybeUpdater = { 10 const maybeUpdater = {
11 updater: null as null | HintsUpdater, 11 updater: null as null | HintsUpdater,
12 async onConfigChange() { 12 async onConfigChange() {
13 if ( 13 const anyEnabled = ctx.config.inlayHints.typeHints
14 !ctx.config.inlayHints.typeHints && 14 || ctx.config.inlayHints.parameterHints
15 !ctx.config.inlayHints.parameterHints && 15 || ctx.config.inlayHints.chainingHints;
16 !ctx.config.inlayHints.chainingHints 16 const enabled = ctx.config.inlayHints.enable && anyEnabled;
17 ) { 17
18 return this.dispose(); 18 if (!enabled) return this.dispose();
19 } 19
20 await sleep(100); 20 await sleep(100);
21 if (this.updater) { 21 if (this.updater) {
22 this.updater.syncCacheAndRenderHints(); 22 this.updater.syncCacheAndRenderHints();
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
new file mode 100644
index 000000000..c51acfccb
--- /dev/null
+++ b/editors/code/src/lsp_ext.ts
@@ -0,0 +1,86 @@
1/**
2 * This file mirrors `crates/rust-analyzer/src/req.rs` declarations.
3 */
4
5import * as lc from "vscode-languageclient";
6
7export const analyzerStatus = new lc.RequestType<null, string, void>("rust-analyzer/analyzerStatus");
8
9export const collectGarbage = new lc.RequestType<null, null, void>("rust-analyzer/collectGarbage");
10
11export interface SyntaxTreeParams {
12 textDocument: lc.TextDocumentIdentifier;
13 range: lc.Range | null;
14}
15export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>("rust-analyzer/syntaxTree");
16
17
18export interface ExpandMacroParams {
19 textDocument: lc.TextDocumentIdentifier;
20 position: lc.Position;
21}
22export interface ExpandedMacro {
23 name: string;
24 expansion: string;
25}
26export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro | null, void>("rust-analyzer/expandMacro");
27
28export interface MatchingBraceParams {
29 textDocument: lc.TextDocumentIdentifier;
30 positions: lc.Position[];
31}
32export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position[], void>("experimental/matchingBrace");
33
34export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule");
35
36export interface JoinLinesParams {
37 textDocument: lc.TextDocumentIdentifier;
38 ranges: lc.Range[];
39}
40export const joinLines = new lc.RequestType<JoinLinesParams, lc.TextEdit[], void>("experimental/joinLines");
41
42export const onEnter = new lc.RequestType<lc.TextDocumentPositionParams, lc.TextEdit[], void>("experimental/onEnter");
43
44export interface RunnablesParams {
45 textDocument: lc.TextDocumentIdentifier;
46 position: lc.Position | null;
47}
48
49export interface Runnable {
50 label: string;
51 location?: lc.LocationLink;
52 kind: "cargo";
53 args: {
54 workspaceRoot?: string;
55 cargoArgs: string[];
56 executableArgs: string[];
57 };
58}
59export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>("experimental/runnables");
60
61export type InlayHint = InlayHint.TypeHint | InlayHint.ParamHint | InlayHint.ChainingHint;
62
63export namespace InlayHint {
64 export const enum Kind {
65 TypeHint = "TypeHint",
66 ParamHint = "ParameterHint",
67 ChainingHint = "ChainingHint",
68 }
69 interface Common {
70 range: lc.Range;
71 label: string;
72 }
73 export type TypeHint = Common & { kind: Kind.TypeHint };
74 export type ParamHint = Common & { kind: Kind.ParamHint };
75 export type ChainingHint = Common & { kind: Kind.ChainingHint };
76}
77export interface InlayHintsParams {
78 textDocument: lc.TextDocumentIdentifier;
79}
80export const inlayHints = new lc.RequestType<InlayHintsParams, InlayHint[], void>("rust-analyzer/inlayHints");
81
82export interface SsrParams {
83 query: string;
84 parseOnly: boolean;
85}
86export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>('experimental/ssr');
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index efd56a84b..b7337621c 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -1,21 +1,24 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as path from "path"; 2import * as path from "path";
3import * as os from "os"; 3import * as os from "os";
4import { promises as fs } from "fs"; 4import { promises as fs, PathLike } from "fs";
5 5
6import * as commands from './commands'; 6import * as commands from './commands';
7import { activateInlayHints } from './inlay_hints'; 7import { activateInlayHints } from './inlay_hints';
8import { activateStatusDisplay } from './status_display'; 8import { activateStatusDisplay } from './status_display';
9import { Ctx } from './ctx'; 9import { Ctx } from './ctx';
10import { Config, NIGHTLY_TAG } from './config'; 10import { Config, NIGHTLY_TAG } from './config';
11import { log, assert } from './util'; 11import { log, assert, isValidExecutable } from './util';
12import { PersistentState } from './persistent_state'; 12import { PersistentState } from './persistent_state';
13import { fetchRelease, download } from './net'; 13import { fetchRelease, download } from './net';
14import { spawnSync } from 'child_process';
15import { activateTaskProvider } from './tasks'; 14import { activateTaskProvider } from './tasks';
15import { setContextValue } from './util';
16import { exec } from 'child_process';
16 17
17let ctx: Ctx | undefined; 18let ctx: Ctx | undefined;
18 19
20const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
21
19export async function activate(context: vscode.ExtensionContext) { 22export async function activate(context: vscode.ExtensionContext) {
20 // Register a "dumb" onEnter command for the case where server fails to 23 // Register a "dumb" onEnter command for the case where server fails to
21 // start. 24 // start.
@@ -54,6 +57,8 @@ export async function activate(context: vscode.ExtensionContext) {
54 // This a horribly, horribly wrong way to deal with this problem. 57 // This a horribly, horribly wrong way to deal with this problem.
55 ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); 58 ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath);
56 59
60 setContextValue(RUST_PROJECT_CONTEXT_NAME, true);
61
57 // Commands which invokes manually via command palette, shortcut, etc. 62 // Commands which invokes manually via command palette, shortcut, etc.
58 63
59 // Reloading is inspired by @DanTup maneuver: https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895 64 // Reloading is inspired by @DanTup maneuver: https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895
@@ -78,19 +83,22 @@ export async function activate(context: vscode.ExtensionContext) {
78 ctx.registerCommand('syntaxTree', commands.syntaxTree); 83 ctx.registerCommand('syntaxTree', commands.syntaxTree);
79 ctx.registerCommand('expandMacro', commands.expandMacro); 84 ctx.registerCommand('expandMacro', commands.expandMacro);
80 ctx.registerCommand('run', commands.run); 85 ctx.registerCommand('run', commands.run);
86 ctx.registerCommand('debug', commands.debug);
87 ctx.registerCommand('newDebugConfig', commands.newDebugConfig);
81 88
82 defaultOnEnter.dispose(); 89 defaultOnEnter.dispose();
83 ctx.registerCommand('onEnter', commands.onEnter); 90 ctx.registerCommand('onEnter', commands.onEnter);
84 91
85 ctx.registerCommand('ssr', commands.ssr); 92 ctx.registerCommand('ssr', commands.ssr);
86 ctx.registerCommand('serverVersion', commands.serverVersion); 93 ctx.registerCommand('serverVersion', commands.serverVersion);
94 ctx.registerCommand('toggleInlayHints', commands.toggleInlayHints);
87 95
88 // Internal commands which are invoked by the server. 96 // Internal commands which are invoked by the server.
89 ctx.registerCommand('runSingle', commands.runSingle); 97 ctx.registerCommand('runSingle', commands.runSingle);
90 ctx.registerCommand('debugSingle', commands.debugSingle); 98 ctx.registerCommand('debugSingle', commands.debugSingle);
91 ctx.registerCommand('showReferences', commands.showReferences); 99 ctx.registerCommand('showReferences', commands.showReferences);
92 ctx.registerCommand('applySourceChange', commands.applySourceChange); 100 ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand);
93 ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); 101 ctx.registerCommand('applyActionGroup', commands.applyActionGroup);
94 102
95 ctx.pushCleanup(activateTaskProvider(workspaceFolder)); 103 ctx.pushCleanup(activateTaskProvider(workspaceFolder));
96 104
@@ -106,6 +114,7 @@ export async function activate(context: vscode.ExtensionContext) {
106} 114}
107 115
108export async function deactivate() { 116export async function deactivate() {
117 setContextValue(RUST_PROJECT_CONTEXT_NAME, undefined);
109 await ctx?.client.stop(); 118 await ctx?.client.stop();
110 ctx = undefined; 119 ctx = undefined;
111} 120}
@@ -179,16 +188,53 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise<
179 188
180 log.debug("Using server binary at", path); 189 log.debug("Using server binary at", path);
181 190
182 const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); 191 if (!isValidExecutable(path)) {
183 log.debug("Checked binary availability via --version", res);
184 log.debug(res, "--version output:", res.output);
185 if (res.status !== 0) {
186 throw new Error(`Failed to execute ${path} --version`); 192 throw new Error(`Failed to execute ${path} --version`);
187 } 193 }
188 194
189 return path; 195 return path;
190} 196}
191 197
198async function patchelf(dest: PathLike): Promise<void> {
199 await vscode.window.withProgress(
200 {
201 location: vscode.ProgressLocation.Notification,
202 title: "Patching rust-analyzer for NixOS"
203 },
204 async (progress, _) => {
205 const expression = `
206 {src, pkgs ? import <nixpkgs> {}}:
207 pkgs.stdenv.mkDerivation {
208 name = "rust-analyzer";
209 inherit src;
210 phases = [ "installPhase" "fixupPhase" ];
211 installPhase = "cp $src $out";
212 fixupPhase = ''
213 chmod 755 $out
214 patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out
215 '';
216 }
217 `;
218 const origFile = dest + "-orig";
219 await fs.rename(dest, origFile);
220 progress.report({ message: "Patching executable", increment: 20 });
221 await new Promise((resolve, reject) => {
222 const handle = exec(`nix-build -E - --arg src '${origFile}' -o ${dest}`,
223 (err, stdout, stderr) => {
224 if (err != null) {
225 reject(Error(stderr));
226 } else {
227 resolve(stdout);
228 }
229 });
230 handle.stdin?.write(expression);
231 handle.stdin?.end();
232 });
233 await fs.unlink(origFile);
234 }
235 );
236}
237
192async function getServer(config: Config, state: PersistentState): Promise<string | undefined> { 238async function getServer(config: Config, state: PersistentState): Promise<string | undefined> {
193 const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; 239 const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath;
194 if (explicitPath) { 240 if (explicitPath) {
@@ -238,6 +284,12 @@ async function getServer(config: Config, state: PersistentState): Promise<string
238 assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); 284 assert(!!artifact, `Bad release: ${JSON.stringify(release)}`);
239 285
240 await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); 286 await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 });
287
288 // Patching executable if that's NixOS.
289 if (await fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) {
290 await patchelf(dest);
291 }
292
241 await state.updateServerVersion(config.package.version); 293 await state.updateServerVersion(config.package.version);
242 return dest; 294 return dest;
243} 295}
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts
new file mode 100644
index 000000000..5c790741f
--- /dev/null
+++ b/editors/code/src/run.ts
@@ -0,0 +1,146 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3import * as ra from './lsp_ext';
4import * as toolchain from "./toolchain";
5
6import { Ctx } from './ctx';
7import { makeDebugConfig } from './debug';
8
9const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }];
10
11export async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise<RunnableQuickPick | undefined> {
12 const editor = ctx.activeRustEditor;
13 const client = ctx.client;
14 if (!editor || !client) return;
15
16 const textDocument: lc.TextDocumentIdentifier = {
17 uri: editor.document.uri.toString(),
18 };
19
20 const runnables = await client.sendRequest(ra.runnables, {
21 textDocument,
22 position: client.code2ProtocolConverter.asPosition(
23 editor.selection.active,
24 ),
25 });
26 const items: RunnableQuickPick[] = [];
27 if (prevRunnable) {
28 items.push(prevRunnable);
29 }
30 for (const r of runnables) {
31 if (
32 prevRunnable &&
33 JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
34 ) {
35 continue;
36 }
37
38 if (debuggeeOnly && (r.label.startsWith('doctest') || r.label.startsWith('cargo'))) {
39 continue;
40 }
41 items.push(new RunnableQuickPick(r));
42 }
43
44 if (items.length === 0) {
45 // it is the debug case, run always has at least 'cargo check ...'
46 // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables
47 vscode.window.showErrorMessage("There's no debug target!");
48 return;
49 }
50
51 return await new Promise((resolve) => {
52 const disposables: vscode.Disposable[] = [];
53 const close = (result?: RunnableQuickPick) => {
54 resolve(result);
55 disposables.forEach(d => d.dispose());
56 };
57
58 const quickPick = vscode.window.createQuickPick<RunnableQuickPick>();
59 quickPick.items = items;
60 quickPick.title = "Select Runnable";
61 if (showButtons) {
62 quickPick.buttons = quickPickButtons;
63 }
64 disposables.push(
65 quickPick.onDidHide(() => close()),
66 quickPick.onDidAccept(() => close(quickPick.selectedItems[0])),
67 quickPick.onDidTriggerButton((_button) => {
68 (async () => await makeDebugConfig(ctx, quickPick.activeItems[0].runnable))();
69 close();
70 }),
71 quickPick.onDidChangeActive((active) => {
72 if (showButtons && active.length > 0) {
73 if (active[0].label.startsWith('cargo')) {
74 // save button makes no sense for `cargo test` or `cargo check`
75 quickPick.buttons = [];
76 } else if (quickPick.buttons.length === 0) {
77 quickPick.buttons = quickPickButtons;
78 }
79 }
80 }),
81 quickPick
82 );
83 quickPick.show();
84 });
85}
86
87export class RunnableQuickPick implements vscode.QuickPickItem {
88 public label: string;
89 public description?: string | undefined;
90 public detail?: string | undefined;
91 public picked?: boolean | undefined;
92
93 constructor(public runnable: ra.Runnable) {
94 this.label = runnable.label;
95 }
96}
97
98interface CargoTaskDefinition extends vscode.TaskDefinition {
99 type: 'cargo';
100 label: string;
101 command: string;
102 args: string[];
103 env?: { [key: string]: string };
104}
105
106export function createTask(runnable: ra.Runnable): vscode.Task {
107 const TASK_SOURCE = 'Rust';
108
109 let command;
110 switch (runnable.kind) {
111 case "cargo": command = toolchain.getPathForExecutable("cargo");
112 }
113 const args = runnable.args.cargoArgs;
114 if (runnable.args.executableArgs.length > 0) {
115 args.push('--', ...runnable.args.executableArgs);
116 }
117 const definition: CargoTaskDefinition = {
118 type: 'cargo',
119 label: runnable.label,
120 command,
121 args,
122 env: Object.assign({}, process.env as { [key: string]: string }, { "RUST_BACKTRACE": "short" }),
123 };
124
125 const execOption: vscode.ShellExecutionOptions = {
126 cwd: runnable.args.workspaceRoot || '.',
127 env: definition.env,
128 };
129 const exec = new vscode.ShellExecution(
130 definition.command,
131 definition.args,
132 execOption,
133 );
134
135 const f = vscode.workspace.workspaceFolders![0];
136 const t = new vscode.Task(
137 definition,
138 f,
139 definition.label,
140 TASK_SOURCE,
141 exec,
142 ['$rustc'],
143 );
144 t.presentationOptions.clear = true;
145 return t;
146}
diff --git a/editors/code/src/rust-analyzer-api.ts b/editors/code/src/rust-analyzer-api.ts
deleted file mode 100644
index 400ac3714..000000000
--- a/editors/code/src/rust-analyzer-api.ts
+++ /dev/null
@@ -1,125 +0,0 @@
1/**
2 * This file mirrors `crates/rust-analyzer/src/req.rs` declarations.
3 */
4
5import * as lc from "vscode-languageclient";
6
7type Option<T> = null | T;
8type Vec<T> = T[];
9type FxHashMap<K extends PropertyKey, V> = Record<K, V>;
10
11function request<TParams, TResult>(method: string) {
12 return new lc.RequestType<TParams, TResult, unknown>(`rust-analyzer/${method}`);
13}
14function notification<TParam>(method: string) {
15 return new lc.NotificationType<TParam>(method);
16}
17
18
19export const analyzerStatus = request<null, string>("analyzerStatus");
20
21
22export const collectGarbage = request<null, null>("collectGarbage");
23
24
25export interface SyntaxTreeParams {
26 textDocument: lc.TextDocumentIdentifier;
27 range: Option<lc.Range>;
28}
29export const syntaxTree = request<SyntaxTreeParams, string>("syntaxTree");
30
31
32export interface ExpandMacroParams {
33 textDocument: lc.TextDocumentIdentifier;
34 position: Option<lc.Position>;
35}
36export interface ExpandedMacro {
37 name: string;
38 expansion: string;
39}
40export const expandMacro = request<ExpandMacroParams, Option<ExpandedMacro>>("expandMacro");
41
42
43export interface FindMatchingBraceParams {
44 textDocument: lc.TextDocumentIdentifier;
45 offsets: Vec<lc.Position>;
46}
47export const findMatchingBrace = request<FindMatchingBraceParams, Vec<lc.Position>>("findMatchingBrace");
48
49
50export interface PublishDecorationsParams {
51 uri: string;
52 decorations: Vec<Decoration>;
53}
54export interface Decoration {
55 range: lc.Range;
56 tag: string;
57 bindingHash: Option<string>;
58}
59export const decorationsRequest = request<lc.TextDocumentIdentifier, Vec<Decoration>>("decorationsRequest");
60
61
62export const parentModule = request<lc.TextDocumentPositionParams, Vec<lc.Location>>("parentModule");
63
64
65export interface JoinLinesParams {
66 textDocument: lc.TextDocumentIdentifier;
67 range: lc.Range;
68}
69export const joinLines = request<JoinLinesParams, SourceChange>("joinLines");
70
71
72export const onEnter = request<lc.TextDocumentPositionParams, Option<SourceChange>>("onEnter");
73
74export interface RunnablesParams {
75 textDocument: lc.TextDocumentIdentifier;
76 position: Option<lc.Position>;
77}
78export interface Runnable {
79 range: lc.Range;
80 label: string;
81 bin: string;
82 args: Vec<string>;
83 extraArgs: Vec<string>;
84 env: FxHashMap<string, string>;
85 cwd: Option<string>;
86}
87export const runnables = request<RunnablesParams, Vec<Runnable>>("runnables");
88
89export type InlayHint = InlayHint.TypeHint | InlayHint.ParamHint | InlayHint.ChainingHint;
90
91export namespace InlayHint {
92 export const enum Kind {
93 TypeHint = "TypeHint",
94 ParamHint = "ParameterHint",
95 ChainingHint = "ChainingHint",
96 }
97 interface Common {
98 range: lc.Range;
99 label: string;
100 }
101 export type TypeHint = Common & { kind: Kind.TypeHint };
102 export type ParamHint = Common & { kind: Kind.ParamHint };
103 export type ChainingHint = Common & { kind: Kind.ChainingHint };
104}
105export interface InlayHintsParams {
106 textDocument: lc.TextDocumentIdentifier;
107}
108export const inlayHints = request<InlayHintsParams, Vec<InlayHint>>("inlayHints");
109
110
111export interface SsrParams {
112 query: string;
113 parseOnly: boolean;
114}
115export const ssr = request<SsrParams, SourceChange>("ssr");
116
117
118export const publishDecorations = notification<PublishDecorationsParams>("publishDecorations");
119
120
121export interface SourceChange {
122 label: string;
123 workspaceEdit: lc.WorkspaceEdit;
124 cursorPosition: Option<lc.TextDocumentPositionParams>;
125}
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts
new file mode 100644
index 000000000..bcb3f2cc7
--- /dev/null
+++ b/editors/code/src/snippets.ts
@@ -0,0 +1,55 @@
1import * as vscode from 'vscode';
2
3import { assert } from './util';
4
5export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) {
6 assert(edit.entries().length === 1, `bad ws edit: ${JSON.stringify(edit)}`);
7 const [uri, edits] = edit.entries()[0];
8
9 const editor = vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString());
10 if (!editor) return;
11 await applySnippetTextEdits(editor, edits);
12}
13
14export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) {
15 let selection: vscode.Selection | undefined = undefined;
16 let lineDelta = 0;
17 await editor.edit((builder) => {
18 for (const indel of edits) {
19 const parsed = parseSnippet(indel.newText);
20 if (parsed) {
21 const [newText, [placeholderStart, placeholderLength]] = parsed;
22 const prefix = newText.substr(0, placeholderStart);
23 const lastNewline = prefix.lastIndexOf('\n');
24
25 const startLine = indel.range.start.line + lineDelta + countLines(prefix);
26 const startColumn = lastNewline === -1 ?
27 indel.range.start.character + placeholderStart
28 : prefix.length - lastNewline - 1;
29 const endColumn = startColumn + placeholderLength;
30 selection = new vscode.Selection(
31 new vscode.Position(startLine, startColumn),
32 new vscode.Position(startLine, endColumn),
33 );
34 builder.replace(indel.range, newText);
35 } else {
36 lineDelta = countLines(indel.newText) - (indel.range.end.line - indel.range.start.line);
37 builder.replace(indel.range, indel.newText);
38 }
39 }
40 });
41 if (selection) editor.selection = selection;
42}
43
44function parseSnippet(snip: string): [string, [number, number]] | undefined {
45 const m = snip.match(/\$(0|\{0:([^}]*)\})/);
46 if (!m) return undefined;
47 const placeholder = m[2] ?? "";
48 const range: [number, number] = [m.index!!, placeholder.length];
49 const insert = snip.replace(m[0], placeholder);
50 return [insert, range];
51}
52
53function countLines(text: string): number {
54 return (text.match(/\n/g) || []).length;
55}
diff --git a/editors/code/src/source_change.ts b/editors/code/src/source_change.ts
deleted file mode 100644
index af8f1df51..000000000
--- a/editors/code/src/source_change.ts
+++ /dev/null
@@ -1,54 +0,0 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3import * as ra from './rust-analyzer-api';
4
5import { Ctx } from './ctx';
6
7export async function applySourceChange(ctx: Ctx, change: ra.SourceChange) {
8 const client = ctx.client;
9 if (!client) return;
10
11 const wsEdit = client.protocol2CodeConverter.asWorkspaceEdit(
12 change.workspaceEdit,
13 );
14 let created;
15 let moved;
16 if (change.workspaceEdit.documentChanges) {
17 for (const docChange of change.workspaceEdit.documentChanges) {
18 if (lc.CreateFile.is(docChange)) {
19 created = docChange.uri;
20 } else if (lc.RenameFile.is(docChange)) {
21 moved = docChange.newUri;
22 }
23 }
24 }
25 const toOpen = created || moved;
26 const toReveal = change.cursorPosition;
27 await vscode.workspace.applyEdit(wsEdit);
28 if (toOpen) {
29 const toOpenUri = vscode.Uri.parse(toOpen);
30 const doc = await vscode.workspace.openTextDocument(toOpenUri);
31 await vscode.window.showTextDocument(doc);
32 } else if (toReveal) {
33 const uri = client.protocol2CodeConverter.asUri(
34 toReveal.textDocument.uri,
35 );
36 const position = client.protocol2CodeConverter.asPosition(
37 toReveal.position,
38 );
39 const editor = vscode.window.activeTextEditor;
40 if (!editor || !editor.selection.isEmpty) {
41 return;
42 }
43
44 if (editor.document.uri !== uri) {
45 const doc = await vscode.workspace.openTextDocument(uri);
46 await vscode.window.showTextDocument(doc);
47 }
48 editor.selection = new vscode.Selection(position, position);
49 editor.revealRange(
50 new vscode.Range(position, position),
51 vscode.TextEditorRevealType.Default,
52 );
53 }
54}
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts
index 1366c76d6..9748824df 100644
--- a/editors/code/src/tasks.ts
+++ b/editors/code/src/tasks.ts
@@ -1,4 +1,5 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as toolchain from "./toolchain";
2 3
3// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and 4// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
4// our configuration should be compatible with it so use the same key. 5// our configuration should be compatible with it so use the same key.
@@ -24,6 +25,8 @@ class CargoTaskProvider implements vscode.TaskProvider {
24 // set of tasks that always exist. These tasks cannot be removed in 25 // set of tasks that always exist. These tasks cannot be removed in
25 // tasks.json - only tweaked. 26 // tasks.json - only tweaked.
26 27
28 const cargoPath = toolchain.cargoPath();
29
27 return [ 30 return [
28 { command: 'build', group: vscode.TaskGroup.Build }, 31 { command: 'build', group: vscode.TaskGroup.Build },
29 { command: 'check', group: vscode.TaskGroup.Build }, 32 { command: 'check', group: vscode.TaskGroup.Build },
@@ -46,7 +49,7 @@ class CargoTaskProvider implements vscode.TaskProvider {
46 `cargo ${command}`, 49 `cargo ${command}`,
47 'rust', 50 'rust',
48 // What to do when this command is executed. 51 // What to do when this command is executed.
49 new vscode.ShellExecution('cargo', [command]), 52 new vscode.ShellExecution(cargoPath, [command]),
50 // Problem matchers. 53 // Problem matchers.
51 ['$rustc'], 54 ['$rustc'],
52 ); 55 );
@@ -80,4 +83,4 @@ class CargoTaskProvider implements vscode.TaskProvider {
80export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable { 83export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable {
81 const provider = new CargoTaskProvider(target); 84 const provider = new CargoTaskProvider(target);
82 return vscode.tasks.registerTaskProvider(TASK_TYPE, provider); 85 return vscode.tasks.registerTaskProvider(TASK_TYPE, provider);
83} \ No newline at end of file 86}
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
new file mode 100644
index 000000000..80a7915e9
--- /dev/null
+++ b/editors/code/src/toolchain.ts
@@ -0,0 +1,174 @@
1import * as cp from 'child_process';
2import * as os from 'os';
3import * as path from 'path';
4import * as fs from 'fs';
5import * as readline from 'readline';
6import { OutputChannel } from 'vscode';
7import { log, memoize } from './util';
8
9interface CompilationArtifact {
10 fileName: string;
11 name: string;
12 kind: string;
13 isTest: boolean;
14}
15
16export interface ArtifactSpec {
17 cargoArgs: string[];
18 filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[];
19}
20
21export class Cargo {
22 constructor(readonly rootFolder: string, readonly output: OutputChannel) { }
23
24 // Made public for testing purposes
25 static artifactSpec(args: readonly string[]): ArtifactSpec {
26 const cargoArgs = [...args, "--message-format=json"];
27
28 // arguments for a runnable from the quick pick should be updated.
29 // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens
30 switch (cargoArgs[0]) {
31 case "run": cargoArgs[0] = "build"; break;
32 case "test": {
33 if (!cargoArgs.includes("--no-run")) {
34 cargoArgs.push("--no-run");
35 }
36 break;
37 }
38 }
39
40 const result: ArtifactSpec = { cargoArgs: cargoArgs };
41 if (cargoArgs[0] === "test") {
42 // for instance, `crates\rust-analyzer\tests\heavy_tests\main.rs` tests
43 // produce 2 artifacts: {"kind": "bin"} and {"kind": "test"}
44 result.filter = (artifacts) => artifacts.filter(it => it.isTest);
45 }
46
47 return result;
48 }
49
50 private async getArtifacts(spec: ArtifactSpec): Promise<CompilationArtifact[]> {
51 const artifacts: CompilationArtifact[] = [];
52
53 try {
54 await this.runCargo(spec.cargoArgs,
55 message => {
56 if (message.reason === 'compiler-artifact' && message.executable) {
57 const isBinary = message.target.crate_types.includes('bin');
58 const isBuildScript = message.target.kind.includes('custom-build');
59 if ((isBinary && !isBuildScript) || message.profile.test) {
60 artifacts.push({
61 fileName: message.executable,
62 name: message.target.name,
63 kind: message.target.kind[0],
64 isTest: message.profile.test
65 });
66 }
67 } else if (message.reason === 'compiler-message') {
68 this.output.append(message.message.rendered);
69 }
70 },
71 stderr => this.output.append(stderr),
72 );
73 } catch (err) {
74 this.output.show(true);
75 throw new Error(`Cargo invocation has failed: ${err}`);
76 }
77
78 return spec.filter?.(artifacts) ?? artifacts;
79 }
80
81 async executableFromArgs(args: readonly string[]): Promise<string> {
82 const artifacts = await this.getArtifacts(Cargo.artifactSpec(args));
83
84 if (artifacts.length === 0) {
85 throw new Error('No compilation artifacts');
86 } else if (artifacts.length > 1) {
87 throw new Error('Multiple compilation artifacts are not supported.');
88 }
89
90 return artifacts[0].fileName;
91 }
92
93 private runCargo(
94 cargoArgs: string[],
95 onStdoutJson: (obj: any) => void,
96 onStderrString: (data: string) => void
97 ): Promise<number> {
98 return new Promise((resolve, reject) => {
99 const cargo = cp.spawn(cargoPath(), cargoArgs, {
100 stdio: ['ignore', 'pipe', 'pipe'],
101 cwd: this.rootFolder
102 });
103
104 cargo.on('error', err => reject(new Error(`could not launch cargo: ${err}`)));
105
106 cargo.stderr.on('data', chunk => onStderrString(chunk.toString()));
107
108 const rl = readline.createInterface({ input: cargo.stdout });
109 rl.on('line', line => {
110 const message = JSON.parse(line);
111 onStdoutJson(message);
112 });
113
114 cargo.on('exit', (exitCode, _) => {
115 if (exitCode === 0)
116 resolve(exitCode);
117 else
118 reject(new Error(`exit code: ${exitCode}.`));
119 });
120 });
121 }
122}
123
124/** Mirrors `ra_toolchain::cargo()` implementation */
125export function cargoPath(): string {
126 return getPathForExecutable("cargo");
127}
128
129/** Mirrors `ra_toolchain::get_path_for_executable()` implementation */
130export const getPathForExecutable = memoize(
131 // We apply caching to decrease file-system interactions
132 (executableName: "cargo" | "rustc" | "rustup"): string => {
133 {
134 const envVar = process.env[executableName.toUpperCase()];
135 if (envVar) return envVar;
136 }
137
138 if (lookupInPath(executableName)) return executableName;
139
140 try {
141 // hmm, `os.homedir()` seems to be infallible
142 // it is not mentioned in docs and cannot be infered by the type signature...
143 const standardPath = path.join(os.homedir(), ".cargo", "bin", executableName);
144
145 if (isFile(standardPath)) return standardPath;
146 } catch (err) {
147 log.error("Failed to read the fs info", err);
148 }
149 return executableName;
150 }
151);
152
153function lookupInPath(exec: string): boolean {
154 const paths = process.env.PATH ?? "";;
155
156 const candidates = paths.split(path.delimiter).flatMap(dirInPath => {
157 const candidate = path.join(dirInPath, exec);
158 return os.type() === "Windows_NT"
159 ? [candidate, `${candidate}.exe`]
160 : [candidate];
161 });
162
163 return candidates.some(isFile);
164}
165
166function isFile(suspectPath: string): boolean {
167 // It is not mentionned in docs, but `statSync()` throws an error when
168 // the path doesn't exist
169 try {
170 return fs.statSync(suspectPath).isFile();
171 } catch {
172 return false;
173 }
174}
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 6f91f81d6..fe3fb71cd 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,7 @@
1import * as lc from "vscode-languageclient"; 1import * as lc from "vscode-languageclient";
2import * as vscode from "vscode"; 2import * as vscode from "vscode";
3import { strict as nativeAssert } from "assert"; 3import { strict as nativeAssert } from "assert";
4import { spawnSync } from "child_process";
4 5
5export function assert(condition: boolean, explanation: string): asserts condition { 6export function assert(condition: boolean, explanation: string): asserts condition {
6 try { 7 try {
@@ -73,12 +74,46 @@ export type RustDocument = vscode.TextDocument & { languageId: "rust" };
73export type RustEditor = vscode.TextEditor & { document: RustDocument }; 74export type RustEditor = vscode.TextEditor & { document: RustDocument };
74 75
75export function isRustDocument(document: vscode.TextDocument): document is RustDocument { 76export function isRustDocument(document: vscode.TextDocument): document is RustDocument {
76 return document.languageId === 'rust' 77 // Prevent corrupted text (particularly via inlay hints) in diff views
77 // SCM diff views have the same URI as the on-disk document but not the same content 78 // by allowing only `file` schemes
78 && document.uri.scheme !== 'git' 79 // unfortunately extensions that use diff views not always set this
79 && document.uri.scheme !== 'svn'; 80 // to something different than 'file' (see ongoing bug: #4608)
81 return document.languageId === 'rust' && document.uri.scheme === 'file';
80} 82}
81 83
82export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { 84export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
83 return isRustDocument(editor.document); 85 return isRustDocument(editor.document);
84} 86}
87
88export function isValidExecutable(path: string): boolean {
89 log.debug("Checking availability of a binary at", path);
90
91 const res = spawnSync(path, ["--version"], { encoding: 'utf8' });
92
93 log.debug(res, "--version output:", res.output);
94
95 return res.status === 0;
96}
97
98/** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */
99export function setContextValue(key: string, value: any): Thenable<void> {
100 return vscode.commands.executeCommand('setContext', key, value);
101}
102
103/**
104 * Returns a higher-order function that caches the results of invoking the
105 * underlying function.
106 */
107export function memoize<Ret, TThis, Param extends string>(func: (this: TThis, arg: Param) => Ret) {
108 const cache = new Map<string, Ret>();
109
110 return function(this: TThis, arg: Param) {
111 const cached = cache.get(arg);
112 if (cached) return cached;
113
114 const result = func.call(this, arg);
115 cache.set(arg, result);
116
117 return result;
118 };
119}
diff --git a/editors/code/tests/runTests.ts b/editors/code/tests/runTests.ts
new file mode 100644
index 000000000..22df80ad3
--- /dev/null
+++ b/editors/code/tests/runTests.ts
@@ -0,0 +1,43 @@
1import * as path from 'path';
2import * as fs from 'fs';
3
4import { runTests } from 'vscode-test';
5
6async function main() {
7 // The folder containing the Extension Manifest package.json
8 // Passed to `--extensionDevelopmentPath`
9 const extensionDevelopmentPath = path.resolve(__dirname, '../../');
10
11 // Minimum supported version.
12 const jsonData = fs.readFileSync(path.join(extensionDevelopmentPath, 'package.json'));
13 const json = JSON.parse(jsonData.toString());
14 let minimalVersion: string = json.engines.vscode;
15 if (minimalVersion.startsWith('^')) minimalVersion = minimalVersion.slice(1);
16
17 const launchArgs = ["--disable-extensions"];
18
19 // All test suites (either unit tests or integration tests) should be in subfolders.
20 const extensionTestsPath = path.resolve(__dirname, './unit/index');
21
22 // Run tests using the minimal supported version.
23 await runTests({
24 version: minimalVersion,
25 launchArgs,
26 extensionDevelopmentPath,
27 extensionTestsPath
28 });
29
30 // and the latest one
31 await runTests({
32 version: 'stable',
33 launchArgs,
34 extensionDevelopmentPath,
35 extensionTestsPath
36 });
37}
38
39main().catch(err => {
40 // eslint-disable-next-line no-console
41 console.error('Failed to run tests', err);
42 process.exit(1);
43});
diff --git a/editors/code/tests/unit/index.ts b/editors/code/tests/unit/index.ts
new file mode 100644
index 000000000..5165720b4
--- /dev/null
+++ b/editors/code/tests/unit/index.ts
@@ -0,0 +1,38 @@
1import * as path from 'path';
2import Mocha from 'mocha';
3import glob from 'glob';
4
5export function run(): Promise<void> {
6 // Create the mocha test
7 const mocha = new Mocha({
8 ui: 'tdd',
9 color: true
10 });
11
12 const testsRoot = __dirname;
13
14 return new Promise((resolve, reject) => {
15 glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
16 if (err) {
17 return reject(err);
18 }
19
20 // Add files to the test suite
21 files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
22
23 try {
24 // Run the mocha test
25 mocha.timeout(100000);
26 mocha.run(failures => {
27 if (failures > 0) {
28 reject(new Error(`${failures} tests failed.`));
29 } else {
30 resolve();
31 }
32 });
33 } catch (err) {
34 reject(err);
35 }
36 });
37 });
38}
diff --git a/editors/code/tests/unit/launch_config.test.ts b/editors/code/tests/unit/launch_config.test.ts
new file mode 100644
index 000000000..68794d53e
--- /dev/null
+++ b/editors/code/tests/unit/launch_config.test.ts
@@ -0,0 +1,52 @@
1import * as assert from 'assert';
2import { Cargo } from '../../src/toolchain';
3
4suite('Launch configuration', () => {
5
6 suite('Lens', () => {
7 test('A binary', async () => {
8 const args = Cargo.artifactSpec(["build", "--package", "pkg_name", "--bin", "pkg_name"]);
9
10 assert.deepEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "pkg_name", "--message-format=json"]);
11 assert.deepEqual(args.filter, undefined);
12 });
13
14 test('One of Multiple Binaries', async () => {
15 const args = Cargo.artifactSpec(["build", "--package", "pkg_name", "--bin", "bin1"]);
16
17 assert.deepEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "bin1", "--message-format=json"]);
18 assert.deepEqual(args.filter, undefined);
19 });
20
21 test('A test', async () => {
22 const args = Cargo.artifactSpec(["test", "--package", "pkg_name", "--lib", "--no-run"]);
23
24 assert.deepEqual(args.cargoArgs, ["test", "--package", "pkg_name", "--lib", "--no-run", "--message-format=json"]);
25 assert.notDeepEqual(args.filter, undefined);
26 });
27 });
28
29 suite('QuickPick', () => {
30 test('A binary', async () => {
31 const args = Cargo.artifactSpec(["run", "--package", "pkg_name", "--bin", "pkg_name"]);
32
33 assert.deepEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "pkg_name", "--message-format=json"]);
34 assert.deepEqual(args.filter, undefined);
35 });
36
37
38 test('One of Multiple Binaries', async () => {
39 const args = Cargo.artifactSpec(["run", "--package", "pkg_name", "--bin", "bin2"]);
40
41 assert.deepEqual(args.cargoArgs, ["build", "--package", "pkg_name", "--bin", "bin2", "--message-format=json"]);
42 assert.deepEqual(args.filter, undefined);
43 });
44
45 test('A test', async () => {
46 const args = Cargo.artifactSpec(["test", "--package", "pkg_name", "--lib"]);
47
48 assert.deepEqual(args.cargoArgs, ["test", "--package", "pkg_name", "--lib", "--message-format=json", "--no-run"]);
49 assert.notDeepEqual(args.filter, undefined);
50 });
51 });
52});
diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json
index ad134865a..32d1a865f 100644
--- a/editors/code/tsconfig.json
+++ b/editors/code/tsconfig.json
@@ -9,7 +9,7 @@
9 "esModuleInterop": true, 9 "esModuleInterop": true,
10 "allowSyntheticDefaultImports": true, 10 "allowSyntheticDefaultImports": true,
11 "sourceMap": true, 11 "sourceMap": true,
12 "rootDir": "src", 12 "rootDir": ".",
13 "strict": true, 13 "strict": true,
14 "noUnusedLocals": true, 14 "noUnusedLocals": true,
15 "noUnusedParameters": true, 15 "noUnusedParameters": true,
@@ -18,6 +18,11 @@
18 "newLine": "LF" 18 "newLine": "LF"
19 }, 19 },
20 "exclude": [ 20 "exclude": [
21 "node_modules" 21 "node_modules",
22 ".vscode-test"
23 ],
24 "include": [
25 "src",
26 "tests"
22 ] 27 ]
23} 28}