@mirascript/monaco 0.1.61 → 0.1.62-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +5 -5
  3. package/dist/basic/index.d.ts +0 -6
  4. package/dist/basic/index.d.ts.map +0 -1
  5. package/dist/basic/index.js +0 -10
  6. package/dist/basic/index.js.map +0 -6
  7. package/dist/basic/language-configuration.d.ts +0 -5
  8. package/dist/basic/language-configuration.d.ts.map +0 -1
  9. package/dist/basic/tokens-provider.d.ts +0 -4
  10. package/dist/basic/tokens-provider.d.ts.map +0 -1
  11. package/dist/chunk-NAOKM25O.js +0 -63
  12. package/dist/chunk-NAOKM25O.js.map +0 -6
  13. package/dist/chunk-SCSO2D5U.js +0 -570
  14. package/dist/chunk-SCSO2D5U.js.map +0 -6
  15. package/dist/constants.d.ts +0 -5
  16. package/dist/constants.d.ts.map +0 -1
  17. package/dist/contribute.d.ts +0 -3
  18. package/dist/contribute.d.ts.map +0 -1
  19. package/dist/index.d.ts +0 -27
  20. package/dist/index.d.ts.map +0 -1
  21. package/dist/index.js +0 -89
  22. package/dist/index.js.map +0 -6
  23. package/dist/lsp/compile-result.d.ts +0 -147
  24. package/dist/lsp/compile-result.d.ts.map +0 -1
  25. package/dist/lsp/diagnostics.d.ts +0 -8
  26. package/dist/lsp/diagnostics.d.ts.map +0 -1
  27. package/dist/lsp/index.d.ts +0 -43
  28. package/dist/lsp/index.d.ts.map +0 -1
  29. package/dist/lsp/index.js +0 -3097
  30. package/dist/lsp/index.js.map +0 -6
  31. package/dist/lsp/monaco-private.d.ts +0 -19
  32. package/dist/lsp/monaco-private.d.ts.map +0 -1
  33. package/dist/lsp/monaco-utils.d.ts +0 -20
  34. package/dist/lsp/monaco-utils.d.ts.map +0 -1
  35. package/dist/lsp/providers/base.d.ts +0 -43
  36. package/dist/lsp/providers/base.d.ts.map +0 -1
  37. package/dist/lsp/providers/code-action-provider.d.ts +0 -12
  38. package/dist/lsp/providers/code-action-provider.d.ts.map +0 -1
  39. package/dist/lsp/providers/code-lens-provider.d.ts +0 -12
  40. package/dist/lsp/providers/code-lens-provider.d.ts.map +0 -1
  41. package/dist/lsp/providers/color-provider.d.ts +0 -10
  42. package/dist/lsp/providers/color-provider.d.ts.map +0 -1
  43. package/dist/lsp/providers/completion-item-provider.d.ts +0 -21
  44. package/dist/lsp/providers/completion-item-provider.d.ts.map +0 -1
  45. package/dist/lsp/providers/definition-reference-provider.d.ts +0 -19
  46. package/dist/lsp/providers/definition-reference-provider.d.ts.map +0 -1
  47. package/dist/lsp/providers/document-highlight-provider.d.ts +0 -12
  48. package/dist/lsp/providers/document-highlight-provider.d.ts.map +0 -1
  49. package/dist/lsp/providers/document-symbol-provider.d.ts +0 -10
  50. package/dist/lsp/providers/document-symbol-provider.d.ts.map +0 -1
  51. package/dist/lsp/providers/formatter-provider.d.ts +0 -18
  52. package/dist/lsp/providers/formatter-provider.d.ts.map +0 -1
  53. package/dist/lsp/providers/hover-provider.d.ts +0 -14
  54. package/dist/lsp/providers/hover-provider.d.ts.map +0 -1
  55. package/dist/lsp/providers/inlay-hints-provider.d.ts +0 -10
  56. package/dist/lsp/providers/inlay-hints-provider.d.ts.map +0 -1
  57. package/dist/lsp/providers/range-provider.d.ts +0 -10
  58. package/dist/lsp/providers/range-provider.d.ts.map +0 -1
  59. package/dist/lsp/providers/rename-provider.d.ts +0 -12
  60. package/dist/lsp/providers/rename-provider.d.ts.map +0 -1
  61. package/dist/lsp/providers/semantic-tokens-provider.d.ts +0 -12
  62. package/dist/lsp/providers/semantic-tokens-provider.d.ts.map +0 -1
  63. package/dist/lsp/providers/signature-help-provider.d.ts +0 -12
  64. package/dist/lsp/providers/signature-help-provider.d.ts.map +0 -1
  65. package/dist/lsp/utils.d.ts +0 -41
  66. package/dist/lsp/utils.d.ts.map +0 -1
  67. package/dist/lsp/worker-helper.d.ts +0 -5
  68. package/dist/lsp/worker-helper.d.ts.map +0 -1
  69. package/dist/lsp/worker.d.ts +0 -23
  70. package/dist/lsp/worker.d.ts.map +0 -1
  71. package/dist/lsp/worker.js +0 -63
  72. package/dist/lsp/worker.js.map +0 -6
  73. package/dist/monaco-api.d.ts +0 -16
  74. package/dist/monaco-api.d.ts.map +0 -1
package/dist/lsp/index.js DELETED
@@ -1,3097 +0,0 @@
1
- import {
2
- KEYWORDS,
3
- REG_BIN,
4
- REG_HEX,
5
- REG_IDENTIFIER_FULL,
6
- REG_NUMBER,
7
- REG_OCT,
8
- REG_ORDINAL_FULL,
9
- RESERVED_KEYWORDS,
10
- isKeyword
11
- } from "../chunk-SCSO2D5U.js";
12
- import {
13
- Emitter,
14
- MarkerSeverity,
15
- MarkerTag,
16
- Position,
17
- Range,
18
- Uri,
19
- editor,
20
- languages
21
- } from "../chunk-NAOKM25O.js";
22
-
23
- // src/lsp/providers/base.ts
24
- import { DefaultVmContext } from "@mirascript/mirascript/subtle";
25
-
26
- // src/lsp/monaco-utils.ts
27
- function strictContainsPosition(range, position) {
28
- return !Range.isEmpty(range) && Range.containsPosition(range, position);
29
- }
30
- function wordAt(model, position) {
31
- const word = model.getWordAtPosition(position);
32
- if (!word) return void 0;
33
- const range = new Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
34
- return { word: word.word, range };
35
- }
36
- function rangeAt(...args) {
37
- if (args.length === 1 || args[1] == null) {
38
- const { lineNumber, startColumn, endColumn } = args[0];
39
- return new Range(lineNumber, startColumn, lineNumber, endColumn);
40
- } else {
41
- const { lineNumber } = args[0];
42
- const { startColumn, endColumn } = args[1];
43
- return new Range(lineNumber, startColumn, lineNumber, endColumn);
44
- }
45
- }
46
-
47
- // src/lsp/compile-result.ts
48
- import {
49
- parseDiagnostics,
50
- DiagnosticCode
51
- } from "@mirascript/mirascript/subtle";
52
- var LocalVariableType = [
53
- DiagnosticCode.LocalMutable,
54
- DiagnosticCode.LocalImmutable,
55
- DiagnosticCode.LocalConst,
56
- DiagnosticCode.LocalFunction,
57
- DiagnosticCode.LocalModule
58
- ];
59
- var ParameterExplicitType = [
60
- DiagnosticCode.ParameterMutable,
61
- DiagnosticCode.ParameterImmutable,
62
- DiagnosticCode.ParameterMutableRest,
63
- DiagnosticCode.ParameterImmutableRest
64
- ];
65
- var ParameterSubPatternType = [
66
- DiagnosticCode.ParameterSubPatternImmutable,
67
- DiagnosticCode.ParameterSubPatternMutable
68
- ];
69
- var ParameterPatternType = [DiagnosticCode.ParameterPattern, DiagnosticCode.ParameterRestPattern];
70
- var ParameterItType = [DiagnosticCode.ParameterIt];
71
- var ParameterDefinitionType = [
72
- ...ParameterExplicitType,
73
- ...ParameterSubPatternType,
74
- ...ParameterItType
75
- ];
76
- var ParameterPlaceholderType = [
77
- ...ParameterExplicitType,
78
- ...ParameterPatternType,
79
- ...ParameterItType
80
- ];
81
- var LocalDefinitionType = [...LocalVariableType, ...ParameterDefinitionType];
82
- var CompileResult = class {
83
- constructor(cacheKey, version, source, result) {
84
- this.cacheKey = cacheKey;
85
- this.version = version;
86
- this.source = source;
87
- this.result = result;
88
- this.diagnosticsReady = false;
89
- this._errors = [];
90
- this._warnings = [];
91
- this._infos = [];
92
- this._hints = [];
93
- this._references = [];
94
- this._tags = [];
95
- this._tagsReferences = [];
96
- this.diagnostics = result.diagnostics;
97
- this.chunk = result.chunk;
98
- }
99
- /** 源代码诊断信息 */
100
- get errors() {
101
- if (!this.diagnosticsReady) {
102
- this.readDiagnostics();
103
- }
104
- return this._errors;
105
- }
106
- /** 源代码诊断信息 */
107
- get warnings() {
108
- if (!this.diagnosticsReady) {
109
- this.readDiagnostics();
110
- }
111
- return this._warnings;
112
- }
113
- /** 源代码诊断信息 */
114
- get infos() {
115
- if (!this.diagnosticsReady) {
116
- this.readDiagnostics();
117
- }
118
- return this._infos;
119
- }
120
- /** 源代码诊断信息 */
121
- get hints() {
122
- if (!this.diagnosticsReady) {
123
- this.readDiagnostics();
124
- }
125
- return this._hints;
126
- }
127
- /** 源代码诊断信息 */
128
- get references() {
129
- if (!this.diagnosticsReady) {
130
- this.readDiagnostics();
131
- }
132
- return this._references;
133
- }
134
- /** 源代码诊断信息 */
135
- get tags() {
136
- if (!this.diagnosticsReady) {
137
- this.readDiagnostics();
138
- }
139
- return this._tags;
140
- }
141
- /** 源代码诊断信息 */
142
- get tagsReferences() {
143
- if (!this.diagnosticsReady) {
144
- this.readDiagnostics();
145
- }
146
- return this._tagsReferences;
147
- }
148
- /** 分析诊断信息 */
149
- readDiagnostics() {
150
- const parsed = parseDiagnostics(this.source, this.diagnostics, (c) => c !== DiagnosticCode.SourceMap);
151
- this._errors = parsed.errors;
152
- this._warnings = parsed.warnings;
153
- this._infos = parsed.infos;
154
- this._hints = parsed.hints;
155
- this._tags = parsed.tags;
156
- this._references = parsed.references;
157
- this._tagsReferences = parsed.tagsReferences;
158
- this.diagnosticsReady = true;
159
- }
160
- /** 获取源代码定义 */
161
- groupedTags(model) {
162
- if (this._groupedTags) {
163
- return this._groupedTags;
164
- }
165
- const getText = (range) => {
166
- if (model.getVersionId() !== this.version) {
167
- return void 0;
168
- }
169
- return model.getValueInRange(range);
170
- };
171
- const locals = [];
172
- const params = [];
173
- const globals = [];
174
- const ranges = [];
175
- const omitNameFields = [];
176
- for (const tag of this.tags) {
177
- if (ParameterPlaceholderType.includes(tag.code)) {
178
- params.push(tag);
179
- }
180
- if (LocalDefinitionType.includes(tag.code)) {
181
- locals.push({
182
- definition: tag,
183
- references: tag.references
184
- });
185
- } else if (tag.code === DiagnosticCode.GlobalVariable) {
186
- const name = getText(tag.range);
187
- let def = globals.find((def2) => name === def2.name);
188
- if (!def) {
189
- def = {
190
- name: name ?? "",
191
- references: []
192
- };
193
- globals.push(def);
194
- }
195
- def.references.push(tag);
196
- } else if (tag.code === DiagnosticCode.Scope || tag.code === DiagnosticCode.String || tag.code === DiagnosticCode.Interpolation || tag.code === DiagnosticCode.FunctionCall || tag.code === DiagnosticCode.ExtensionCall) {
197
- ranges.push(tag);
198
- } else if (tag.code === DiagnosticCode.OmitNamedRecordField) {
199
- omitNameFields.push(tag);
200
- }
201
- }
202
- locals.sort(
203
- (a, b) => Range.compareRangesUsingStarts(a.definition.range, b.definition.range)
204
- );
205
- params.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
206
- globals.sort((a, b) => a.name.localeCompare(b.name));
207
- ranges.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
208
- this._groupedTags = {
209
- locals,
210
- params,
211
- globals,
212
- ranges,
213
- omitNameFields
214
- };
215
- return this._groupedTags;
216
- }
217
- /** 获取指定位置的变量访问信息 */
218
- variableAccessAt(model, position) {
219
- const { globals } = this.groupedTags(model);
220
- for (const d of globals) {
221
- const refIndex = d.references.findIndex((u) => strictContainsPosition(u.range, position));
222
- if (refIndex >= 0) {
223
- return { def: d, ref: refIndex, range: d.references[refIndex].range };
224
- }
225
- }
226
- this.scopes(model);
227
- const { locals } = this.groupedTags(model);
228
- for (const d of locals) {
229
- if (strictContainsPosition(d.definition.range, position)) {
230
- return { def: d, ref: void 0, range: d.definition.range };
231
- }
232
- const refIndex = d.references.findIndex((u) => strictContainsPosition(u.range, position));
233
- if (refIndex >= 0) {
234
- return { def: d, ref: refIndex, range: d.references[refIndex].range };
235
- }
236
- }
237
- return void 0;
238
- }
239
- /** 获取作用域信息 */
240
- scopes(model) {
241
- if (this._scopes) {
242
- return this._scopes;
243
- }
244
- const { locals, params, ranges } = this.groupedTags(model);
245
- const scopes = ranges.filter((r) => r.code === DiagnosticCode.Scope).map((r) => {
246
- return {
247
- range: r.range,
248
- locals: [],
249
- params: [],
250
- parent: void 0,
251
- children: []
252
- };
253
- });
254
- for (let i = 0; i < scopes.length; i++) {
255
- const scopeA = scopes[i];
256
- let parent;
257
- for (let j = 0; j < scopes.length; j++) {
258
- if (i === j) continue;
259
- const scopeB = scopes[j];
260
- const aRange = scopeA.range;
261
- const bRange = scopeB.range;
262
- const isContained = Range.containsRange(bRange, aRange);
263
- if (isContained) {
264
- if (!parent || Range.containsRange(parent.range, bRange)) {
265
- parent = scopeB;
266
- }
267
- }
268
- }
269
- if (parent) {
270
- if (parent.parent === scopeA) {
271
- continue;
272
- }
273
- scopeA.parent = parent;
274
- parent.children.push(scopeA);
275
- }
276
- }
277
- const root = scopes.find((s) => !s.parent);
278
- if (!root) {
279
- this._scopes = [
280
- {
281
- range: model.getFullModelRange(),
282
- locals: [],
283
- params: [],
284
- parent: void 0,
285
- children: []
286
- }
287
- ];
288
- return this._scopes;
289
- }
290
- const queue = [root];
291
- const sortedScopes = [];
292
- while (queue.length > 0) {
293
- const scope = queue.shift();
294
- sortedScopes.push(scope);
295
- scope.children.sort(
296
- (a, b) => Range.compareRangesUsingStarts(a.range, b.range)
297
- );
298
- for (const child of scope.children) {
299
- queue.push(child);
300
- }
301
- }
302
- for (const local of locals) {
303
- const { range } = local.definition;
304
- const scope = sortedScopes.findLast((s) => Range.containsRange(s.range, range));
305
- if (scope) {
306
- scope.locals.push(local);
307
- }
308
- }
309
- for (const param of params) {
310
- const { range } = param;
311
- const scope = sortedScopes.findLast((s) => Range.containsRange(s.range, range));
312
- if (scope) {
313
- scope.params.push(param);
314
- }
315
- }
316
- const scopeMap = /* @__PURE__ */ new Map();
317
- for (const scope of sortedScopes) {
318
- scope.locals.sort(
319
- (a, b) => Range.compareRangesUsingStarts(a.definition.range, b.definition.range)
320
- );
321
- scope.params.sort(
322
- (a, b) => Range.compareRangesUsingStarts(a.range, b.range)
323
- );
324
- for (const local of scope.locals) {
325
- scopeMap.set(local, scope);
326
- if (local.definition.code === DiagnosticCode.LocalFunction) {
327
- const funcScope = scope.children.find(
328
- (s) => Range.compareRangesUsingStarts(s.range, local.definition.range) > 0
329
- );
330
- if (funcScope) {
331
- const args = funcScope.locals.filter(
332
- (l) => ParameterDefinitionType.includes(l.definition.code)
333
- );
334
- local.fn = {
335
- scope: funcScope,
336
- args
337
- };
338
- }
339
- }
340
- }
341
- }
342
- this._scopeMap = scopeMap;
343
- this._scopes = sortedScopes;
344
- return this._scopes;
345
- }
346
- /** 获取定义所在作用域 */
347
- scopeOf(model, def) {
348
- if (!this._scopeMap) {
349
- this.scopes(model);
350
- }
351
- return this._scopeMap.get(def);
352
- }
353
- /** 获取位置所在作用域 */
354
- scopeAt(model, position) {
355
- const scopes = this.scopes(model);
356
- let scope = scopes.findLast((s) => Range.containsPosition(s.range, position)) ?? scopes[0];
357
- while (scope.children.length > 0) {
358
- const inner = scope.children.find((s) => Range.containsPosition(s.range, position));
359
- if (!inner) break;
360
- scope = inner;
361
- }
362
- return scope;
363
- }
364
- /** 获取指定位置的字段访问信息 */
365
- fieldAccessAt(model, position) {
366
- let prevDef;
367
- const { globals } = this.groupedTags(model);
368
- for (const d of globals) {
369
- for (const [refIndex, ref] of d.references.entries()) {
370
- if (!Position.isBefore(Range.getEndPosition(ref.range), position)) continue;
371
- if (prevDef && Position.isBefore(Range.getEndPosition(ref.range), Range.getEndPosition(prevDef.range)))
372
- continue;
373
- prevDef = { def: d, ref: refIndex, range: ref.range };
374
- }
375
- }
376
- this.scopes(model);
377
- const { locals } = this.groupedTags(model);
378
- for (const d of locals) {
379
- for (const [refIndex, ref] of d.references.entries()) {
380
- if (!Position.isBefore(Range.getEndPosition(ref.range), position)) continue;
381
- if (prevDef && Position.isBefore(Range.getEndPosition(ref.range), Range.getEndPosition(prevDef.range)))
382
- continue;
383
- prevDef = { def: d, ref: refIndex, range: ref.range };
384
- }
385
- }
386
- if (!prevDef) return void 0;
387
- const chain = model.getValueInRange(Range.fromPositions(Range.getStartPosition(prevDef.range), position));
388
- const chainParts = chain.split(/\s*(?:!\.|\.)\s*/);
389
- if (
390
- // 至少包含变量名和当前位置的字段名
391
- chainParts.length < 2 || !chainParts.every(
392
- (part, index) => (
393
- // 如果是最后一个部分,则可以为空(表示当前位置的字段名),否则必须是合法的标识符
394
- (index === chainParts.length - 1 ? !part : false) || REG_IDENTIFIER_FULL.test(part) || REG_ORDINAL_FULL.test(part)
395
- )
396
- )
397
- ) {
398
- return void 0;
399
- }
400
- return { def: prevDef, fields: chainParts.slice(1) };
401
- }
402
- /** 获取指定位置的字段访问信息 */
403
- accessAt(model, position) {
404
- const v = this.variableAccessAt(model, position);
405
- if (v) return { def: v, fields: [] };
406
- return this.fieldAccessAt(model, position);
407
- }
408
- };
409
-
410
- // src/lsp/diagnostics.ts
411
- import { DiagnosticCode as DiagnosticCode3, getDiagnosticMessage, formatDiagnosticMessage } from "@mirascript/mirascript/subtle";
412
-
413
- // src/lsp/utils.ts
414
- import { DiagnosticCode as DiagnosticCode2 } from "@mirascript/constants";
415
- import {
416
- getVmFunctionInfo,
417
- isVmArray,
418
- isVmExtern,
419
- isVmFunction,
420
- isVmModule,
421
- isVmPrimitive,
422
- isVmRecord,
423
- isVmWrapper,
424
- serialize
425
- } from "@mirascript/mirascript";
426
- import { lib, operations, serializeRecordKey, serializeString } from "@mirascript/mirascript/subtle";
427
- var UNKNOWN_REPR = "/* .. */";
428
- function globalParamsSignature(info) {
429
- if (info == null || !info.params && !info.paramsType) return [["..", "..", ""]];
430
- const paramItems = [];
431
- const params = Object.keys(info.paramsType ?? {});
432
- for (const key of Object.keys(info.params ?? {})) {
433
- if (params.includes(key)) continue;
434
- params.push(key);
435
- }
436
- for (const key of params) {
437
- const type = info.paramsType?.[key] ?? "";
438
- const doc = info.params?.[key] ?? "";
439
- paramItems.push([key, `${key}: ${type || "any"}`, doc ? `\`${key}\`: ${doc}` : ""]);
440
- }
441
- return paramItems;
442
- }
443
- var SIG_WIDTH = 60;
444
- function fnSignature(id, info) {
445
- const prefix = id ? `fn ${id}` : "fn";
446
- const params = globalParamsSignature(info);
447
- const returns = info.returnsType ? ` -> ${info.returnsType}` : "";
448
- return {
449
- params,
450
- returns,
451
- toString() {
452
- let p;
453
- if (this.params.length >= 1 && (prefix.length + this.returns.length > SIG_WIDTH || prefix.length + this.returns.length + params.reduce((a, b) => a + b[1].length, 0) > SIG_WIDTH)) {
454
- p = `(
455
- ${params.map((item) => ` ${item[1]},`).join("\n")}
456
- )`;
457
- } else {
458
- p = `(${params.map((item) => item[1]).join(", ")})`;
459
- }
460
- return `${prefix}${p}${this.returns}`;
461
- }
462
- };
463
- }
464
- function localParamSignature(model, info) {
465
- const {
466
- args,
467
- scope: { params }
468
- } = info;
469
- if (params[0]?.code === DiagnosticCode2.ParameterIt) {
470
- return params[0].references.length ? [["it", "it", ""]] : [];
471
- }
472
- return params.map((a, i) => {
473
- const rest = a.code === DiagnosticCode2.ParameterRestPattern || a.code === DiagnosticCode2.ParameterMutableRest || a.code === DiagnosticCode2.ParameterImmutableRest;
474
- const argsInParam = args.filter((arg) => Range.containsRange(a.range, arg.definition.range));
475
- let argName;
476
- if (argsInParam.length > 0) {
477
- argName = argsInParam.map((arg) => model.getValueInRange(arg.definition.range)).join("_");
478
- } else if (rest) {
479
- argName = "args";
480
- } else {
481
- argName = `arg${i}`;
482
- }
483
- if (rest) return [`..${argName}`, `..${argName}`, ""];
484
- return [argName, argName, ""];
485
- });
486
- }
487
- function paramsList(model, info) {
488
- if (!info) return "(..)";
489
- if ("scope" in info) {
490
- return `(${localParamSignature(model, info).map((p) => p[1]).join(", ")})`;
491
- } else {
492
- if (!info.params) return "(..)";
493
- const paramItems = Object.keys(info.params).join(", ");
494
- return `(${paramItems})`;
495
- }
496
- }
497
- function globalFnDoc(info) {
498
- const doc = [];
499
- if (info.summary) {
500
- doc.push(info.summary);
501
- }
502
- const paramDoc = [];
503
- if (info.params) {
504
- for (const [key, value] of Object.entries(info.params)) {
505
- if (!value) continue;
506
- paramDoc.push(`- \`${key}\`: ${value}`);
507
- }
508
- }
509
- if (info.returns) {
510
- paramDoc.push(`- **返回值**: ${info.returns}`);
511
- }
512
- if (paramDoc.length) {
513
- doc.push("", paramDoc.join("\n"));
514
- }
515
- if (info.examples?.length) {
516
- let exp = `### 示例`;
517
- for (const example of info.examples) {
518
- exp += codeblock(example);
519
- }
520
- doc.push("", exp);
521
- }
522
- return doc;
523
- }
524
- function codeblock(value) {
525
- const lang = value.startsWith("\0") ? "mirascript-doc" : "mirascript";
526
- const includeFences = /`{3,}/.exec(value);
527
- const CODEBLOCK_FENCE = includeFences ? "`".repeat(includeFences[0].length + 1) : "```";
528
- return `
529
- ${CODEBLOCK_FENCE}${lang}
530
- ${value}
531
- ${CODEBLOCK_FENCE}
532
- `;
533
- }
534
- function serializeIntegerImpl(num, base, prefix, sep) {
535
- let str = Math.abs(num).toString(base);
536
- if (base > 10) str = str.toUpperCase();
537
- const sepSize = Math.abs(sep);
538
- if (sep !== 0 && str.length > sepSize) {
539
- const seg = [];
540
- if (sep > 0) {
541
- while (str.length > sepSize) {
542
- seg.unshift(str.slice(-sepSize));
543
- str = str.slice(0, -sepSize);
544
- }
545
- if (str.length > 0) {
546
- seg.unshift(str);
547
- }
548
- } else {
549
- while (str.length > sepSize) {
550
- seg.push(str.slice(0, sepSize));
551
- str = str.slice(sepSize);
552
- }
553
- if (str.length > 0) {
554
- seg.push(str);
555
- }
556
- }
557
- str = seg.join("_");
558
- }
559
- return (num < 0 ? "-" : "") + prefix + str;
560
- }
561
- function serializeInteger(num, base, sep = true) {
562
- const prefix = base === 2 ? "0b" : base === 8 ? "0o" : "0x";
563
- const sepSize = sep ? base === 2 ? 8 : base === 8 ? 6 : 4 : 0;
564
- return serializeIntegerImpl(num, base, prefix, sepSize);
565
- }
566
- function serializeNumber(num) {
567
- if (!Number.isFinite(num)) {
568
- return serialize(num);
569
- }
570
- const str = String(num);
571
- const dot = str.indexOf(".");
572
- const exp = str.indexOf("e");
573
- let intPart;
574
- let fracPart;
575
- let expPart;
576
- if (dot >= 0) {
577
- intPart = str.slice(0, dot);
578
- if (exp >= 0) {
579
- fracPart = str.slice(dot + 1, exp);
580
- expPart = str.slice(exp);
581
- } else {
582
- fracPart = str.slice(dot + 1);
583
- expPart = "";
584
- }
585
- } else {
586
- if (exp >= 0) {
587
- intPart = str.slice(0, exp);
588
- fracPart = "";
589
- expPart = str.slice(exp);
590
- } else {
591
- intPart = str;
592
- fracPart = "";
593
- expPart = "";
594
- }
595
- }
596
- if (intPart.length > 5) intPart = serializeIntegerImpl(Number(intPart), 10, "", 3);
597
- if (fracPart.length > 5) fracPart = serializeIntegerImpl(Number(fracPart), 10, "", -3);
598
- return intPart + (fracPart ? "." + fracPart : "") + expPart;
599
- }
600
- function serializeForDisplayInner(value, maxWidth) {
601
- if (maxWidth < 10) maxWidth = 10;
602
- if (typeof value === "string") {
603
- if (value.length < maxWidth) {
604
- return serializeString(value);
605
- }
606
- return `${serializeString(value.slice(0, maxWidth))}..`;
607
- }
608
- if (typeof value === "number") {
609
- return serializeNumber(value);
610
- }
611
- if (isVmPrimitive(value)) {
612
- return serialize(value);
613
- }
614
- if (isVmArray(value)) {
615
- const len = value.length;
616
- if (!len) return "[]";
617
- return `[../* x${len} */]`;
618
- }
619
- if (isVmRecord(value)) {
620
- const len = Object.keys(value).length;
621
- if (!len) return "()";
622
- return `(../* x${len} */)`;
623
- }
624
- if (isVmExtern(value)) {
625
- return `/* <extern ${value.tag}> */`;
626
- }
627
- return `/* ${operations.$ToString(value)} */`;
628
- }
629
- function serializeField(obj, key, maxWidth) {
630
- const value = getField(obj, key);
631
- if (value === void 0) {
632
- return UNKNOWN_REPR;
633
- }
634
- return serializeForDisplayInner(value, maxWidth);
635
- }
636
- function serializeForDisplay(value, maxEntries = 100, maxWidth = 40) {
637
- if (isVmPrimitive(value) || isVmFunction(value)) {
638
- return serializeForDisplayInner(value, maxWidth);
639
- }
640
- let begin, end;
641
- const entries = [];
642
- let resultLength = 0;
643
- if (isVmArray(value)) {
644
- begin = "[";
645
- end = "]";
646
- const len = value.length;
647
- if (len === 0) return "[]";
648
- for (let i = 0; i < len; i++) {
649
- if (entries.length > maxEntries) {
650
- entries.push(`../* x${value.length - entries.length} */`);
651
- break;
652
- }
653
- const entry = serializeField(value, i, maxWidth - 2);
654
- entries.push(entry);
655
- resultLength += entry.length;
656
- }
657
- } else if (isVmRecord(value)) {
658
- const keys = Object.keys(value);
659
- if (keys.length === 0) return "()";
660
- begin = "(";
661
- end = ")";
662
- for (const key of keys) {
663
- if (entries.length > maxEntries) {
664
- entries.push(`../* x${keys.length - entries.length} */`);
665
- break;
666
- }
667
- const sk = serializeRecordKey(key);
668
- const sv = serializeField(value, key, maxWidth - sk.length - 4);
669
- const entry = `${sk}: ${sv}`;
670
- entries.push(entry);
671
- resultLength += entry.length;
672
- }
673
- } else {
674
- const hint = serializeForDisplayInner(value, 100);
675
- const isArray = value.isArrayLike();
676
- begin = `${hint} ${isArray ? "[" : "("}`;
677
- end = isArray ? "]" : ")";
678
- const keys = value.keys();
679
- if (keys.length === 0 && !isArray) {
680
- if (typeof value.value == "object") {
681
- for (const key of Object.getOwnPropertyNames(value.value)) {
682
- if (value.has(key)) keys.push(key);
683
- }
684
- } else {
685
- begin = hint;
686
- end = "";
687
- }
688
- }
689
- for (const [index, key] of keys.entries()) {
690
- if (entries.length > maxEntries) {
691
- entries.push(`../* x${keys.length - entries.length} */`);
692
- break;
693
- }
694
- let entry;
695
- if (isArray && String(index) === key) {
696
- entry = serializeForDisplayInner(value.get(key) ?? null, maxWidth - 2);
697
- } else {
698
- const sk = serializeRecordKey(key);
699
- entry = `${sk}: ${serializeForDisplayInner(value.get(key) ?? null, maxWidth - sk.length - 4)}`;
700
- }
701
- entries.push(entry);
702
- resultLength += entry.length;
703
- }
704
- }
705
- if (resultLength >= maxWidth) {
706
- return `${begin}
707
- ${entries.join(",\n ")}
708
- ${end}`;
709
- }
710
- return `${begin}${entries.join(", ")}${end}`;
711
- }
712
- function docComment(doc) {
713
- const lines = doc.flatMap((sec) => sec.split("\n").map((s) => s.trimEnd()));
714
- const firstLine = lines.findIndex((line) => line.length > 0);
715
- const lastLine = lines.findLastIndex((line) => line.length > 0);
716
- if (firstLine < 0 || lastLine < 0) return [];
717
- return [`/**`, ...lines.slice(firstLine, lastLine + 1).map((line) => ` * ${line}`), ` */`];
718
- }
719
- function valueDoc(name, value, type, parent) {
720
- const info = getVmFunctionInfo(value);
721
- const describe = parent?.describe?.(name);
722
- if (info) {
723
- const doc = globalFnDoc(info);
724
- if (describe && doc[0] !== describe) {
725
- doc.unshift(describe);
726
- }
727
- return {
728
- script: fnSignature(name, info).toString() + (type === "declare" ? ";" : ""),
729
- doc
730
- };
731
- }
732
- let prefix;
733
- let suffix = "";
734
- if (type === "hint") {
735
- prefix = `${serializeRecordKey(name)} = `;
736
- } else if (type === "declare") {
737
- if (name.startsWith("@")) {
738
- prefix = `const ${name} = `;
739
- } else {
740
- prefix = `let ${name} = `;
741
- }
742
- suffix = ";";
743
- } else if (/^\d/.test(name)) {
744
- prefix = `[${name}]: `;
745
- } else {
746
- prefix = `${name}: `;
747
- }
748
- if (isVmModule(value)) {
749
- let script;
750
- if (type === "declare") {
751
- const exports = value.keys();
752
- if (!exports.length) {
753
- script = `mod ${value.name} { }`;
754
- } else {
755
- script = `mod ${value.name} {
756
- `;
757
- for (const k of exports) {
758
- const v = value.get(k);
759
- const vDoc = valueDoc(k, v, "declare", value);
760
- const code = [...docComment(vDoc.doc), "pub " + vDoc.script];
761
- const lines = code.flatMap((line) => line.split("\n"));
762
- for (const line of lines) {
763
- script += line ? " " + line + "\n" : "\n";
764
- }
765
- script += "\n";
766
- }
767
- script = script.trimEnd() + "\n}";
768
- }
769
- } else {
770
- script = `mod ${value.name}`;
771
- if (value.name !== name) {
772
- script = `${prefix}${script}`;
773
- }
774
- }
775
- return { script, doc: [`模块 \`${value.name}\``] };
776
- }
777
- let valueStr = UNKNOWN_REPR;
778
- if (value !== void 0) {
779
- try {
780
- valueStr = serializeForDisplay(value, type === "declare" ? 1e3 : 100, type === "declare" ? 80 : 40);
781
- } catch (ex) {
782
- }
783
- }
784
- return {
785
- script: `${prefix}${valueStr}${suffix}`,
786
- doc: describe ? [describe] : []
787
- };
788
- }
789
- function getDeep(globals, name, path) {
790
- if (!globals.has(name)) return [null, void 0];
791
- let current = globals.get(name);
792
- if (!path.length) {
793
- return [globals, current];
794
- }
795
- let parent = null;
796
- for (const key of path) {
797
- if (current == null) return [null, void 0];
798
- if (!operations.$Has(current, key)) return [null, void 0];
799
- parent = current;
800
- current = operations.$Get(parent, key);
801
- }
802
- return [isVmWrapper(parent) ? parent : null, current];
803
- }
804
- function getField(obj, key) {
805
- if (obj == null) return void 0;
806
- try {
807
- if (!operations.$Has(obj, key)) return void 0;
808
- } catch {
809
- return void 0;
810
- }
811
- try {
812
- return operations.$Get(obj, key);
813
- } catch {
814
- return void 0;
815
- }
816
- }
817
- function listFields(obj, includeNonEnumerable) {
818
- if (obj == null || typeof obj != "object") return [];
819
- if (isVmWrapper(obj)) {
820
- try {
821
- return obj.keys(includeNonEnumerable);
822
- } catch {
823
- return [];
824
- }
825
- }
826
- return lib.keys(obj);
827
- }
828
- function isDeprecatedGlobal(globals, name) {
829
- if (!globals.has(name)) {
830
- return void 0;
831
- }
832
- const value = globals.get(name);
833
- const funcInfo = getVmFunctionInfo(value);
834
- if (funcInfo) {
835
- return funcInfo.deprecated;
836
- }
837
- const info = lib[name];
838
- if (!info?.deprecated) return void 0;
839
- if (info.value !== value) return void 0;
840
- const { use } = info.deprecated;
841
- if (use) {
842
- if (!globals.has(use)) return void 0;
843
- const replacement = globals.get(use);
844
- if (replacement !== info.value) return void 0;
845
- }
846
- return info.deprecated;
847
- }
848
-
849
- // src/lsp/diagnostics.ts
850
- var formatMessage = (model, code, $0) => {
851
- return formatDiagnosticMessage(code, () => {
852
- if (!$0) return void 0;
853
- if (typeof $0 == "string") return $0;
854
- return model.getValueInRange($0);
855
- });
856
- };
857
- var makeMarkerData = (model, range, code, message, severity, tags) => {
858
- const { startLineNumber, startColumn, endLineNumber, endColumn } = range;
859
- if (!message) {
860
- if (typeof code != "number") {
861
- message = "";
862
- } else {
863
- message = formatMessage(model, code, range);
864
- }
865
- }
866
- const marker = {
867
- startLineNumber,
868
- startColumn,
869
- endLineNumber,
870
- endColumn,
871
- message,
872
- severity,
873
- modelVersionId: model.getVersionId(),
874
- source: "MiraScript",
875
- tags
876
- };
877
- const codeName = typeof code == "number" ? DiagnosticCode3[code] : void 0;
878
- if (codeName) {
879
- marker.code = {
880
- value: codeName,
881
- target: Uri.parse(`https://mira.cloudpss.net/code/${codeName}`)
882
- };
883
- } else {
884
- marker.code = `${code}`;
885
- }
886
- return marker;
887
- };
888
- function getDiagnosticCode(marker) {
889
- if (!marker) return void 0;
890
- const { code } = marker;
891
- if (typeof code == "object") {
892
- const codeName = code.value;
893
- if (codeName in DiagnosticCode3) {
894
- return DiagnosticCode3[codeName];
895
- }
896
- } else if (typeof code == "string") {
897
- if (code in DiagnosticCode3) {
898
- return DiagnosticCode3[code];
899
- }
900
- }
901
- return void 0;
902
- }
903
- var makeMarker = (model, diagnostic, severity) => {
904
- const { range, code } = diagnostic;
905
- let unnecessary = false;
906
- const deprecated = false;
907
- if (code === DiagnosticCode3.UnusedLocalVariable || code === DiagnosticCode3.UnusedLocalFunction) {
908
- unnecessary = true;
909
- severity = MarkerSeverity.Hint;
910
- }
911
- const marker = makeMarkerData(model, range, code, void 0, severity);
912
- if (unnecessary) {
913
- marker.tags ??= [];
914
- marker.tags.push(MarkerTag.Unnecessary);
915
- }
916
- if (deprecated) {
917
- marker.tags ??= [];
918
- marker.tags.push(MarkerTag.Deprecated);
919
- }
920
- if (diagnostic.references.length) {
921
- marker.relatedInformation = [];
922
- for (const ref of diagnostic.references) {
923
- const { range: range2, code: code2 } = ref;
924
- const { startLineNumber, startColumn, endLineNumber, endColumn } = range2;
925
- const message = getDiagnosticMessage(code2) ?? "...here";
926
- marker.relatedInformation.push({
927
- message,
928
- resource: model.uri,
929
- startLineNumber,
930
- startColumn,
931
- endLineNumber,
932
- endColumn
933
- });
934
- }
935
- }
936
- return marker;
937
- };
938
- async function makeModelMarkers(model, result) {
939
- const { version } = result;
940
- if (version !== model.getVersionId()) return null;
941
- const errors = result.errors.map((d) => makeMarker(model, d, MarkerSeverity.Error));
942
- const warnings = result.warnings.map((d) => makeMarker(model, d, MarkerSeverity.Warning));
943
- const infos = result.infos.map((d) => makeMarker(model, d, MarkerSeverity.Info));
944
- const hints = result.hints.map((d) => makeMarker(model, d, MarkerSeverity.Hint));
945
- const markers = [...errors, ...warnings, ...infos, ...hints];
946
- const { globals } = result.groupedTags(model);
947
- if (globals.length) {
948
- const context = await Provider.getContext(model);
949
- for (const g of globals) {
950
- const { name } = g;
951
- if (!context.has(name)) {
952
- const message = formatMessage(model, DiagnosticCode3.GlobalVariableNotDeclared, name);
953
- for (const ref of g.references) {
954
- markers.push(
955
- makeMarkerData(
956
- model,
957
- ref.range,
958
- DiagnosticCode3.GlobalVariableNotDeclared,
959
- message,
960
- MarkerSeverity.Warning
961
- )
962
- );
963
- }
964
- continue;
965
- }
966
- const deprecated = isDeprecatedGlobal(context, name);
967
- if (deprecated) {
968
- const replacement = deprecated.use;
969
- if (replacement) {
970
- const message = formatMessage(model, deprecated.message, replacement);
971
- for (const ref of g.references) {
972
- markers.push(
973
- makeMarkerData(model, ref.range, deprecated.message, message, MarkerSeverity.Hint, [
974
- MarkerTag.Deprecated
975
- ])
976
- );
977
- }
978
- } else {
979
- for (const ref of g.references) {
980
- markers.push(
981
- makeMarkerData(model, ref.range, deprecated.message, void 0, MarkerSeverity.Hint, [
982
- MarkerTag.Deprecated
983
- ])
984
- );
985
- }
986
- }
987
- }
988
- }
989
- }
990
- return markers;
991
- }
992
-
993
- // src/lsp/worker-helper.ts
994
- var cache = /* @__PURE__ */ new Map();
995
- var worker = void 0;
996
- var CACHE_MAX_AGE = 3e4;
997
- setInterval(() => {
998
- const now = Date.now();
999
- for (const [key, { lastAccess }] of cache) {
1000
- if (now - lastAccess > CACHE_MAX_AGE) {
1001
- cache.delete(key);
1002
- }
1003
- }
1004
- }, CACHE_MAX_AGE);
1005
- async function compileWorker(req) {
1006
- if (!worker) {
1007
- const w = new Worker(new URL("#lsp/worker", import.meta.url), {
1008
- type: "module",
1009
- name: "@mirascript/lsp-server"
1010
- });
1011
- worker = new Promise((resolve, reject) => {
1012
- const onError = (e) => {
1013
- cleanUp();
1014
- reject(new Error(`Worker failed to start: ${e.message}`));
1015
- };
1016
- const onMessage = (e) => {
1017
- if (e.data === "mirascript lsp ready") {
1018
- cleanUp();
1019
- resolve(w);
1020
- } else if (e.data instanceof Error) {
1021
- cleanUp();
1022
- reject(e.data);
1023
- }
1024
- };
1025
- w.addEventListener("error", onError);
1026
- w.addEventListener("message", onMessage);
1027
- const cleanUp = () => {
1028
- w.removeEventListener("error", onError);
1029
- w.removeEventListener("message", onMessage);
1030
- };
1031
- setTimeout(() => {
1032
- onError(new ErrorEvent("error", { message: "Worker did not respond in time" }));
1033
- }, 3e4);
1034
- });
1035
- }
1036
- try {
1037
- await worker;
1038
- } catch (ex) {
1039
- console.error("Failed to initialize worker, use sync compile:", ex);
1040
- USE_WORKER = false;
1041
- return compileSync(req);
1042
- }
1043
- const instance = await worker;
1044
- instance.postMessage(req);
1045
- const [key, version, source] = req;
1046
- const [_key, _version, result] = await new Promise((resolve, reject) => {
1047
- const onMessage = (e) => {
1048
- if (e.data[0] === key && e.data[1] === version) {
1049
- instance.removeEventListener("message", onMessage);
1050
- if (e.data[2] instanceof Error) {
1051
- reject(e.data[2]);
1052
- } else {
1053
- resolve(e.data);
1054
- }
1055
- }
1056
- };
1057
- instance.addEventListener("message", onMessage);
1058
- });
1059
- return new CompileResult(key, version, source, result);
1060
- }
1061
- var compileImpl;
1062
- async function compileSync(req) {
1063
- const [key, version, script, mode] = req;
1064
- if (compileImpl == null) {
1065
- const mod = await import("./worker.js");
1066
- compileImpl = mod.compile;
1067
- }
1068
- const result = compileImpl(script, mode);
1069
- return new CompileResult(key, version, script, result);
1070
- }
1071
- var USE_WORKER = typeof Worker === "function";
1072
- async function compile(model) {
1073
- const version = model.getVersionId();
1074
- const mode = model.getLanguageId() === "mirascript-template" ? "Template" : "Script";
1075
- const cacheKey = model.id;
1076
- const cached = cache.get(cacheKey);
1077
- if (cached?.version === version && cached.mode === mode) {
1078
- cached.lastAccess = Date.now();
1079
- return cached.result;
1080
- }
1081
- const value = model.getValue();
1082
- const req = [cacheKey, version, value, mode];
1083
- const res = USE_WORKER ? compileWorker(req) : compileSync(req);
1084
- void res.then(async (result) => {
1085
- if (model.isDisposed()) return;
1086
- const setModelMarkers = editor?.setModelMarkers;
1087
- if (typeof setModelMarkers != "function") return;
1088
- const markers = await makeModelMarkers(model, result);
1089
- if (!markers) return;
1090
- setModelMarkers(model, "mirascript", markers);
1091
- });
1092
- const item = {
1093
- version,
1094
- lastAccess: Date.now(),
1095
- mode,
1096
- result: res
1097
- };
1098
- cache.set(cacheKey, item);
1099
- res.catch(() => {
1100
- const current = cache.get(cacheKey);
1101
- if (current === item) {
1102
- cache.delete(cacheKey);
1103
- }
1104
- });
1105
- return res;
1106
- }
1107
-
1108
- // src/lsp/providers/base.ts
1109
- var contextProvider;
1110
- var DEFAULT_MONACO_CONTEXT = Object.freeze({
1111
- get(key) {
1112
- return DefaultVmContext.get(key);
1113
- },
1114
- getOrUndefined(key) {
1115
- return DefaultVmContext.has(key) ? DefaultVmContext.get(key) : void 0;
1116
- },
1117
- has(key) {
1118
- return DefaultVmContext.has(key);
1119
- },
1120
- keys() {
1121
- return DefaultVmContext.keys();
1122
- },
1123
- describe(key) {
1124
- return void 0;
1125
- }
1126
- });
1127
- async function getContextImpl(model, clearCache) {
1128
- try {
1129
- const context = await contextProvider?.(model);
1130
- if (!context) {
1131
- return DEFAULT_MONACO_CONTEXT;
1132
- }
1133
- const monacoContext = Object.freeze({
1134
- get(key) {
1135
- try {
1136
- return context.get(key);
1137
- } catch {
1138
- clearCache();
1139
- return DEFAULT_MONACO_CONTEXT.get(key);
1140
- }
1141
- },
1142
- getOrUndefined(key) {
1143
- try {
1144
- return context.has(key) ? context.get(key) : void 0;
1145
- } catch {
1146
- clearCache();
1147
- return DEFAULT_MONACO_CONTEXT.getOrUndefined(key);
1148
- }
1149
- },
1150
- has(key) {
1151
- try {
1152
- return context.has(key);
1153
- } catch {
1154
- clearCache();
1155
- return DEFAULT_MONACO_CONTEXT.has(key);
1156
- }
1157
- },
1158
- keys() {
1159
- try {
1160
- return context.keys();
1161
- } catch {
1162
- clearCache();
1163
- return DEFAULT_MONACO_CONTEXT.keys();
1164
- }
1165
- },
1166
- describe(key) {
1167
- try {
1168
- return context.describe?.(key) || void 0;
1169
- } catch {
1170
- clearCache();
1171
- return DEFAULT_MONACO_CONTEXT.describe(key);
1172
- }
1173
- }
1174
- });
1175
- return monacoContext;
1176
- } catch (ex) {
1177
- console.error("Error getting MiraScript Monaco context:", ex);
1178
- return DEFAULT_MONACO_CONTEXT;
1179
- }
1180
- }
1181
- var cachedContext = null;
1182
- var Provider = class _Provider {
1183
- constructor(enabled = () => true) {
1184
- this.enabled = enabled;
1185
- this.displayName = "MiraScript LSP";
1186
- this._debugDisplayName = "MiraScript LSP";
1187
- this._onDidChange = null;
1188
- }
1189
- /** 是否启用 */
1190
- get isEnabled() {
1191
- return this.enabled();
1192
- }
1193
- /** 设置全局变量提供者 */
1194
- static setContextProvider(provider) {
1195
- contextProvider = provider;
1196
- cachedContext = null;
1197
- }
1198
- /** 获取编译结果 */
1199
- static async getCompileResult(model) {
1200
- if (model.uri.scheme === "mirascript") {
1201
- return void 0;
1202
- }
1203
- return await compile(model);
1204
- }
1205
- /** 获取编译结果 */
1206
- async getCompileResult(model) {
1207
- if (!this.isEnabled) return void 0;
1208
- return _Provider.getCompileResult(model);
1209
- }
1210
- /** 获取执行上下文(全局变量) */
1211
- static async getContext(model) {
1212
- if (cachedContext?.[0] === model) {
1213
- return cachedContext[1];
1214
- }
1215
- const clearCache = () => {
1216
- if (cachedContext === cache2) {
1217
- cachedContext = null;
1218
- }
1219
- };
1220
- const context = getContextImpl(model, clearCache);
1221
- const cache2 = [model, context];
1222
- cachedContext = cache2;
1223
- setTimeout(clearCache, 100);
1224
- return context;
1225
- }
1226
- /** 获取执行上下文(全局变量) */
1227
- async getContext(model) {
1228
- return _Provider.getContext(model);
1229
- }
1230
- /** 获取当前位置的值 */
1231
- async getValueAt(model, position) {
1232
- const compiled = await this.getCompileResult(model);
1233
- if (!compiled) return void 0;
1234
- const d = compiled.variableAccessAt(model, position);
1235
- if (d) return { range: d.range, variable: d };
1236
- const word = wordAt(model, position);
1237
- if (word) {
1238
- const a = compiled.fieldAccessAt(model, {
1239
- lineNumber: position.lineNumber,
1240
- column: word.range.endColumn
1241
- });
1242
- if (a) return { range: word.range, fields: a };
1243
- }
1244
- return void 0;
1245
- }
1246
- /** @inheritdoc */
1247
- get onDidChange() {
1248
- this._onDidChange ??= new Emitter();
1249
- return this._onDidChange.event;
1250
- }
1251
- /** 触发 onDidChange */
1252
- emitDidChange() {
1253
- this._onDidChange?.fire(this);
1254
- }
1255
- };
1256
-
1257
- // src/lsp/providers/code-action-provider.ts
1258
- import { DiagnosticCode as DiagnosticCode4 } from "@mirascript/constants";
1259
- function createCodeAction(result, context, model, marker) {
1260
- const code = getDiagnosticCode(marker);
1261
- if (!code) return void 0;
1262
- const range = Range.lift(marker);
1263
- const action = {
1264
- title: "",
1265
- diagnostics: [marker]
1266
- };
1267
- const edits = (...textEdits) => {
1268
- const edits2 = [];
1269
- for (const textEdit of textEdits) {
1270
- if (textEdit == null) continue;
1271
- edits2.push({
1272
- resource: model.uri,
1273
- versionId: result.version,
1274
- textEdit
1275
- });
1276
- }
1277
- return { edits: edits2 };
1278
- };
1279
- if (code === DiagnosticCode4.PreferUppercaseConstant) {
1280
- const current = model.getValueInRange(range);
1281
- const uppercase = current.toUpperCase();
1282
- if (current === uppercase || !Object.is(context.getOrUndefined(current), context.getOrUndefined(uppercase))) {
1283
- return void 0;
1284
- }
1285
- action.title = "转换为大写常量";
1286
- action.kind = "quickfix";
1287
- action.edit = edits({
1288
- range,
1289
- text: uppercase
1290
- });
1291
- } else if (code === DiagnosticCode4.PreferParenthesesForRecordLiteral) {
1292
- const current = model.getValueInRange(range);
1293
- let fixed = current;
1294
- if (current.startsWith("{ ")) {
1295
- fixed = `(${fixed.slice(2)}`;
1296
- } else if (current.startsWith("{")) {
1297
- fixed = `(${fixed.slice(1)}`;
1298
- }
1299
- if (current.endsWith(" }")) {
1300
- fixed = `${fixed.slice(0, -2)})`;
1301
- } else if (current.endsWith("}")) {
1302
- fixed = `${fixed.slice(0, -1)})`;
1303
- }
1304
- if (fixed === current) {
1305
- return void 0;
1306
- }
1307
- const prefix = model.getValueInRange({
1308
- startLineNumber: range.startLineNumber,
1309
- startColumn: range.startColumn - 1,
1310
- endLineNumber: range.startLineNumber,
1311
- endColumn: range.startColumn
1312
- });
1313
- if (prefix === "$") {
1314
- fixed = `(${fixed})`;
1315
- }
1316
- action.title = `转换为使用圆括号的记录字面量`;
1317
- action.kind = "quickfix";
1318
- action.edit = edits({
1319
- range,
1320
- text: fixed
1321
- });
1322
- } else if (code === DiagnosticCode4.PreferLogicalOperatorAnd || code === DiagnosticCode4.PreferLogicalOperatorOr || code === DiagnosticCode4.PreferLogicalOperatorNot) {
1323
- let range0 = range;
1324
- const current = model.getValueInRange(range);
1325
- let fixed;
1326
- if (current === "and") {
1327
- fixed = "&&";
1328
- } else if (current === "or") {
1329
- fixed = "||";
1330
- } else if (current === "not") {
1331
- const range1 = range.setEndPosition(range.endLineNumber, range.endColumn + 1);
1332
- const current1 = model.getValueInRange(range1);
1333
- if (current1.trim() === "not") {
1334
- range0 = range1;
1335
- }
1336
- fixed = "!";
1337
- }
1338
- if (!fixed) {
1339
- return void 0;
1340
- }
1341
- action.title = `转换为 '${fixed}' 运算符`;
1342
- action.kind = "quickfix";
1343
- action.edit = edits({
1344
- range: range0,
1345
- text: fixed
1346
- });
1347
- } else if (code === DiagnosticCode4.UnnecessaryParentheses) {
1348
- const current = model.getValueInRange(range);
1349
- let fixed = current;
1350
- if (current.startsWith("(")) {
1351
- fixed = fixed.slice(1);
1352
- }
1353
- if (current.endsWith(")")) {
1354
- fixed = fixed.slice(0, -1);
1355
- }
1356
- if (fixed === current) {
1357
- return void 0;
1358
- }
1359
- action.title = "移除不必要的括号";
1360
- action.kind = "quickfix";
1361
- action.edit = edits({
1362
- range,
1363
- text: fixed
1364
- });
1365
- } else if (code === DiagnosticCode4.PreferIfExpression) {
1366
- const tag = result.tags.find(
1367
- (tag2) => tag2.code === DiagnosticCode4.IfExpression && Range.equalsRange(tag2.range, range)
1368
- );
1369
- if (!tag) return void 0;
1370
- const questionMark = tag.references.find((ref) => ref.code === DiagnosticCode4.KeywordIf);
1371
- const colon = tag.references.find((ref) => ref.code === DiagnosticCode4.KeywordElse);
1372
- if (!questionMark || !colon) return void 0;
1373
- const condRange = Range.fromPositions(
1374
- range.getStartPosition(),
1375
- model.getPositionAt(model.getOffsetAt(Range.getStartPosition(questionMark.range)))
1376
- );
1377
- const thenRange = Range.fromPositions(
1378
- model.getPositionAt(model.getOffsetAt(Range.getEndPosition(questionMark.range))),
1379
- model.getPositionAt(model.getOffsetAt(Range.getStartPosition(colon.range)))
1380
- );
1381
- const elseRange = Range.fromPositions(
1382
- model.getPositionAt(model.getOffsetAt(Range.getEndPosition(colon.range))),
1383
- range.getEndPosition()
1384
- );
1385
- const cond = model.getValueInRange(condRange).trim();
1386
- const thenExpr = model.getValueInRange(thenRange).trim();
1387
- const elseExpr = model.getValueInRange(elseRange).trim();
1388
- const wrapIfNeeded = (expr, elseBranch) => {
1389
- if (elseBranch && expr.startsWith("if ") && expr.endsWith("}")) {
1390
- return expr;
1391
- }
1392
- if (expr.startsWith("{") && expr.endsWith("}") && !expr.includes(":")) {
1393
- return expr;
1394
- }
1395
- if (expr.includes("\n")) {
1396
- return `{
1397
- ${expr}
1398
- }`;
1399
- }
1400
- return `{ ${expr} }`;
1401
- };
1402
- const fixed = `if ${cond} ${wrapIfNeeded(thenExpr, false)} else ${wrapIfNeeded(elseExpr, true)}`;
1403
- action.title = "转换为 if 表达式";
1404
- action.kind = "quickfix";
1405
- action.edit = edits({
1406
- range,
1407
- text: fixed
1408
- });
1409
- }
1410
- if (action.title) return action;
1411
- return void 0;
1412
- }
1413
- var CodeActionProvider = class extends Provider {
1414
- /** @inheritdoc */
1415
- async provideCodeActions(model, range, { markers, only, trigger }, token) {
1416
- const result = await this.getCompileResult(model);
1417
- if (!result) return void 0;
1418
- const context = await this.getContext(model);
1419
- const actions = [];
1420
- for (const marker of markers) {
1421
- const action = createCodeAction(result, context, model, marker);
1422
- if (action == null || (only && action.kind ? action.kind !== only : false)) {
1423
- continue;
1424
- }
1425
- actions.push(action);
1426
- }
1427
- return {
1428
- actions,
1429
- dispose: () => void 0
1430
- };
1431
- }
1432
- };
1433
-
1434
- // src/lsp/providers/code-lens-provider.ts
1435
- import { DiagnosticCode as DiagnosticCode5 } from "@mirascript/constants";
1436
- var CodeLensProvider = class extends Provider {
1437
- /** @inheritdoc */
1438
- async provideCodeLenses(model, token) {
1439
- const result = await this.getCompileResult(model);
1440
- if (!result) return void 0;
1441
- const lenses = [];
1442
- for (const { definition, references } of result.groupedTags(model).locals) {
1443
- if (definition.code === DiagnosticCode5.LocalFunction || definition.code === DiagnosticCode5.LocalModule) {
1444
- lenses.push({
1445
- range: definition.range,
1446
- command: {
1447
- id: "editor.action.findReferences",
1448
- title: `${references.length} 个引用`,
1449
- arguments: [model.uri, Range.getStartPosition(definition.range)]
1450
- }
1451
- });
1452
- }
1453
- }
1454
- return { lenses };
1455
- }
1456
- };
1457
-
1458
- // src/lsp/providers/color-provider.ts
1459
- import { DiagnosticCode as DiagnosticCode6 } from "@mirascript/constants";
1460
- var REG_COLOR_STR = /^(@*)(['"`])(#(?:[0-9a-f]{6}|[0-9a-f]{3}|[0-9a-f]{8}|[0-9a-f]{4}))\2\1$/iu;
1461
- var { parseInt } = Number;
1462
- function parseColorString(text) {
1463
- const colorMatch = REG_COLOR_STR.exec(text);
1464
- if (!colorMatch) {
1465
- return void 0;
1466
- }
1467
- const ats = colorMatch[1] || "";
1468
- const quote = colorMatch[2] || "";
1469
- const colorString = colorMatch[3];
1470
- let color;
1471
- if (colorString.startsWith("#")) {
1472
- const colorCode = colorString.slice(1);
1473
- if (colorCode.length === 3) {
1474
- color = {
1475
- red: parseInt(colorCode[0] + colorCode[0], 16) / 255,
1476
- green: parseInt(colorCode[1] + colorCode[1], 16) / 255,
1477
- blue: parseInt(colorCode[2] + colorCode[2], 16) / 255,
1478
- alpha: 1
1479
- };
1480
- } else if (colorCode.length === 6) {
1481
- color = {
1482
- red: parseInt(colorCode.slice(0, 2), 16) / 255,
1483
- green: parseInt(colorCode.slice(2, 4), 16) / 255,
1484
- blue: parseInt(colorCode.slice(4, 6), 16) / 255,
1485
- alpha: 1
1486
- // 假设不透明
1487
- };
1488
- } else if (colorCode.length === 8) {
1489
- color = {
1490
- red: parseInt(colorCode.slice(0, 2), 16) / 255,
1491
- green: parseInt(colorCode.slice(2, 4), 16) / 255,
1492
- blue: parseInt(colorCode.slice(4, 6), 16) / 255,
1493
- alpha: parseInt(colorCode.slice(6, 8), 16) / 255
1494
- };
1495
- } else if (colorCode.length === 4) {
1496
- color = {
1497
- red: parseInt(colorCode[0] + colorCode[0], 16) / 255,
1498
- green: parseInt(colorCode[1] + colorCode[1], 16) / 255,
1499
- blue: parseInt(colorCode[2] + colorCode[2], 16) / 255,
1500
- alpha: parseInt(colorCode[3] + colorCode[3], 16) / 255
1501
- };
1502
- } else {
1503
- return void 0;
1504
- }
1505
- } else {
1506
- return void 0;
1507
- }
1508
- return {
1509
- ats,
1510
- quote,
1511
- colorString,
1512
- color
1513
- };
1514
- }
1515
- var ColorProvider = class extends Provider {
1516
- /** @inheritdoc */
1517
- async provideDocumentColors(model, token) {
1518
- const compiled = await this.getCompileResult(model);
1519
- if (!compiled) return void 0;
1520
- const info = [];
1521
- for (const { range, code } of compiled.groupedTags(model).ranges) {
1522
- if (code !== DiagnosticCode6.String) continue;
1523
- if (range.startLineNumber !== range.endLineNumber) {
1524
- continue;
1525
- }
1526
- const text = model.getValueInRange(range);
1527
- const parsed = parseColorString(text);
1528
- if (!parsed) continue;
1529
- info.push({
1530
- range: {
1531
- startLineNumber: range.startLineNumber,
1532
- startColumn: range.startColumn + parsed.ats.length + parsed.quote.length,
1533
- endLineNumber: range.endLineNumber,
1534
- endColumn: range.endColumn - parsed.ats.length - parsed.quote.length
1535
- },
1536
- color: parsed.color
1537
- });
1538
- }
1539
- return info;
1540
- }
1541
- /** @inheritdoc */
1542
- provideColorPresentations(model, colorInfo, token) {
1543
- const { color } = colorInfo;
1544
- return [
1545
- {
1546
- label: `#${Math.round(color.red * 255).toString(16).padStart(2, "0")}${Math.round(color.green * 255).toString(16).padStart(2, "0")}${Math.round(color.blue * 255).toString(16).padStart(2, "0")}${color.alpha >= 1 ? "" : Math.round(color.alpha * 255).toString(16).padStart(2, "0")}`
1547
- }
1548
- ];
1549
- }
1550
- };
1551
-
1552
- // src/lsp/providers/completion-item-provider.ts
1553
- import {
1554
- getVmFunctionInfo as getVmFunctionInfo2,
1555
- isVmExtern as isVmExtern2,
1556
- isVmModule as isVmModule2,
1557
- isVmWrapper as isVmWrapper2,
1558
- serialize as serialize2
1559
- } from "@mirascript/mirascript";
1560
- import { DiagnosticCode as DiagnosticCode7 } from "@mirascript/mirascript/subtle";
1561
- import { KEYWORDS as HELP_KEYWORDS } from "@mirascript/help";
1562
- var DESC_GLOBAL = "(global)";
1563
- var DESC_LOCAL = "(local)";
1564
- var DESC_FIELD = "(field)";
1565
- var SUGGEST_KEYWORDS = [];
1566
- var loadSuggestKeywords = () => {
1567
- if (SUGGEST_KEYWORDS.length > 0) return SUGGEST_KEYWORDS;
1568
- for (const kw of KEYWORDS) {
1569
- if (RESERVED_KEYWORDS.includes(kw)) continue;
1570
- SUGGEST_KEYWORDS.push(kw);
1571
- }
1572
- return SUGGEST_KEYWORDS;
1573
- };
1574
- var COMMON_GLOBAL_SUGGESTIONS = (range, extension) => {
1575
- const suggestions = [
1576
- {
1577
- label: "type",
1578
- kind: languages.CompletionItemKind.Keyword,
1579
- insertText: "type",
1580
- commitCharacters: ["("],
1581
- documentation: { value: HELP_KEYWORDS.type },
1582
- range
1583
- },
1584
- {
1585
- label: "global",
1586
- kind: languages.CompletionItemKind.Keyword,
1587
- insertText: "global",
1588
- commitCharacters: [".", "["],
1589
- documentation: { value: HELP_KEYWORDS.global },
1590
- range
1591
- }
1592
- ];
1593
- if (!extension) {
1594
- suggestions.push(
1595
- {
1596
- label: { label: "if", description: "If 表达式" },
1597
- kind: languages.CompletionItemKind.Snippet,
1598
- insertText: "if ${1:condition} {\n $0\n}",
1599
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1600
- documentation: {
1601
- value: `使用 \`if\` 表达式进行条件判断。${codeblock("if condition {\n // code\n}")}`
1602
- },
1603
- range
1604
- },
1605
- {
1606
- label: { label: "ifelse", description: "If-Else 表达式" },
1607
- kind: languages.CompletionItemKind.Snippet,
1608
- insertText: "if ${1:condition} {\n $0\n} else {\n \n}",
1609
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1610
- documentation: {
1611
- value: `使用 \`ifelse\` 表达式进行条件判断。${codeblock("if condition {\n // code\n} else {\n // code\n}")}`
1612
- },
1613
- range
1614
- },
1615
- {
1616
- label: { label: "match", description: "Match 表达式" },
1617
- kind: languages.CompletionItemKind.Snippet,
1618
- insertText: "match ${1:value} {\n case ${2:case1} {\n $0\n }\n case ${3:case2} {\n \n }\n case _ {\n \n }\n}",
1619
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1620
- documentation: {
1621
- value: `使用 \`match\` 表达式进行模式匹配。${codeblock("match value {\n case case1 {\n // code\n }\n case case2 {\n // code\n }\n case _ {\n // code\n }\n}")}`
1622
- },
1623
- range
1624
- },
1625
- {
1626
- label: { label: "loop", description: "Loop 表达式" },
1627
- kind: languages.CompletionItemKind.Snippet,
1628
- insertText: "loop {\n $0\n}",
1629
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1630
- documentation: {
1631
- value: `使用 \`loop\` 表达式进行无限循环。${codeblock("loop {\n // code\n}")}`
1632
- },
1633
- range
1634
- },
1635
- {
1636
- label: { label: "while", description: "While 表达式" },
1637
- kind: languages.CompletionItemKind.Snippet,
1638
- insertText: "while ${1:condition} {\n $0\n}",
1639
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1640
- documentation: {
1641
- value: `使用 \`while\` 表达式进行条件循环。${codeblock("while condition {\n // code\n}")}`
1642
- },
1643
- range
1644
- },
1645
- {
1646
- label: { label: "whileelse", description: "While-Else 表达式" },
1647
- kind: languages.CompletionItemKind.Snippet,
1648
- insertText: "while ${1:condition} {\n $0\n} else {\n \n}",
1649
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1650
- documentation: {
1651
- value: `使用 \`whileelse\` 表达式进行条件循环。${codeblock("while condition {\n // code\n} else {\n // code\n}")}`
1652
- },
1653
- range
1654
- },
1655
- {
1656
- label: { label: "for", description: "For 表达式" },
1657
- kind: languages.CompletionItemKind.Snippet,
1658
- insertText: "for ${1:item} in ${2:collection} {\n $0\n}",
1659
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1660
- documentation: {
1661
- value: `使用 \`for\` 表达式进行迭代循环。${codeblock("for item in collection {\n // code\n}")}`
1662
- },
1663
- range
1664
- },
1665
- {
1666
- label: { label: "forelse", description: "For-Else 表达式" },
1667
- kind: languages.CompletionItemKind.Snippet,
1668
- insertText: "for ${1:item} in ${2:collection} {\n $0\n} else {\n \n}",
1669
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1670
- documentation: {
1671
- value: `使用 \`forelse\` 表达式进行迭代循环。${codeblock("for item in collection {\n // code\n} else {\n // code\n}")}`
1672
- },
1673
- range
1674
- },
1675
- {
1676
- label: { label: "fn", description: "Fn 语句" },
1677
- kind: languages.CompletionItemKind.Snippet,
1678
- insertText: "fn ${1:name}(${2:params}) {\n $0\n}",
1679
- insertTextRules: languages.CompletionItemInsertTextRule.InsertAsSnippet,
1680
- documentation: {
1681
- value: `使用 \`fn\` 语句进行函数声明。${codeblock("fn name(params) {\n // code\n}")}`
1682
- },
1683
- range
1684
- }
1685
- );
1686
- for (const kw of loadSuggestKeywords()) {
1687
- const exist = suggestions.find(
1688
- (item) => item.label === kw && item.kind === languages.CompletionItemKind.Keyword
1689
- );
1690
- if (exist) continue;
1691
- suggestions.push(kwSuggestion(kw, range));
1692
- }
1693
- }
1694
- return suggestions;
1695
- };
1696
- function kwSuggestion(kw, range) {
1697
- const doc = HELP_KEYWORDS[kw];
1698
- return {
1699
- label: kw,
1700
- kind: languages.CompletionItemKind.Keyword,
1701
- insertText: kw,
1702
- documentation: doc ? { value: doc } : void 0,
1703
- range
1704
- };
1705
- }
1706
- function filterText(key, char) {
1707
- if (char == null || key.startsWith(char)) return key;
1708
- if (key.startsWith("@")) return key.replace(/^@+/, "");
1709
- if (key.startsWith("$")) return key.replace(/^\$+/, "");
1710
- return key;
1711
- }
1712
- function completion(model, description, key, value, fn, field) {
1713
- let detail = "";
1714
- let kind;
1715
- if (fn == null && typeof value == "function") {
1716
- fn = getVmFunctionInfo2(value);
1717
- }
1718
- if (fn != null) {
1719
- detail = paramsList(model, fn);
1720
- kind = field ? languages.CompletionItemKind.Function : languages.CompletionItemKind.Method;
1721
- } else if (isVmModule2(value)) {
1722
- kind = languages.CompletionItemKind.Module;
1723
- } else if (isVmExtern2(value) && typeof value.value == "function") {
1724
- if (value.value.prototype != null && (key[0] ?? "").toUpperCase() === key[0]) {
1725
- kind = languages.CompletionItemKind.Class;
1726
- } else {
1727
- detail = "(..)";
1728
- kind = value.thisArg ? languages.CompletionItemKind.Method : languages.CompletionItemKind.Function;
1729
- }
1730
- } else if (!field && key.startsWith("@")) {
1731
- kind = languages.CompletionItemKind.Constant;
1732
- } else {
1733
- kind = field ? languages.CompletionItemKind.Field : languages.CompletionItemKind.Variable;
1734
- }
1735
- return {
1736
- label: { label: key, description, detail },
1737
- kind,
1738
- commitCharacters: fn ? ["!", "("] : ["!", ".", "[", "("],
1739
- vmValue: value,
1740
- isField: field
1741
- };
1742
- }
1743
- var CompletionItemProvider = class extends Provider {
1744
- constructor() {
1745
- super(...arguments);
1746
- this.triggerCharacters = [".", ":"];
1747
- }
1748
- /** 查找全局变量 */
1749
- async completeGlobal(model, char, locals, range, hasGlobalPrefix) {
1750
- const global = await this.getContext(model);
1751
- const suggestions = [];
1752
- const localKeys = new Set(locals.map((item) => item.insertText));
1753
- for (const key of new Set(global.keys())) {
1754
- if (!global.has(key)) continue;
1755
- const element = global.get(key);
1756
- let prefix = key;
1757
- const edits = [];
1758
- if (!REG_IDENTIFIER_FULL.test(key)) {
1759
- const kStr = serialize2(key);
1760
- if (hasGlobalPrefix) {
1761
- prefix = `[${kStr}]`;
1762
- edits.push({
1763
- range: {
1764
- startLineNumber: range.replace.startLineNumber,
1765
- startColumn: range.replace.startColumn - 1,
1766
- endLineNumber: range.replace.endLineNumber,
1767
- endColumn: range.replace.endColumn
1768
- },
1769
- text: ""
1770
- });
1771
- } else {
1772
- prefix = `global[${serialize2(key)}]`;
1773
- }
1774
- } else if (!hasGlobalPrefix && (localKeys.has(key) || isKeyword(key))) {
1775
- prefix = `global.${key}`;
1776
- }
1777
- if (isVmModule2(element)) {
1778
- for (const f of element.keys()) {
1779
- if (char && !f.toLowerCase().includes(char)) {
1780
- continue;
1781
- }
1782
- const field = element.get(f);
1783
- if (field === void 0) continue;
1784
- suggestions.push({
1785
- insertText: `${prefix}.${f}`,
1786
- filterText: filterText(f, char),
1787
- range,
1788
- additionalTextEdits: edits,
1789
- vmParent: element,
1790
- ...completion(model, DESC_GLOBAL, `${key}.${f}`, field, void 0, true)
1791
- });
1792
- }
1793
- }
1794
- if (char && !key.toLowerCase().includes(char)) {
1795
- continue;
1796
- }
1797
- if (isDeprecatedGlobal(global, key)) {
1798
- continue;
1799
- }
1800
- suggestions.push({
1801
- insertText: prefix,
1802
- filterText: filterText(key, char),
1803
- range,
1804
- additionalTextEdits: edits,
1805
- vmParent: global,
1806
- ...completion(model, DESC_GLOBAL, key, element, void 0, false)
1807
- });
1808
- }
1809
- return suggestions;
1810
- }
1811
- /** 查找局部变量 */
1812
- async completeLocal(model, position, char, range) {
1813
- const compiled = await this.getCompileResult(model);
1814
- if (!compiled) return [];
1815
- const suggestions = [];
1816
- let scope = compiled.scopeAt(model, position);
1817
- const locals = /* @__PURE__ */ new Set();
1818
- while (scope) {
1819
- for (const { definition, fn } of scope.locals) {
1820
- const name = definition.code === DiagnosticCode7.ParameterIt ? "it" : model.getValueInRange(definition.range);
1821
- if (char && !name.toLowerCase().includes(char)) continue;
1822
- if (locals.has(name)) continue;
1823
- locals.add(name);
1824
- const suggestion = {
1825
- insertText: name,
1826
- filterText: filterText(name, char),
1827
- range,
1828
- ...completion(model, DESC_LOCAL, name, void 0, fn, false)
1829
- };
1830
- if (definition.code === DiagnosticCode7.LocalModule) {
1831
- suggestion.kind = languages.CompletionItemKind.Module;
1832
- } else if (definition.code === DiagnosticCode7.LocalFunction) {
1833
- suggestion.kind = languages.CompletionItemKind.Function;
1834
- }
1835
- suggestions.push(suggestion);
1836
- }
1837
- if (!scope.parent) break;
1838
- scope = scope.parent;
1839
- }
1840
- return suggestions;
1841
- }
1842
- /** 查找变量字段 */
1843
- async completeFields(model, position, char, range) {
1844
- const compiled = await this.getCompileResult(model);
1845
- if (!compiled) return [];
1846
- const access = compiled.fieldAccessAt(model, position);
1847
- if (!access || access.fields.length === 0) return [];
1848
- const { def, fields } = access;
1849
- if ("definition" in def.def) {
1850
- return [];
1851
- }
1852
- const vmGlobal = await this.getContext(model);
1853
- fields.pop();
1854
- const [, value] = getDeep(vmGlobal, def.def.name, fields);
1855
- if (value == null || typeof value != "object") {
1856
- return [];
1857
- }
1858
- const keys = listFields(value, true);
1859
- const result = [];
1860
- for (const k of keys) {
1861
- const key = String(k);
1862
- if (char && !String(key).toLowerCase().includes(char)) {
1863
- continue;
1864
- }
1865
- if (!REG_IDENTIFIER_FULL.test(key) && !REG_ORDINAL_FULL.test(key)) {
1866
- continue;
1867
- }
1868
- const field = getField(value, key);
1869
- result.push({
1870
- insertText: key,
1871
- range,
1872
- vmParent: isVmWrapper2(value) ? value : void 0,
1873
- ...completion(model, DESC_FIELD, key, field, void 0, true)
1874
- });
1875
- }
1876
- return result;
1877
- }
1878
- /** 获取完成范围 */
1879
- toCompletionItemRanges(position, range) {
1880
- return {
1881
- replace: range,
1882
- insert: Range.fromPositions(Range.getStartPosition(range), position)
1883
- };
1884
- }
1885
- /** @inheritdoc */
1886
- async provideCompletionItems(model, position, context, token) {
1887
- const compiled = await this.getCompileResult(model);
1888
- if (!compiled) return void 0;
1889
- if (context.triggerCharacter === ".") {
1890
- const prevWord = model.getWordAtPosition({
1891
- lineNumber: position.lineNumber,
1892
- column: position.column - 1
1893
- });
1894
- if (prevWord?.word === "global") {
1895
- const globals2 = await this.completeGlobal(
1896
- model,
1897
- void 0,
1898
- [],
1899
- this.toCompletionItemRanges(position, {
1900
- startLineNumber: position.lineNumber,
1901
- startColumn: position.column,
1902
- endLineNumber: position.lineNumber,
1903
- endColumn: position.column
1904
- }),
1905
- true
1906
- );
1907
- return { suggestions: globals2 };
1908
- }
1909
- }
1910
- const word = wordAt(model, position);
1911
- const prev = model.getValueInRange({
1912
- startLineNumber: position.lineNumber,
1913
- startColumn: (word?.range.startColumn ?? position.column) - 2,
1914
- endLineNumber: position.lineNumber,
1915
- endColumn: word?.range.startColumn ?? position.column
1916
- });
1917
- if (context.triggerCharacter === ":" && prev !== "::") {
1918
- return void 0;
1919
- }
1920
- let char;
1921
- let range;
1922
- const def = compiled.variableAccessAt(model, position);
1923
- if (def) {
1924
- if (def.ref == null) {
1925
- const suggestions2 = [];
1926
- if (word && compiled.tags.some(
1927
- (t) => strictContainsPosition(t.range, position) && t.code === DiagnosticCode7.MatchExpression
1928
- )) {
1929
- suggestions2.push(
1930
- kwSuggestion("case", this.toCompletionItemRanges(position, word.range)),
1931
- kwSuggestion("if", this.toCompletionItemRanges(position, word.range))
1932
- );
1933
- }
1934
- return { suggestions: suggestions2 };
1935
- }
1936
- const d = def.def;
1937
- range = d.references[def.ref].range;
1938
- char = model.getValueInRange({
1939
- startLineNumber: range.startLineNumber,
1940
- startColumn: range.startColumn,
1941
- endLineNumber: range.startLineNumber,
1942
- endColumn: range.startColumn + 1
1943
- });
1944
- } else if (word) {
1945
- range = word.range;
1946
- char = word.word[0];
1947
- } else {
1948
- range = {
1949
- startLineNumber: position.lineNumber,
1950
- startColumn: position.column,
1951
- endLineNumber: position.lineNumber,
1952
- endColumn: position.column
1953
- };
1954
- }
1955
- char = char?.toLowerCase();
1956
- const completionRange = this.toCompletionItemRanges(position, range);
1957
- if (/[^.]\.$/u.test(prev)) {
1958
- const suggestions2 = await this.completeFields(model, position, char, completionRange);
1959
- return { suggestions: suggestions2 };
1960
- }
1961
- const suggestions = COMMON_GLOBAL_SUGGESTIONS(completionRange, prev === "::");
1962
- const locals = await this.completeLocal(model, position, char, completionRange);
1963
- const globals = await this.completeGlobal(model, char, locals, completionRange, false);
1964
- suggestions.push(...locals, ...globals);
1965
- return { suggestions };
1966
- }
1967
- /** @inheritdoc */
1968
- resolveCompletionItem(item, token) {
1969
- if (typeof item.label == "string") {
1970
- return item;
1971
- }
1972
- const { vmValue, isField, vmParent } = item;
1973
- const { label } = item.label;
1974
- if (vmValue !== void 0 || vmParent) {
1975
- if (item.documentation) return item;
1976
- const last = label.split(".").pop();
1977
- const def = valueDoc(last, vmValue, isField ? "field" : "hint", vmParent ?? null);
1978
- item.documentation = {
1979
- value: `${codeblock("\0" + def.script)}
1980
- ${def.doc.join("\n")}`
1981
- };
1982
- }
1983
- return item;
1984
- }
1985
- };
1986
-
1987
- // src/lsp/providers/definition-reference-provider.ts
1988
- var DefinitionReferenceProvider = class extends Provider {
1989
- constructor() {
1990
- super(...arguments);
1991
- /** 创建全局模型 */
1992
- this.createGlobalModel = (uri) => editor.createModel(``, "mirascript-doc", Uri.parse(uri));
1993
- }
1994
- #globalModel;
1995
- /** 全局模型 */
1996
- async getGlobalModel() {
1997
- if (!this.#globalModel || this.#globalModel.isDisposed()) {
1998
- this.#globalModel = await this.createGlobalModel("mirascript:///lib/global.mira") ?? void 0;
1999
- }
2000
- return this.#globalModel;
2001
- }
2002
- /** 准备要显示的定义 */
2003
- async prepareGlobal(model, paths, focus = 0) {
2004
- const globalModel = await this.getGlobalModel();
2005
- if (!globalModel) return void 0;
2006
- const globals = await this.getContext(model);
2007
- const code = [];
2008
- const focusRange = {
2009
- startColumn: 1,
2010
- startLineNumber: 1,
2011
- endColumn: 1,
2012
- endLineNumber: 1
2013
- };
2014
- for (const [index, path] of paths.entries()) {
2015
- const [name, ...access] = path;
2016
- const [parent, value] = getDeep(globals, name, access);
2017
- if (value === void 0) return void 0;
2018
- const { script, doc } = valueDoc(path.at(-1), value, "declare", parent);
2019
- if (index !== focus) {
2020
- code.push(...docComment(doc), ...script.split("\n"), "");
2021
- continue;
2022
- }
2023
- code.push(...docComment(doc));
2024
- const defName = path.at(-1);
2025
- const scriptLines = script.split("\n");
2026
- const decLine = scriptLines.findIndex((line) => line.includes(defName));
2027
- if (decLine < 0) {
2028
- focusRange.startLineNumber = code.length + 1;
2029
- code.push(...script.split("\n"));
2030
- focusRange.endLineNumber = code.length + 1;
2031
- } else {
2032
- code.push(...script.split("\n"));
2033
- const decLineText = scriptLines[decLine];
2034
- focusRange.startLineNumber = code.length - scriptLines.length + decLine + 1;
2035
- focusRange.endLineNumber = focusRange.startLineNumber;
2036
- const nameIndex = decLineText.indexOf(defName);
2037
- focusRange.startColumn = nameIndex + 1;
2038
- focusRange.endColumn = nameIndex + defName.length + 1;
2039
- }
2040
- code.push("");
2041
- }
2042
- globalModel.setValue(code.join("\n"));
2043
- return {
2044
- uri: globalModel.uri,
2045
- range: focusRange
2046
- };
2047
- }
2048
- /** @inheritdoc */
2049
- async provideDefinition(model, position, token) {
2050
- const value = await this.getValueAt(model, position);
2051
- if (!value) return void 0;
2052
- if ("variable" in value) {
2053
- const { def } = value.variable;
2054
- let link;
2055
- if ("name" in def) {
2056
- link = await this.prepareGlobal(model, [[def.name]]);
2057
- } else {
2058
- link = { uri: model.uri, range: def.definition.range };
2059
- }
2060
- if (!link) return void 0;
2061
- link.originSelectionRange = value.range;
2062
- return [link];
2063
- } else {
2064
- const {
2065
- def: { def },
2066
- fields
2067
- } = value.fields;
2068
- if ("name" in def) {
2069
- const link = await this.prepareGlobal(model, [
2070
- [def.name, ...fields]
2071
- ]);
2072
- if (!link) return void 0;
2073
- link.originSelectionRange = value.range;
2074
- return [link];
2075
- }
2076
- }
2077
- return void 0;
2078
- }
2079
- /** @inheritdoc */
2080
- async provideReferences(model, position, context, token) {
2081
- const value = await this.getValueAt(model, position);
2082
- if (!value) return void 0;
2083
- if ("variable" in value) {
2084
- const { def } = value.variable;
2085
- const links = def.references.map((u) => ({
2086
- uri: model.uri,
2087
- range: u.range
2088
- }));
2089
- if (context.includeDeclaration) {
2090
- if ("name" in def) {
2091
- const link = await this.prepareGlobal(model, [[def.name]]);
2092
- if (link) links.push(link);
2093
- } else if (!Range.isEmpty(def.definition.range)) {
2094
- links.push({ uri: model.uri, range: def.definition.range });
2095
- }
2096
- }
2097
- return links;
2098
- }
2099
- return void 0;
2100
- }
2101
- };
2102
-
2103
- // src/lsp/providers/document-highlight-provider.ts
2104
- import { DiagnosticCode as DiagnosticCode8 } from "@mirascript/mirascript/subtle";
2105
- var DocumentHighlightProvider = class extends Provider {
2106
- /** @inheritdoc */
2107
- async provideDocumentHighlights(model, position, token) {
2108
- const word = model.getWordAtPosition(position);
2109
- if (word && isKeyword(word.word)) {
2110
- const result = await this.highlightKeyword(model, position, word.word);
2111
- if (result) return result;
2112
- }
2113
- return this.getDocumentHighlightsFromDefinition(model, position);
2114
- }
2115
- /** 从 definition 生成 DocumentHighlight 列表 */
2116
- async getDocumentHighlightsFromDefinition(model, position) {
2117
- const compiled = await this.getCompileResult(model);
2118
- if (!compiled) return void 0;
2119
- const def = compiled.variableAccessAt(model, position)?.def;
2120
- if (!def) return void 0;
2121
- const links = def.references.map((u) => {
2122
- const { code, range } = u;
2123
- let kind = languages.DocumentHighlightKind.Read;
2124
- if (code === DiagnosticCode8.WriteLocal || code === DiagnosticCode8.ReadWriteLocal || code === DiagnosticCode8.RedeclareLocal) {
2125
- kind = languages.DocumentHighlightKind.Write;
2126
- }
2127
- return {
2128
- kind,
2129
- range
2130
- };
2131
- });
2132
- if ("definition" in def && !Range.isEmpty(def.definition.range)) {
2133
- links.push({
2134
- kind: languages.DocumentHighlightKind.Write,
2135
- range: def.definition.range
2136
- });
2137
- }
2138
- return links;
2139
- }
2140
- /** 高亮关键字 */
2141
- async highlightKeyword(model, position, word) {
2142
- const compiled = await this.getCompileResult(model);
2143
- if (!compiled) return void 0;
2144
- const kw = compiled.tagsReferences.find((kw2) => Range.containsPosition(kw2.range, position));
2145
- if (!kw) return void 0;
2146
- return kw.diagnostic.references.map((r) => ({
2147
- kind: languages.DocumentHighlightKind.Text,
2148
- range: r.range
2149
- }));
2150
- }
2151
- };
2152
-
2153
- // src/lsp/providers/document-symbol-provider.ts
2154
- import { DiagnosticCode as DiagnosticCode9 } from "@mirascript/constants";
2155
- var DocumentSymbolProvider = class extends Provider {
2156
- /** 构建树 */
2157
- handleScope(model, scope) {
2158
- const symbols = [];
2159
- const unhandledChildren = new Set(scope.children);
2160
- for (const { definition } of scope.locals) {
2161
- const { range } = definition;
2162
- let kind;
2163
- let name;
2164
- let children = [];
2165
- let allRange = range;
2166
- switch (definition.code) {
2167
- case DiagnosticCode9.ParameterIt:
2168
- if (definition.references.length === 0) {
2169
- continue;
2170
- }
2171
- name = `it`;
2172
- break;
2173
- case DiagnosticCode9.LocalFunction: {
2174
- kind = languages.SymbolKind.Function;
2175
- const funcScope = scope.children.find((s) => Range.compareRangesUsingStarts(s.range, range) > 0);
2176
- if (funcScope) {
2177
- allRange = Range.plusRange(range, funcScope.range);
2178
- children = this.handleScope(model, funcScope);
2179
- unhandledChildren.delete(funcScope);
2180
- }
2181
- break;
2182
- }
2183
- }
2184
- name ??= model.getValueInRange(definition.range);
2185
- kind ??= name.startsWith("@") ? languages.SymbolKind.Constant : languages.SymbolKind.Variable;
2186
- symbols.push({
2187
- name,
2188
- detail: "",
2189
- kind,
2190
- range: allRange,
2191
- tags: [],
2192
- selectionRange: range,
2193
- children
2194
- });
2195
- }
2196
- for (const child of unhandledChildren) {
2197
- symbols.push(...this.handleScope(model, child));
2198
- }
2199
- return symbols;
2200
- }
2201
- /** @inheritdoc */
2202
- async provideDocumentSymbols(model, token) {
2203
- const compiled = await this.getCompileResult(model);
2204
- if (!compiled) return void 0;
2205
- const root = compiled.scopes(model)[0];
2206
- if (!root) return void 0;
2207
- return this.handleScope(model, root);
2208
- }
2209
- };
2210
-
2211
- // src/lsp/providers/formatter-provider.ts
2212
- async function format(model, ranges, options, hint, token) {
2213
- if (hint !== "full") return [];
2214
- const compiled = await Provider.getCompileResult(model);
2215
- if (compiled?.result.formatted == null) return [];
2216
- return [
2217
- {
2218
- range: model.getFullModelRange(),
2219
- text: compiled.result.formatted
2220
- }
2221
- ];
2222
- }
2223
- var FormatterProvider = class extends Provider {
2224
- constructor() {
2225
- super(...arguments);
2226
- /** @inheritdoc */
2227
- this.autoFormatTriggerCharacters = [";", "}", "]", ")"];
2228
- }
2229
- /** 进行完整格式化 */
2230
- static async format(model, options) {
2231
- const formatted = await format(model, [], options, "full", void 0);
2232
- return formatted.length === 1 ? formatted[0].text : null;
2233
- }
2234
- /** @inheritdoc */
2235
- provideDocumentFormattingEdits(model, options, token) {
2236
- return format(model, [], options, "full", token);
2237
- }
2238
- /** @inheritdoc */
2239
- provideDocumentRangeFormattingEdits(model, range, options, token) {
2240
- return format(model, [range], options, "range", token);
2241
- }
2242
- /** @inheritdoc */
2243
- provideDocumentRangesFormattingEdits(model, ranges, options, token) {
2244
- return format(model, ranges, options, "range", token);
2245
- }
2246
- /** @inheritdoc */
2247
- provideOnTypeFormattingEdits(model, position, ch, options, token) {
2248
- return format(
2249
- model,
2250
- [Range.fromPositions(position, position)],
2251
- options,
2252
- ch === ";" ? "statement" : "expression",
2253
- token
2254
- );
2255
- }
2256
- };
2257
-
2258
- // src/lsp/providers/hover-provider.ts
2259
- import { DiagnosticCode as DiagnosticCode10 } from "@mirascript/constants";
2260
- import { convert } from "@mirascript/mirascript/subtle";
2261
- import { KEYWORDS as HELP_KEYWORDS2, OPERATORS as HELP_OPERATORS } from "@mirascript/help";
2262
-
2263
- // src/lsp/monaco-private.js
2264
- function fromStandardTokenType(tokenType) {
2265
- switch (tokenType) {
2266
- case 1:
2267
- return "comment";
2268
- case 2:
2269
- return "string";
2270
- case 3:
2271
- return "regex";
2272
- default:
2273
- return "other";
2274
- }
2275
- }
2276
- function tokenAt(model, position) {
2277
- try {
2278
- let tryGetTokenProp2 = function(method, fallback) {
2279
- try {
2280
- return lineTokens[method](tokenIndex);
2281
- } catch {
2282
- return fallback;
2283
- }
2284
- };
2285
- var tryGetTokenProp = tryGetTokenProp2;
2286
- const lineTokens = model.tokenization.getLineTokens(position.lineNumber);
2287
- const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
2288
- if (tokenIndex < 0) return void 0;
2289
- return {
2290
- type: fromStandardTokenType(tryGetTokenProp2("getStandardTokenType", 0)),
2291
- text: tryGetTokenProp2("getTokenText", null),
2292
- startColumn: tryGetTokenProp2("getStartOffset", 0) + 1,
2293
- endColumn: tryGetTokenProp2("getEndOffset", 0) + 1
2294
- };
2295
- } catch {
2296
- return void 0;
2297
- }
2298
- }
2299
-
2300
- // src/lsp/providers/hover-provider.ts
2301
- var OPERATOR_TOKENS_DESC = Object.keys(HELP_OPERATORS).sort((a, b) => b.length - a.length);
2302
- var REG_NUMBER_ALL_FULL = new RegExp(
2303
- `^(?:${REG_BIN.source}|${REG_OCT.source}|${REG_HEX.source}|${REG_NUMBER.source})$`,
2304
- REG_NUMBER.flags
2305
- );
2306
- var BIN_MAX = 2 ** 32 - 1;
2307
- var OCT_MAX = 8 ** 18 - 1;
2308
- var HEX_MAX = 16 ** 16 - 1;
2309
- function operatorAt(lineContent, column) {
2310
- const index = Math.max(0, column - 1);
2311
- for (const token of OPERATOR_TOKENS_DESC) {
2312
- for (let offset = 0; offset < token.length; offset++) {
2313
- const start = index - offset;
2314
- if (start < 0) continue;
2315
- const end = start + token.length;
2316
- if (end > lineContent.length) continue;
2317
- if (lineContent.slice(start, end) !== token) continue;
2318
- if (index < start || index >= end) continue;
2319
- return {
2320
- token,
2321
- range: {
2322
- startLineNumber: 0,
2323
- startColumn: start + 1,
2324
- endLineNumber: 0,
2325
- endColumn: end + 1
2326
- }
2327
- };
2328
- }
2329
- }
2330
- return void 0;
2331
- }
2332
- var HoverProvider = class extends Provider {
2333
- /** 变量提示 */
2334
- async provideVariableHover(model, { def, ref }) {
2335
- const contents = [];
2336
- let range;
2337
- if ("name" in def) {
2338
- const globals = await this.getContext(model);
2339
- const value = globals.getOrUndefined(def.name);
2340
- const { script, doc } = valueDoc(def.name, value, "hint", globals);
2341
- contents.push({ value: codeblock(`\0(global) ${script}`) });
2342
- for (const d of doc) {
2343
- contents.push({ value: d });
2344
- }
2345
- range = def.references[ref]?.range;
2346
- } else {
2347
- let content;
2348
- const tag = def.definition;
2349
- switch (tag.code) {
2350
- case DiagnosticCode10.ParameterSubPatternImmutable:
2351
- content = {
2352
- value: codeblock(`\0(parameter pattern) ${model.getValueInRange(tag.range)}`)
2353
- };
2354
- break;
2355
- case DiagnosticCode10.ParameterSubPatternMutable:
2356
- content = {
2357
- value: codeblock(`\0(parameter pattern) mut ${model.getValueInRange(tag.range)}`)
2358
- };
2359
- break;
2360
- case DiagnosticCode10.ParameterImmutable:
2361
- content = {
2362
- value: codeblock(`\0(parameter) ${model.getValueInRange(tag.range)}`)
2363
- };
2364
- break;
2365
- case DiagnosticCode10.ParameterMutable:
2366
- content = {
2367
- value: codeblock(`\0(parameter) mut ${model.getValueInRange(tag.range)}`)
2368
- };
2369
- break;
2370
- case DiagnosticCode10.ParameterIt:
2371
- content = {
2372
- value: codeblock(`\0(parameter) it`)
2373
- };
2374
- break;
2375
- case DiagnosticCode10.ParameterImmutableRest:
2376
- content = {
2377
- value: codeblock(`\0(parameter) ..${model.getValueInRange(tag.range)}`)
2378
- };
2379
- break;
2380
- case DiagnosticCode10.ParameterMutableRest:
2381
- content = {
2382
- value: codeblock(`\0(parameter) ..mut ${model.getValueInRange(tag.range)}`)
2383
- };
2384
- break;
2385
- case DiagnosticCode10.LocalFunction: {
2386
- const params = paramsList(model, def.fn);
2387
- content = {
2388
- value: codeblock(`\0fn ${model.getValueInRange(tag.range)}${params}`)
2389
- };
2390
- break;
2391
- }
2392
- case DiagnosticCode10.LocalModule:
2393
- content = {
2394
- value: codeblock(`\0mod ${model.getValueInRange(tag.range)}`)
2395
- };
2396
- break;
2397
- case DiagnosticCode10.LocalImmutable:
2398
- content = {
2399
- value: codeblock(`\0let ${model.getValueInRange(tag.range)}`)
2400
- };
2401
- break;
2402
- case DiagnosticCode10.LocalConst:
2403
- content = {
2404
- value: codeblock(`\0const ${model.getValueInRange(tag.range)}`)
2405
- };
2406
- break;
2407
- case DiagnosticCode10.LocalMutable:
2408
- content = {
2409
- value: codeblock(`\0let mut ${model.getValueInRange(tag.range)}`)
2410
- };
2411
- break;
2412
- }
2413
- if (ref == null) {
2414
- range = tag.range;
2415
- } else {
2416
- range = def.references[ref]?.range;
2417
- }
2418
- if (content) {
2419
- contents.push(content);
2420
- }
2421
- }
2422
- if (!contents.length) return void 0;
2423
- return {
2424
- contents,
2425
- range
2426
- };
2427
- }
2428
- /** 字段提示 */
2429
- async provideFieldHover(model, range, { def: { def, ref }, fields }) {
2430
- if ("definition" in def) {
2431
- return void 0;
2432
- }
2433
- const vmGlobal = await this.getContext(model);
2434
- const lastField = fields.at(-1);
2435
- const [obj, value] = getDeep(vmGlobal, def.name, fields);
2436
- if (value == null) return void 0;
2437
- const { script, doc } = valueDoc(lastField, value, "field", obj);
2438
- return {
2439
- contents: [{ value: codeblock(`\0(field) ${script}`) }, ...doc.map((d) => ({ value: d }))],
2440
- range
2441
- };
2442
- }
2443
- /** 语法元素提示 */
2444
- provideSyntaxHover(model, position) {
2445
- const token = tokenAt(model, position);
2446
- if (token?.type && token.type !== "other") {
2447
- return void 0;
2448
- }
2449
- if (token?.text) {
2450
- if (token.text in HELP_KEYWORDS2) {
2451
- const doc = HELP_KEYWORDS2[token.text];
2452
- return {
2453
- contents: [{ value: doc }],
2454
- range: rangeAt(position, token)
2455
- };
2456
- }
2457
- if (token.text in HELP_OPERATORS) {
2458
- const doc = HELP_OPERATORS[token.text];
2459
- return {
2460
- contents: [{ value: doc }],
2461
- range: rangeAt(position, token)
2462
- };
2463
- }
2464
- if (REG_NUMBER_ALL_FULL.test(token.text)) {
2465
- const num = convert.toNumber(token.text.replaceAll("_", ""), null);
2466
- if (num == null) return void 0;
2467
- const contents = [];
2468
- if (!token.text.includes(".") && !token.text.includes("e") && !token.text.includes("E") && Number.isInteger(num)) {
2469
- contents.push(`\0(dec) ` + serializeNumber(num));
2470
- const abs = Math.abs(num);
2471
- if (abs <= BIN_MAX) {
2472
- contents.push("\0(bin) " + serializeInteger(num, 2));
2473
- }
2474
- if (abs <= OCT_MAX) {
2475
- contents.push("\0(oct) " + serializeInteger(num, 8));
2476
- }
2477
- if (abs <= HEX_MAX) {
2478
- contents.push("\0(hex) " + serializeInteger(num, 16));
2479
- }
2480
- } else {
2481
- contents.push(`\0(number) ` + serializeNumber(num));
2482
- }
2483
- return {
2484
- contents: [{ value: codeblock(contents.join("\n")) }],
2485
- range: rangeAt(position, token)
2486
- };
2487
- }
2488
- }
2489
- const word = model.getWordAtPosition(position);
2490
- if (word?.word && word.word in HELP_KEYWORDS2) {
2491
- const doc = HELP_KEYWORDS2[word.word];
2492
- return {
2493
- contents: [{ value: doc }],
2494
- range: rangeAt(position, word)
2495
- };
2496
- }
2497
- const lineContent = model.getLineContent(position.lineNumber);
2498
- const hit = operatorAt(lineContent, position.column);
2499
- if (hit && hit.token in HELP_OPERATORS) {
2500
- const doc = HELP_OPERATORS[hit.token];
2501
- return {
2502
- contents: [{ value: doc }],
2503
- range: rangeAt(position, hit.range)
2504
- };
2505
- }
2506
- return void 0;
2507
- }
2508
- /** @inheritdoc */
2509
- async provideHover(model, position, token, context) {
2510
- const value = await this.getValueAt(model, position);
2511
- if (!value) {
2512
- return this.provideSyntaxHover(model, position);
2513
- } else if ("fields" in value) {
2514
- return this.provideFieldHover(model, value.range, value.fields);
2515
- } else {
2516
- return this.provideVariableHover(model, value.variable);
2517
- }
2518
- }
2519
- };
2520
-
2521
- // src/lsp/providers/inlay-hints-provider.ts
2522
- import { DiagnosticCode as DiagnosticCode11 } from "@mirascript/constants";
2523
- var InlayHintsProvider = class extends Provider {
2524
- /** @inheritdoc */
2525
- get onDidChangeInlayHints() {
2526
- return this.onDidChange;
2527
- }
2528
- /** @inheritdoc */
2529
- async provideInlayHints(model, range, token) {
2530
- const compiled = await this.getCompileResult(model);
2531
- if (!compiled) {
2532
- return void 0;
2533
- }
2534
- const hints = [];
2535
- for (const tag of compiled.tags) {
2536
- if (!range.containsRange(tag.range)) {
2537
- continue;
2538
- }
2539
- let lineNumber = 0;
2540
- let column = 0;
2541
- let label = "";
2542
- const kind = languages.InlayHintKind.Parameter;
2543
- let paddingLeft = true;
2544
- let paddingRight = false;
2545
- const edits = [];
2546
- switch (tag.code) {
2547
- case DiagnosticCode11.ParameterIt: {
2548
- if (!tag.references.length) {
2549
- continue;
2550
- }
2551
- lineNumber = tag.range.endLineNumber;
2552
- column = tag.range.endColumn;
2553
- label = "(it)";
2554
- paddingLeft = /\bfn$/u.test(
2555
- model.getValueInRange(new Range(lineNumber, column - 3, lineNumber, column))
2556
- );
2557
- paddingRight = model.getValueInRange(new Range(lineNumber, column, lineNumber, column + 1)) === "{";
2558
- edits.push({
2559
- range: new Range(lineNumber, column, lineNumber, column),
2560
- text: `${paddingLeft ? " " : ""}${label}${paddingRight ? " " : ""}`
2561
- });
2562
- break;
2563
- }
2564
- case DiagnosticCode11.UnnamedRecordField0:
2565
- case DiagnosticCode11.UnnamedRecordField1:
2566
- case DiagnosticCode11.UnnamedRecordField2:
2567
- case DiagnosticCode11.UnnamedRecordField3:
2568
- case DiagnosticCode11.UnnamedRecordField4:
2569
- case DiagnosticCode11.UnnamedRecordField5:
2570
- case DiagnosticCode11.UnnamedRecordField6:
2571
- case DiagnosticCode11.UnnamedRecordField7:
2572
- case DiagnosticCode11.UnnamedRecordField8:
2573
- case DiagnosticCode11.UnnamedRecordField9:
2574
- case DiagnosticCode11.UnnamedRecordFieldN: {
2575
- const index = tag.code - DiagnosticCode11.UnnamedRecordField0;
2576
- if (index > 9) break;
2577
- lineNumber = tag.range.startLineNumber;
2578
- column = tag.range.startColumn;
2579
- label = `${index}:`;
2580
- paddingLeft = /[^\s(]/u.test(
2581
- model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column))
2582
- );
2583
- paddingRight = true;
2584
- break;
2585
- }
2586
- case DiagnosticCode11.OmitNamedRecordField: {
2587
- const ref = tag.references[0];
2588
- if (ref?.code !== DiagnosticCode11.OmitNamedRecordFieldName) continue;
2589
- lineNumber = tag.range.startLineNumber;
2590
- column = tag.range.startColumn;
2591
- label = model.getValueInRange(ref.range);
2592
- paddingLeft = /[^\s(]/u.test(
2593
- model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column))
2594
- );
2595
- paddingRight = false;
2596
- const insertRight = !/\s/u.test(
2597
- model.getValueInRange(
2598
- new Range(
2599
- tag.range.endLineNumber,
2600
- tag.range.endColumn,
2601
- tag.range.endLineNumber,
2602
- tag.range.endColumn + 1
2603
- )
2604
- )
2605
- );
2606
- edits.push({
2607
- range: tag.range,
2608
- text: `${paddingLeft ? " " : ""}${label}${model.getValueInRange(tag.range)}${insertRight ? " " : ""}`
2609
- });
2610
- break;
2611
- }
2612
- }
2613
- if (!label) continue;
2614
- const hint = {
2615
- position: { lineNumber, column },
2616
- label,
2617
- kind,
2618
- paddingLeft,
2619
- paddingRight,
2620
- textEdits: edits
2621
- };
2622
- hints.push(hint);
2623
- }
2624
- return {
2625
- hints,
2626
- dispose: () => {
2627
- }
2628
- };
2629
- }
2630
- };
2631
-
2632
- // src/lsp/providers/range-provider.ts
2633
- var RangeProvider = class extends Provider {
2634
- /** @inheritdoc */
2635
- async provideFoldingRanges(model, context, token) {
2636
- const compiled = await this.getCompileResult(model);
2637
- if (!compiled) return void 0;
2638
- return void 0;
2639
- }
2640
- /** @inheritdoc */
2641
- async provideSelectionRanges(model, positions, token) {
2642
- const compiled = await this.getCompileResult(model);
2643
- if (!compiled) return void 0;
2644
- const { ranges } = compiled.groupedTags(model);
2645
- return positions.map((pos) => {
2646
- return ranges.filter((r) => Range.containsPosition(r.range, pos)).map((t) => ({
2647
- range: t.range
2648
- }));
2649
- });
2650
- }
2651
- };
2652
-
2653
- // src/lsp/providers/rename-provider.ts
2654
- import { DiagnosticCode as DiagnosticCode12 } from "@mirascript/constants";
2655
- var RenameProvider = class extends Provider {
2656
- /** 重命名推断字段 */
2657
- provideRenameEditsOmitNameFields(model, compiled, edits, ref, oldName) {
2658
- const { omitNameFields } = compiled.groupedTags(model);
2659
- for (const tag of omitNameFields) {
2660
- if (Range.equalsRange(tag.references[0]?.range, ref.range)) {
2661
- const current = model.getValueInRange(tag.range);
2662
- const paddingLeft = /[^\s(]/u.test(
2663
- model.getValueInRange({
2664
- startLineNumber: tag.range.startLineNumber,
2665
- startColumn: tag.range.startColumn - 1,
2666
- endLineNumber: tag.range.startLineNumber,
2667
- endColumn: tag.range.startColumn
2668
- })
2669
- );
2670
- const paddingRight = !/\s/u.test(
2671
- model.getValueInRange({
2672
- startLineNumber: tag.range.endLineNumber,
2673
- startColumn: tag.range.endColumn,
2674
- endLineNumber: tag.range.endLineNumber,
2675
- endColumn: tag.range.endColumn + 1
2676
- })
2677
- );
2678
- edits.push({
2679
- resource: model.uri,
2680
- versionId: compiled.version,
2681
- textEdit: {
2682
- range: tag.range,
2683
- text: `${paddingLeft ? " " : ""}${oldName}${current}${paddingRight ? " " : ""}`
2684
- }
2685
- });
2686
- }
2687
- }
2688
- }
2689
- /** @inheritdoc */
2690
- async provideRenameEdits(model, position, newName, token) {
2691
- newName = newName.trim();
2692
- const compiled = await this.getCompileResult(model);
2693
- if (!compiled) return void 0;
2694
- const d = compiled.variableAccessAt(model, position);
2695
- if (!d) return void 0;
2696
- const edits = [];
2697
- const { references } = d.def;
2698
- let oldName;
2699
- if ("definition" in d.def) {
2700
- edits.push({
2701
- resource: model.uri,
2702
- versionId: compiled.version,
2703
- textEdit: {
2704
- range: d.def.definition.range,
2705
- text: d.def.definition.code === DiagnosticCode12.ParameterIt ? `(${newName})` : newName
2706
- }
2707
- });
2708
- oldName = model.getValueInRange(d.def.definition.range);
2709
- this.provideRenameEditsOmitNameFields(model, compiled, edits, d.def.definition, oldName);
2710
- } else {
2711
- oldName = d.def.name;
2712
- }
2713
- for (const ref of references) {
2714
- edits.push({
2715
- resource: model.uri,
2716
- versionId: compiled.version,
2717
- textEdit: {
2718
- range: ref.range,
2719
- text: newName
2720
- }
2721
- });
2722
- this.provideRenameEditsOmitNameFields(model, compiled, edits, ref, oldName);
2723
- }
2724
- const { globals } = compiled.groupedTags(model);
2725
- const globalWithSameName = globals.find((g) => g.name === newName);
2726
- if (globalWithSameName) {
2727
- for (const ref of globalWithSameName.references) {
2728
- edits.push({
2729
- resource: model.uri,
2730
- versionId: compiled.version,
2731
- textEdit: {
2732
- range: ref.range,
2733
- text: `global.${newName}`
2734
- }
2735
- });
2736
- this.provideRenameEditsOmitNameFields(model, compiled, edits, ref, oldName);
2737
- }
2738
- }
2739
- return { edits };
2740
- }
2741
- /** @inheritdoc */
2742
- async resolveRenameLocation(model, position, token) {
2743
- const compiled = await this.getCompileResult(model);
2744
- if (!compiled) return void 0;
2745
- const d = compiled.variableAccessAt(model, position);
2746
- if (!d) {
2747
- return {
2748
- range: Range.fromPositions(position),
2749
- text: "",
2750
- rejectReason: "Cannot rename this element"
2751
- };
2752
- }
2753
- const { def, ref } = d;
2754
- if ("name" in def) {
2755
- return {
2756
- range: def.references[ref]?.range ?? Range.fromPositions(position),
2757
- text: def.name,
2758
- rejectReason: "Cannot rename global variables"
2759
- };
2760
- }
2761
- const tag = ref == null ? def.definition : def.references[ref];
2762
- return {
2763
- range: tag.range,
2764
- text: model.getValueInRange(tag.range) ?? ""
2765
- };
2766
- }
2767
- };
2768
-
2769
- // src/lsp/providers/semantic-tokens-provider.ts
2770
- import { isVmFunction as isVmFunction2, isVmModule as isVmModule3 } from "@mirascript/mirascript";
2771
- import { DiagnosticCode as DiagnosticCode13 } from "@mirascript/constants";
2772
- var TOKEN_TYPES = {
2773
- [0 /* VARIABLE */]: "variable.other.constant",
2774
- [1 /* VARIABLE_MUTABLE */]: "variable",
2775
- [2 /* CONSTANT */]: "variable.other.constant",
2776
- [3 /* GLOBAL */]: "variable",
2777
- [4 /* FUNCTION */]: "entity.name.function",
2778
- [5 /* MODULE */]: "type",
2779
- [6 /* PROPERTY */]: "variable.other.property",
2780
- [7 /* KEYWORD_CONTROL */]: "keyword.flow",
2781
- [8 /* PARAM */]: "variable.other.constant.emphasis",
2782
- [9 /* PARAM_MUTABLE */]: "variable.emphasis"
2783
- };
2784
- var DocumentSemanticTokensProvider = class extends Provider {
2785
- /** @inheritdoc */
2786
- getLegend() {
2787
- const tokenTypes = Object.values(TOKEN_TYPES);
2788
- return {
2789
- tokenTypes,
2790
- tokenModifiers: tokenTypes.map((_) => "")
2791
- };
2792
- }
2793
- /** @inheritdoc */
2794
- async provideDocumentSemanticTokens(model, lastResultId, token) {
2795
- const resultId = `${model.uri.toString()}?${model.getVersionId()}`;
2796
- const compiled = await this.getCompileResult(model);
2797
- if (!compiled) {
2798
- return void 0;
2799
- }
2800
- const globals = await this.getContext(model);
2801
- const data = [];
2802
- for (const { code, range, references } of compiled.tags) {
2803
- let tokenType = -1;
2804
- let onlyReferences = false;
2805
- switch (code) {
2806
- case DiagnosticCode13.GlobalVariable: {
2807
- const id = model.getValueInRange(range);
2808
- if (id.startsWith("@")) {
2809
- tokenType = 2 /* CONSTANT */;
2810
- } else {
2811
- const val = globals.getOrUndefined(id);
2812
- if (isVmFunction2(val)) {
2813
- tokenType = 4 /* FUNCTION */;
2814
- } else if (isVmModule3(val)) {
2815
- tokenType = 5 /* MODULE */;
2816
- } else {
2817
- tokenType = 3 /* GLOBAL */;
2818
- }
2819
- }
2820
- break;
2821
- }
2822
- case DiagnosticCode13.LocalFunction: {
2823
- tokenType = 4 /* FUNCTION */;
2824
- break;
2825
- }
2826
- case DiagnosticCode13.LocalModule: {
2827
- tokenType = 5 /* MODULE */;
2828
- break;
2829
- }
2830
- case DiagnosticCode13.ParameterMutable:
2831
- case DiagnosticCode13.ParameterSubPatternMutable:
2832
- case DiagnosticCode13.ParameterMutableRest: {
2833
- tokenType = 9 /* PARAM_MUTABLE */;
2834
- break;
2835
- }
2836
- case DiagnosticCode13.LocalMutable: {
2837
- tokenType = 1 /* VARIABLE_MUTABLE */;
2838
- break;
2839
- }
2840
- case DiagnosticCode13.ParameterIt: {
2841
- tokenType = 8 /* PARAM */;
2842
- onlyReferences = true;
2843
- break;
2844
- }
2845
- case DiagnosticCode13.ParameterImmutable:
2846
- case DiagnosticCode13.ParameterSubPatternImmutable:
2847
- case DiagnosticCode13.ParameterImmutableRest: {
2848
- tokenType = 8 /* PARAM */;
2849
- break;
2850
- }
2851
- case DiagnosticCode13.LocalImmutable: {
2852
- tokenType = 0 /* VARIABLE */;
2853
- break;
2854
- }
2855
- case DiagnosticCode13.LocalConst: {
2856
- tokenType = 2 /* CONSTANT */;
2857
- break;
2858
- }
2859
- // case DiagnosticCode.RecordFieldStringName:
2860
- case DiagnosticCode13.RecordFieldOrdinalName:
2861
- case DiagnosticCode13.RecordFieldIdName: {
2862
- tokenType = 6 /* PROPERTY */;
2863
- break;
2864
- }
2865
- case DiagnosticCode13.ForExpression: {
2866
- tokenType = 7 /* KEYWORD_CONTROL */;
2867
- onlyReferences = true;
2868
- break;
2869
- }
2870
- }
2871
- if (tokenType < 0) continue;
2872
- const { startLineNumber, startColumn, endColumn } = range;
2873
- const length = endColumn - startColumn;
2874
- if (!onlyReferences) {
2875
- data.push({
2876
- row: startLineNumber - 1,
2877
- // 从 0 开始
2878
- col: startColumn - 1,
2879
- length,
2880
- tokenType,
2881
- tokenModifiers: 1 << tokenType
2882
- });
2883
- }
2884
- for (const ref of references) {
2885
- if (ref.code === DiagnosticCode13.ExportedLocal) {
2886
- continue;
2887
- }
2888
- data.push({
2889
- row: ref.range.startLineNumber - 1,
2890
- col: ref.range.startColumn - 1,
2891
- length: ref.range.endColumn - ref.range.startColumn,
2892
- tokenType,
2893
- tokenModifiers: 1 << tokenType
2894
- });
2895
- }
2896
- }
2897
- data.sort((a, b) => {
2898
- if (a.row !== b.row) {
2899
- return a.row - b.row;
2900
- }
2901
- return a.col - b.col;
2902
- });
2903
- const bin = new Uint32Array(data.length * 5);
2904
- for (let i = 0; i < data.length; i++) {
2905
- const current = data[i];
2906
- let { row, col } = current;
2907
- if (i > 0) {
2908
- const prev = data[i - 1];
2909
- row -= prev.row;
2910
- if (row === 0) {
2911
- col -= prev.col;
2912
- }
2913
- }
2914
- bin.set([row, col, current.length, current.tokenType, current.tokenModifiers], i * 5);
2915
- }
2916
- return {
2917
- resultId,
2918
- data: bin
2919
- };
2920
- }
2921
- /** @inheritdoc */
2922
- releaseDocumentSemanticTokens(resultId) {
2923
- }
2924
- };
2925
-
2926
- // src/lsp/providers/signature-help-provider.ts
2927
- import { DiagnosticCode as DiagnosticCode14 } from "@mirascript/constants";
2928
- import { getVmFunctionInfo as getVmFunctionInfo3 } from "@mirascript/mirascript";
2929
- var SignatureHelpProvider = class extends Provider {
2930
- constructor() {
2931
- super(...arguments);
2932
- /** @inheritdoc */
2933
- this.signatureHelpTriggerCharacters = ["(", ","];
2934
- /** @inheritdoc */
2935
- this.signatureHelpRetriggerCharacters = [")"];
2936
- }
2937
- /** @inheritdoc */
2938
- async provideSignatureHelp(model, position, token, context) {
2939
- const compiled = await this.getCompileResult(model);
2940
- if (!compiled) return void 0;
2941
- const invokes = compiled.groupedTags(model).ranges.filter((r) => {
2942
- if (r.code !== DiagnosticCode14.FunctionCall && r.code !== DiagnosticCode14.ExtensionCall) {
2943
- return false;
2944
- }
2945
- if (!strictContainsPosition(r.range, position)) {
2946
- return false;
2947
- }
2948
- const argStart = r.references.find((ref) => ref.code === DiagnosticCode14.ArgumentStart);
2949
- const argEnd = r.references.find((ref) => ref.code === DiagnosticCode14.ArgumentEnd);
2950
- if (!argStart || !argEnd) {
2951
- return false;
2952
- }
2953
- return Range.containsPosition(
2954
- Range.fromPositions(Range.getEndPosition(argStart.range), Range.getStartPosition(argEnd.range)),
2955
- position
2956
- );
2957
- });
2958
- if (!invokes.length) return void 0;
2959
- invokes.sort((a, b) => Range.strictContainsRange(a.range, b.range) ? 1 : -1);
2960
- const invoke = invokes[0];
2961
- const callableRef = invoke.references.find((ref) => ref.code === DiagnosticCode14.Callable);
2962
- if (!callableRef) return void 0;
2963
- const callableInfo = compiled.accessAt(model, Range.getEndPosition(callableRef.range));
2964
- if (!callableInfo) return void 0;
2965
- let sig;
2966
- if ("name" in callableInfo.def.def) {
2967
- const { name } = callableInfo.def.def;
2968
- const globals = await this.getContext(model);
2969
- const [, callable] = getDeep(globals, name, callableInfo.fields);
2970
- const info = getVmFunctionInfo3(callable);
2971
- if (!info) return void 0;
2972
- const fnName = callableInfo.fields.length ? callableInfo.fields.at(-1) : name;
2973
- sig = { ...fnSignature(fnName, info), name: fnName, summary: info.summary };
2974
- } else if (callableInfo.def.def.fn) {
2975
- const { fn, definition } = callableInfo.def.def;
2976
- const params = localParamSignature(model, fn);
2977
- const name = model.getValueInRange(definition.range);
2978
- sig = { params, returns: "", name, summary: "" };
2979
- }
2980
- if (!sig) return void 0;
2981
- const signature = {
2982
- label: "",
2983
- parameters: []
2984
- };
2985
- if (invoke.code === DiagnosticCode14.ExtensionCall) {
2986
- const thisArg = sig.params[0];
2987
- if (thisArg && !thisArg[0].startsWith("..")) {
2988
- sig.params.shift();
2989
- const s = thisArg[1].includes(" ") ? `(${thisArg[1]})` : thisArg[1];
2990
- signature.label = `fn ${s}::${sig.name}(`;
2991
- } else {
2992
- signature.label = `fn ()::${sig.name}(`;
2993
- }
2994
- } else {
2995
- signature.label = `fn ${sig.name}(`;
2996
- }
2997
- signature.documentation = { value: sig.summary ?? "" };
2998
- for (let i = 0; i < sig.params.length; i++) {
2999
- const [_, p, doc] = sig.params[i];
3000
- const start = signature.label.length;
3001
- signature.parameters.push({
3002
- label: [start, start + p.length],
3003
- documentation: { value: doc }
3004
- });
3005
- if (i === sig.params.length - 1) {
3006
- signature.label += p;
3007
- } else {
3008
- signature.label += p + ", ";
3009
- }
3010
- }
3011
- signature.label += ")" + sig.returns;
3012
- let pos = 0;
3013
- for (const ref of invoke.references) {
3014
- if (ref.code === DiagnosticCode14.ArgumentSpread) pos = Number.NaN;
3015
- if (ref.code !== DiagnosticCode14.ArgumentComma || Range.isEmpty(ref.range)) continue;
3016
- if (Position.isBeforeOrEqual(Range.getEndPosition(ref.range), position) && !sig.params[pos]?.[0].startsWith("..")) {
3017
- pos++;
3018
- }
3019
- }
3020
- return {
3021
- dispose: () => void 0,
3022
- value: {
3023
- signatures: [signature],
3024
- activeSignature: 0,
3025
- activeParameter: pos
3026
- }
3027
- };
3028
- }
3029
- };
3030
-
3031
- // src/lsp/index.ts
3032
- async function registerLSP(contextProvider2, features = {}) {
3033
- Provider.setContextProvider(contextProvider2);
3034
- const { loadModule } = await import("@mirascript/bindings/wasm");
3035
- await loadModule();
3036
- const disposables = [];
3037
- const registerIfEnabled = (feature, provider, register) => {
3038
- const providerInstance = new provider(() => features[feature] !== false);
3039
- const d = register(["mirascript", "mirascript-template"], providerInstance);
3040
- if (Array.isArray(d)) disposables.push(...d);
3041
- else disposables.push(d);
3042
- };
3043
- registerIfEnabled("codeAction", CodeActionProvider, languages.registerCodeActionProvider);
3044
- registerIfEnabled("codeLens", CodeLensProvider, languages.registerCodeLensProvider);
3045
- registerIfEnabled("color", ColorProvider, languages.registerColorProvider);
3046
- registerIfEnabled("definitionReference", DefinitionReferenceProvider, (language, provider) => {
3047
- return [
3048
- languages.registerDefinitionProvider(language, provider),
3049
- languages.registerReferenceProvider(language, provider)
3050
- ];
3051
- });
3052
- registerIfEnabled("documentHighlight", DocumentHighlightProvider, languages.registerDocumentHighlightProvider);
3053
- registerIfEnabled("documentSymbol", DocumentSymbolProvider, languages.registerDocumentSymbolProvider);
3054
- registerIfEnabled("formatter", FormatterProvider, (language, provider) => {
3055
- return [
3056
- languages.registerDocumentFormattingEditProvider(language, provider)
3057
- // languages.registerDocumentRangeFormattingEditProvider(language, provider),
3058
- // languages.registerOnTypeFormattingEditProvider(language, provider),
3059
- ];
3060
- });
3061
- registerIfEnabled("hover", HoverProvider, languages.registerHoverProvider);
3062
- registerIfEnabled("inlayHints", InlayHintsProvider, languages.registerInlayHintsProvider);
3063
- registerIfEnabled("range", RangeProvider, (language, provider) => {
3064
- return [
3065
- languages.registerFoldingRangeProvider(language, provider),
3066
- languages.registerSelectionRangeProvider(language, provider)
3067
- ];
3068
- });
3069
- registerIfEnabled(
3070
- "documentSemanticTokens",
3071
- DocumentSemanticTokensProvider,
3072
- languages.registerDocumentSemanticTokensProvider
3073
- );
3074
- registerIfEnabled("rename", RenameProvider, languages.registerRenameProvider);
3075
- registerIfEnabled("completionItem", CompletionItemProvider, languages.registerCompletionItemProvider);
3076
- registerIfEnabled("signatureHelp", SignatureHelpProvider, languages.registerSignatureHelpProvider);
3077
- return disposables;
3078
- }
3079
- export {
3080
- CodeActionProvider,
3081
- CodeLensProvider,
3082
- ColorProvider,
3083
- CompletionItemProvider,
3084
- DefinitionReferenceProvider,
3085
- DocumentHighlightProvider,
3086
- DocumentSemanticTokensProvider,
3087
- DocumentSymbolProvider,
3088
- FormatterProvider,
3089
- HoverProvider,
3090
- InlayHintsProvider,
3091
- Provider,
3092
- RangeProvider,
3093
- RenameProvider,
3094
- SignatureHelpProvider,
3095
- registerLSP
3096
- };
3097
- //# sourceMappingURL=index.js.map