@marko/language-server 0.12.17 → 1.0.0

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 (38) hide show
  1. package/dist/index.js +2021 -1565
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.mjs +2055 -1594
  4. package/dist/index.mjs.map +4 -4
  5. package/dist/service/marko/complete/AttrName.d.ts +2 -2
  6. package/dist/service/marko/complete/AttrValue.d.ts +2 -2
  7. package/dist/service/marko/complete/Import.d.ts +3 -0
  8. package/dist/service/marko/complete/OpenTagName.d.ts +2 -2
  9. package/dist/service/marko/complete/Tag.d.ts +2 -2
  10. package/dist/service/marko/complete/index.d.ts +5 -8
  11. package/dist/service/marko/definition/AttrName.d.ts +2 -2
  12. package/dist/service/marko/definition/OpenTagName.d.ts +2 -2
  13. package/dist/service/marko/definition/index.d.ts +5 -8
  14. package/dist/service/marko/hover/OpenTagName.d.ts +2 -2
  15. package/dist/service/marko/hover/index.d.ts +5 -8
  16. package/dist/service/marko/util/is-document-link-attr.d.ts +2 -3
  17. package/dist/service/script/index.d.ts +3 -0
  18. package/dist/service/types.d.ts +6 -4
  19. package/dist/ts-plugin/host.d.ts +5 -0
  20. package/dist/ts-plugin/index.d.ts +5 -0
  21. package/dist/utils/constants.d.ts +3 -0
  22. package/dist/utils/file.d.ts +21 -0
  23. package/dist/utils/get-component-filename.d.ts +2 -0
  24. package/dist/utils/get-runtime-types.d.ts +8 -0
  25. package/dist/utils/get-script-lang.d.ts +4 -0
  26. package/dist/utils/project.d.ts +11 -0
  27. package/dist/utils/text-documents.d.ts +10 -0
  28. package/dist/utils/workspace.d.ts +5 -0
  29. package/package.json +20 -16
  30. package/dist/service/marko/complete/Statement.d.ts +0 -3
  31. package/dist/service/stylesheet/extract.d.ts +0 -10
  32. package/dist/utils/compiler.d.ts +0 -21
  33. package/dist/utils/doc-file.d.ts +0 -3
  34. package/dist/utils/extractor.d.ts +0 -12
  35. package/dist/utils/get-node-at-offset.d.ts +0 -2
  36. package/dist/utils/parser.d.ts +0 -176
  37. package/dist/utils/utils.d.ts +0 -4
  38. /package/dist/service/{stylesheet → style}/index.d.ts +0 -0
package/dist/index.js CHANGED
@@ -14,578 +14,54 @@ var __copyProps = (to, from, except, desc) => {
14
14
  return to;
15
15
  };
16
16
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
17
21
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
18
22
  mod
19
23
  ));
20
24
 
21
25
  // src/index.ts
22
- var import_node = require("vscode-languageserver/node");
23
- var import_vscode_languageserver_textdocument3 = require("vscode-languageserver-textdocument");
24
26
  var import_util2 = require("util");
27
+ var import_node = require("vscode-languageserver/node");
25
28
 
26
- // src/utils/compiler.ts
27
- var import_resolve_from = __toESM(require("resolve-from"));
29
+ // src/utils/project.ts
30
+ var defaultCompiler = __toESM(require("@marko/compiler"));
31
+ var defaultTranslator = __toESM(require("@marko/translator-default"));
28
32
  var import_lasso_package_root = __toESM(require("lasso-package-root"));
29
- var builtinCompiler = __toESM(require("@marko/compiler"));
30
- var builtinTranslator = __toESM(require("@marko/translator-default"));
31
-
32
- // src/utils/doc-file.ts
33
- var import_path = __toESM(require("path"));
34
- var import_vscode_uri = require("vscode-uri");
35
- function getDocDir(doc) {
36
- const filename = getDocFile(doc);
37
- return filename ? import_path.default.dirname(filename) : void 0;
38
- }
39
- function getDocFile(doc) {
40
- return import_vscode_uri.URI.parse(doc.uri).fsPath;
41
- }
42
-
43
- // src/utils/parser.ts
44
- var import_htmljs_parser = require("htmljs-parser");
45
-
46
- // src/utils/get-node-at-offset.ts
47
- function getNodeAtOffset(offset, program) {
48
- const bodyNode = childAtOffset(offset, program.body);
49
- if (bodyNode)
50
- return visitChildNode(offset, bodyNode);
51
- return childAtOffset(offset, program.static) || program;
52
- }
53
- function visitChildNode(offset, child) {
54
- switch (child.type) {
55
- case 1 /* Tag */:
56
- case 14 /* AttrTag */:
57
- return visitTag(offset, child);
58
- default:
59
- return child;
60
- }
61
- }
62
- function visitTag(offset, tag) {
63
- const { body } = tag;
64
- if (body && offset > tag.open.end) {
65
- const childNode = childAtOffset(offset, body);
66
- return childNode ? visitChildNode(offset, childNode) : tag;
67
- }
68
- const { attrs } = tag;
69
- if (attrs && offset > attrs[0].start) {
70
- const attrNode = childAtOffset(offset, attrs);
71
- return attrNode ? visitAttrNode(offset, attrNode) : tag;
72
- }
73
- const { var: tagVar } = tag;
74
- if (tagVar && offset > tagVar.start && offset <= tagVar.end) {
75
- return tagVar;
76
- }
77
- const { args } = tag;
78
- if (args && offset > args.start && offset <= args.end) {
79
- return args;
80
- }
81
- const { params } = tag;
82
- if (params && offset > params.start && offset <= params.end) {
83
- return params;
84
- }
85
- const { name } = tag;
86
- if (name && offset <= name.end) {
87
- return name;
88
- }
89
- return tag;
90
- }
91
- function visitAttrNode(offset, attr) {
92
- switch (attr.type) {
93
- case 14 /* AttrTag */:
94
- return visitTag(offset, attr);
95
- case 8 /* AttrNamed */: {
96
- const { value } = attr;
97
- if (value && offset > value.start) {
98
- return value;
99
- }
100
- const { name } = attr;
101
- if (offset > name.start && offset <= name.end) {
102
- return name;
103
- }
104
- break;
105
- }
106
- }
107
- return attr;
108
- }
109
- function childAtOffset(offset, children) {
110
- let max = children.length - 1;
111
- if (max === -1)
112
- return void 0;
113
- let min = 0;
114
- while (min < max) {
115
- const mid = 1 + min + max >>> 1;
116
- if (children[mid].start < offset) {
117
- min = mid;
118
- } else {
119
- max = mid - 1;
120
- }
121
- }
122
- const child = children[min];
123
- return offset > child.start && offset <= child.end ? child : void 0;
124
- }
125
-
126
- // src/utils/parser.ts
127
- var UNFINISHED = Number.MAX_SAFE_INTEGER;
128
- var NodeType = /* @__PURE__ */ ((NodeType2) => {
129
- NodeType2[NodeType2["Program"] = 0] = "Program";
130
- NodeType2[NodeType2["Tag"] = 1] = "Tag";
131
- NodeType2[NodeType2["OpenTagName"] = 2] = "OpenTagName";
132
- NodeType2[NodeType2["ShorthandId"] = 3] = "ShorthandId";
133
- NodeType2[NodeType2["ShorthandClassName"] = 4] = "ShorthandClassName";
134
- NodeType2[NodeType2["TagVar"] = 5] = "TagVar";
135
- NodeType2[NodeType2["TagArgs"] = 6] = "TagArgs";
136
- NodeType2[NodeType2["TagParams"] = 7] = "TagParams";
137
- NodeType2[NodeType2["AttrNamed"] = 8] = "AttrNamed";
138
- NodeType2[NodeType2["AttrName"] = 9] = "AttrName";
139
- NodeType2[NodeType2["AttrArgs"] = 10] = "AttrArgs";
140
- NodeType2[NodeType2["AttrValue"] = 11] = "AttrValue";
141
- NodeType2[NodeType2["AttrMethod"] = 12] = "AttrMethod";
142
- NodeType2[NodeType2["AttrSpread"] = 13] = "AttrSpread";
143
- NodeType2[NodeType2["AttrTag"] = 14] = "AttrTag";
144
- NodeType2[NodeType2["Text"] = 15] = "Text";
145
- NodeType2[NodeType2["CDATA"] = 16] = "CDATA";
146
- NodeType2[NodeType2["Doctype"] = 17] = "Doctype";
147
- NodeType2[NodeType2["Declaration"] = 18] = "Declaration";
148
- NodeType2[NodeType2["Comment"] = 19] = "Comment";
149
- NodeType2[NodeType2["Statement"] = 20] = "Statement";
150
- NodeType2[NodeType2["Placeholder"] = 21] = "Placeholder";
151
- NodeType2[NodeType2["Scriptlet"] = 22] = "Scriptlet";
152
- return NodeType2;
153
- })(NodeType || {});
154
- function parse(source) {
155
- const program = {
156
- type: 0 /* Program */,
157
- parent: void 0,
158
- static: [],
159
- body: [],
160
- start: 0,
161
- end: source.length
162
- };
163
- let curBodyType;
164
- let curOpenTagStart;
165
- let curParent = program;
166
- let curAttr = void 0;
167
- let curBody = program.body;
168
- const parser = (0, import_htmljs_parser.createParser)({
169
- onText(range) {
170
- curBody.push({
171
- type: 15 /* Text */,
172
- parent: curParent,
173
- start: range.start,
174
- end: range.end
175
- });
176
- },
177
- onCDATA(range) {
178
- curBody.push({
179
- type: 16 /* CDATA */,
180
- parent: curParent,
181
- value: range.value,
182
- start: range.start,
183
- end: range.end
184
- });
185
- },
186
- onDoctype(range) {
187
- curBody.push({
188
- type: 17 /* Doctype */,
189
- parent: curParent,
190
- value: range.value,
191
- start: range.start,
192
- end: range.end
193
- });
194
- },
195
- onDeclaration(range) {
196
- curBody.push({
197
- type: 18 /* Declaration */,
198
- parent: curParent,
199
- value: range.value,
200
- start: range.start,
201
- end: range.end
202
- });
203
- },
204
- onComment(range) {
205
- curBody.push({
206
- type: 19 /* Comment */,
207
- parent: curParent,
208
- value: range.value,
209
- start: range.start,
210
- end: range.end
211
- });
212
- },
213
- onPlaceholder(range) {
214
- curBody.push({
215
- type: 21 /* Placeholder */,
216
- parent: curParent,
217
- value: range.value,
218
- escape: range.escape,
219
- start: range.start,
220
- end: range.end
221
- });
222
- },
223
- onScriptlet(range) {
224
- curBody.push({
225
- type: 22 /* Scriptlet */,
226
- parent: curParent,
227
- value: range.value,
228
- block: range.block,
229
- start: range.start,
230
- end: range.end
231
- });
232
- },
233
- onOpenTagStart(range) {
234
- curOpenTagStart = range;
235
- },
236
- onOpenTagName(range) {
237
- let concise = true;
238
- let start = range.start;
239
- let type = 1 /* Tag */;
240
- let nameText = void 0;
241
- if (curOpenTagStart) {
242
- concise = false;
243
- start = curOpenTagStart.start;
244
- curOpenTagStart = void 0;
245
- }
246
- if (range.expressions.length) {
247
- curBodyType = import_htmljs_parser.TagType.html;
248
- } else {
249
- switch (nameText = parser.read(range)) {
250
- case "area":
251
- case "base":
252
- case "br":
253
- case "col":
254
- case "embed":
255
- case "hr":
256
- case "img":
257
- case "input":
258
- case "link":
259
- case "meta":
260
- case "param":
261
- case "source":
262
- case "track":
263
- case "wbr":
264
- curBodyType = import_htmljs_parser.TagType.void;
265
- break;
266
- case "html-comment":
267
- case "script":
268
- case "style":
269
- case "textarea":
270
- curBodyType = import_htmljs_parser.TagType.text;
271
- break;
272
- case "class":
273
- case "export":
274
- case "import":
275
- case "static": {
276
- let i = program.body.length;
277
- for (; i--; ) {
278
- const prev = program.body[i];
279
- if (prev.type === 19 /* Comment */) {
280
- program.static.push(prev);
281
- } else {
282
- break;
283
- }
284
- }
285
- program.body.length = i + 1;
286
- program.static.push(
287
- curParent = {
288
- type: 20 /* Statement */,
289
- parent: program,
290
- start: range.start,
291
- end: UNFINISHED
292
- }
293
- );
294
- return curBodyType = import_htmljs_parser.TagType.statement;
295
- }
296
- default:
297
- if (nameText[0] === "@") {
298
- type = 14 /* AttrTag */;
299
- }
300
- curBodyType = import_htmljs_parser.TagType.html;
301
- break;
302
- }
303
- }
304
- const parent = curParent;
305
- const end = UNFINISHED;
306
- const name = {
307
- type: 2 /* OpenTagName */,
308
- parent: void 0,
309
- quasis: range.quasis,
310
- expressions: range.expressions,
311
- start: range.start,
312
- end: range.end
313
- };
314
- const tag = curParent = name.parent = {
315
- type,
316
- parent,
317
- owner: void 0,
318
- concise,
319
- open: { start, end },
320
- nameText,
321
- name,
322
- var: void 0,
323
- args: void 0,
324
- params: void 0,
325
- shorthandId: void 0,
326
- shorthandClassNames: void 0,
327
- attrs: void 0,
328
- selfClosed: false,
329
- bodyType: curBodyType,
330
- body: void 0,
331
- close: void 0,
332
- start,
333
- end
334
- };
335
- if (tag.type === 14 /* AttrTag */) {
336
- let owner = parent;
337
- outer:
338
- do {
339
- switch (owner.type) {
340
- case 14 /* AttrTag */:
341
- break;
342
- case 1 /* Tag */:
343
- if (isTransparentTag(owner)) {
344
- owner = owner.parent;
345
- continue outer;
346
- }
347
- break;
348
- default:
349
- break outer;
350
- }
351
- tag.owner = owner;
352
- tag.nameText = resolveAttrTagName(tag);
353
- pushAttr(owner, tag);
354
- } while (false);
355
- }
356
- curBody.push(tag);
357
- curOpenTagStart = void 0;
358
- return curBodyType;
359
- },
360
- onTagShorthandId(range) {
361
- curParent.shorthandId = {
362
- type: 3 /* ShorthandId */,
363
- parent: curParent,
364
- quasis: range.quasis,
365
- expressions: range.expressions,
366
- start: range.start,
367
- end: range.end
368
- };
369
- },
370
- onTagShorthandClass(range) {
371
- const shorthandClassName = {
372
- type: 4 /* ShorthandClassName */,
373
- parent: curParent,
374
- quasis: range.quasis,
375
- expressions: range.expressions,
376
- start: range.start,
377
- end: range.end
378
- };
379
- if (curParent.shorthandClassNames) {
380
- curParent.shorthandClassNames.push(shorthandClassName);
381
- } else {
382
- curParent.shorthandClassNames = [shorthandClassName];
383
- }
384
- },
385
- onTagVar(range) {
386
- curParent.var = {
387
- type: 5 /* TagVar */,
388
- parent: curParent,
389
- value: range.value,
390
- start: range.start,
391
- end: range.end
392
- };
393
- },
394
- onTagParams(range) {
395
- curParent.params = {
396
- type: 7 /* TagParams */,
397
- parent: curParent,
398
- value: range.value,
399
- start: range.start,
400
- end: range.end
401
- };
402
- },
403
- onTagArgs(range) {
404
- curParent.args = {
405
- type: 6 /* TagArgs */,
406
- parent: curParent,
407
- value: range.value,
408
- start: range.start,
409
- end: range.end
410
- };
411
- },
412
- onAttrName(range) {
413
- const parent = curParent;
414
- const name = {
415
- type: 9 /* AttrName */,
416
- parent: void 0,
417
- start: range.start,
418
- end: range.end
419
- };
420
- pushAttr(
421
- parent,
422
- curAttr = name.parent = {
423
- type: 8 /* AttrNamed */,
424
- parent,
425
- name,
426
- value: void 0,
427
- args: void 0,
428
- start: range.start,
429
- end: range.end
430
- }
431
- );
432
- },
433
- onAttrArgs(range) {
434
- curAttr.args = {
435
- type: 10 /* AttrArgs */,
436
- parent: curAttr,
437
- value: range.value,
438
- start: range.start,
439
- end: range.end
440
- };
441
- },
442
- onAttrValue(range) {
443
- curAttr.value = {
444
- type: 11 /* AttrValue */,
445
- parent: curAttr,
446
- value: range.value,
447
- bound: range.bound,
448
- start: range.start,
449
- end: range.end
450
- };
451
- curAttr.end = range.end;
452
- },
453
- onAttrMethod(range) {
454
- curAttr.value = {
455
- type: 12 /* AttrMethod */,
456
- parent: curAttr,
457
- params: range.params,
458
- body: range.body,
459
- start: range.start,
460
- end: range.end
461
- };
462
- curAttr.end = range.end;
463
- },
464
- onAttrSpread(range) {
465
- pushAttr(curParent, {
466
- type: 13 /* AttrSpread */,
467
- parent: curParent,
468
- value: range.value,
469
- start: range.start,
470
- end: range.end
471
- });
472
- },
473
- onOpenTagEnd(range) {
474
- curAttr = void 0;
475
- if (curBodyType === import_htmljs_parser.TagType.statement) {
476
- curParent.end = range.end;
477
- curParent = curParent.parent;
478
- } else {
479
- const tag = curParent;
480
- tag.open.end = range.end;
481
- if (range.selfClosed || curBodyType === import_htmljs_parser.TagType.void) {
482
- curParent = tag.parent;
483
- tag.selfClosed = range.selfClosed;
484
- tag.end = range.end;
485
- } else {
486
- curBody = tag.body = [];
487
- }
488
- }
489
- },
490
- onCloseTagStart(range) {
491
- curParent.close = {
492
- start: range.start,
493
- end: Number.MAX_SAFE_INTEGER
494
- };
495
- },
496
- onCloseTagEnd(range) {
497
- if (hasCloseTag(curParent))
498
- curParent.close.end = range.end;
499
- curParent.end = range.end;
500
- curBody = (curParent = curParent.parent).body;
501
- }
502
- });
503
- parser.parse(source);
504
- return {
505
- read: parser.read,
506
- locationAt: parser.locationAt,
507
- positionAt: parser.positionAt,
508
- nodeAt: (offset) => getNodeAtOffset(offset, program),
509
- program
510
- };
511
- }
512
- function pushAttr(parent, node) {
513
- if (parent.attrs) {
514
- parent.attrs.push(node);
515
- } else {
516
- parent.attrs = [node];
517
- }
518
- }
519
- function hasCloseTag(parent) {
520
- return parent.close !== void 0;
521
- }
522
- function resolveAttrTagName(tag) {
523
- let name = tag.nameText;
524
- let parentTag = tag.owner;
525
- do {
526
- switch (parentTag.type) {
527
- case 1 /* Tag */:
528
- return parentTag.nameText ? `${parentTag.nameText}:${name}` : void 0;
529
- case 14 /* AttrTag */:
530
- name = `${parentTag.nameText}:${name}`;
531
- parentTag = parentTag.owner;
532
- break;
533
- default:
534
- return;
535
- }
536
- } while (parentTag);
537
- }
538
- function isTransparentTag(node) {
539
- return node.nameText !== void 0 && /^(?:if|else(?:-if)?|for|while)$/.test(node.nameText);
540
- }
541
-
542
- // src/utils/compiler.ts
543
- var lookupKey = Symbol("lookup");
544
- var compilerInfoByDir = /* @__PURE__ */ new Map();
545
- var builtinInfo = {
33
+ var import_resolve_from = __toESM(require("resolve-from"));
34
+ var cwd = process.cwd();
35
+ var kTaglib = Symbol("taglib");
36
+ var projectsByDir = /* @__PURE__ */ new Map();
37
+ var defaultProject = {
38
+ rootDir: cwd,
546
39
  cache: /* @__PURE__ */ new Map(),
547
- lookup: builtinCompiler.taglib.buildLookup(__dirname, builtinTranslator),
548
- compiler: builtinCompiler,
549
- translator: builtinTranslator
40
+ lookup: defaultCompiler.taglib.buildLookup(cwd, defaultTranslator),
41
+ compiler: defaultCompiler,
42
+ translator: defaultTranslator
550
43
  };
551
- builtinCompiler.configure({ translator: builtinTranslator });
552
- function parse2(doc) {
553
- const compilerInfo = getCompilerInfo(doc);
554
- let parsed = compilerInfo.cache.get(doc);
555
- if (!parsed) {
556
- const source = doc.getText();
557
- compilerInfo.cache.set(doc, parsed = parse(source));
558
- }
559
- return parsed;
560
- }
561
- function getCompilerInfo(doc) {
562
- const dir = getDocDir(doc);
44
+ defaultCompiler.configure({ translator: defaultTranslator });
45
+ function getMarkoProject(dir) {
563
46
  if (!dir)
564
- return builtinInfo;
565
- let info = compilerInfoByDir.get(dir);
566
- if (!info) {
567
- info = loadCompilerInfo(dir);
568
- compilerInfoByDir.set(dir, info);
47
+ return defaultProject;
48
+ let project = projectsByDir.get(dir);
49
+ if (!project) {
50
+ project = loadProject(dir);
51
+ projectsByDir.set(dir, project);
569
52
  }
570
- return info;
53
+ return project;
571
54
  }
572
- function clearCompilerCache(doc) {
573
- if (doc) {
574
- getCompilerInfo(doc).cache.delete(doc);
575
- } else {
576
- for (const [, info] of compilerInfoByDir) {
577
- info.cache.clear();
578
- info.compiler.taglib.clearCaches();
579
- }
580
- }
55
+ function getMarkoProjects() {
56
+ return new Set(projectsByDir.values());
581
57
  }
582
- function loadCompilerInfo(dir) {
583
- const rootDir = import_lasso_package_root.default.getRootDir(dir);
584
- const pkgPath = rootDir && import_resolve_from.default.silent(rootDir, "@marko/compiler/package.json");
58
+ function loadProject(dir) {
59
+ const rootDir = import_lasso_package_root.default.getRootDir(dir) || cwd;
60
+ const pkgPath = import_resolve_from.default.silent(rootDir, "@marko/compiler/package.json");
585
61
  const pkg = pkgPath && require(pkgPath);
586
- const cache4 = /* @__PURE__ */ new Map();
587
- let translator = builtinTranslator;
588
- let compiler = builtinCompiler;
62
+ const cache = /* @__PURE__ */ new Map();
63
+ let translator = defaultTranslator;
64
+ let compiler = defaultCompiler;
589
65
  if (pkg && /^5\./.test(pkg.version)) {
590
66
  try {
591
67
  let checkTranslator = [].concat(
@@ -604,16 +80,17 @@ function loadCompilerInfo(dir) {
604
80
  }
605
81
  }
606
82
  return {
607
- cache: cache4,
83
+ rootDir,
84
+ cache,
608
85
  get lookup() {
609
- let lookup = cache4.get(lookupKey);
86
+ let lookup = cache.get(kTaglib);
610
87
  if (lookup === void 0) {
611
88
  try {
612
89
  lookup = compiler.taglib.buildLookup(dir, translator);
613
90
  } catch {
614
- lookup = builtinInfo.lookup;
91
+ lookup = defaultProject.lookup;
615
92
  }
616
- cache4.set(lookupKey, lookup);
93
+ cache.set(kTaglib, lookup);
617
94
  }
618
95
  return lookup;
619
96
  },
@@ -622,189 +99,279 @@ function loadCompilerInfo(dir) {
622
99
  };
623
100
  }
624
101
 
625
- // src/utils/messages.ts
626
- var import_util = require("util");
627
- var connection;
628
- function setup(_) {
629
- connection = _;
102
+ // src/utils/text-documents.ts
103
+ var import_fs = __toESM(require("fs"));
104
+ var import_vscode_uri = require("vscode-uri");
105
+ var import_vscode_languageserver = require("vscode-languageserver");
106
+ var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
107
+ var docs = /* @__PURE__ */ new Map();
108
+ var openDocs = /* @__PURE__ */ new Set();
109
+ var fileExists = /* @__PURE__ */ new Map();
110
+ var fileChangeHandlers = /* @__PURE__ */ new Set();
111
+ var projectVersion = 0;
112
+ function onFileChange(handler) {
113
+ fileChangeHandlers.add(handler);
630
114
  }
631
- function displayError(data) {
632
- display("showError", data);
115
+ function getAllOpen() {
116
+ return openDocs;
633
117
  }
634
- function display(type, data) {
635
- const msg = typeof data === "string" ? data : (0, import_util.inspect)(data, { colors: false });
636
- setImmediate(() => connection.sendNotification(type, msg));
118
+ function get(uri) {
119
+ const doc = docs.get(uri);
120
+ if (doc)
121
+ return doc;
122
+ const { fsPath, scheme } = import_vscode_uri.URI.parse(uri);
123
+ if (scheme === "file") {
124
+ if (fileExists.get(uri) === false)
125
+ return void 0;
126
+ try {
127
+ const newDoc = import_vscode_languageserver_textdocument.TextDocument.create(
128
+ uri,
129
+ getLanguageId(uri),
130
+ import_fs.default.statSync(fsPath).mtimeMs,
131
+ import_fs.default.readFileSync(fsPath, "utf-8")
132
+ );
133
+ docs.set(uri, newDoc);
134
+ fileExists.set(uri, true);
135
+ return newDoc;
136
+ } catch {
137
+ fileExists.set(uri, false);
138
+ }
139
+ }
637
140
  }
638
-
639
- // src/service/index.ts
640
- var import_vscode_languageserver15 = require("vscode-languageserver");
641
-
642
- // src/service/marko/complete/index.ts
643
- var import_vscode_languageserver6 = require("vscode-languageserver");
644
-
645
- // src/service/marko/complete/Tag.ts
646
- var import_vscode_languageserver = require("vscode-languageserver");
647
- var partialCloseTagReg = /<\/(?:[^><]*>)?/iy;
648
- function Tag(event) {
649
- const { node } = event;
650
- const isClosed = node.end !== UNFINISHED;
651
- if (isClosed || node.concise)
652
- return;
653
- const { offset, parsed, code } = event;
654
- const closingTagStr = `</${node.nameText}>`;
655
- if (offset === node.open.end) {
656
- return [
657
- {
658
- label: closingTagStr,
659
- kind: import_vscode_languageserver.CompletionItemKind.Class,
660
- insertTextFormat: import_vscode_languageserver.InsertTextFormat.Snippet,
661
- insertText: `
662
- $0
663
- ${closingTagStr}`
141
+ function exists(uri) {
142
+ const cached = fileExists.get(uri);
143
+ if (cached !== void 0)
144
+ return cached;
145
+ const { fsPath, scheme } = import_vscode_uri.URI.parse(uri);
146
+ if (scheme === "file") {
147
+ try {
148
+ import_fs.default.accessSync(fsPath);
149
+ fileExists.set(uri, true);
150
+ return true;
151
+ } catch {
152
+ fileExists.set(uri, false);
153
+ return false;
154
+ }
155
+ }
156
+ return false;
157
+ }
158
+ function isOpen(doc) {
159
+ return openDocs.has(doc);
160
+ }
161
+ function setup(connection4) {
162
+ connection4.onDidOpenTextDocument((params) => {
163
+ const ref = params.textDocument;
164
+ const existingDoc = docs.get(ref.uri);
165
+ projectVersion++;
166
+ if (existingDoc) {
167
+ if (existingDoc.version === ref.version) {
168
+ openDocs.add(existingDoc);
169
+ return;
664
170
  }
665
- ];
666
- } else if (node.close && offset >= node.close.start) {
667
- const start = node.close.start;
668
- partialCloseTagReg.lastIndex = start;
669
- const [{ length }] = partialCloseTagReg.exec(code);
670
- const end = start + length;
671
- return [
672
- {
673
- label: closingTagStr,
674
- kind: import_vscode_languageserver.CompletionItemKind.Class,
675
- insertTextFormat: import_vscode_languageserver.InsertTextFormat.Snippet,
676
- textEdit: import_vscode_languageserver.TextEdit.replace(
677
- parsed.locationAt({
678
- start,
679
- end
680
- }),
681
- closingTagStr
682
- )
171
+ openDocs.delete(existingDoc);
172
+ docs.delete(ref.uri);
173
+ }
174
+ const newDoc = import_vscode_languageserver_textdocument.TextDocument.create(
175
+ ref.uri,
176
+ ref.languageId,
177
+ ref.version,
178
+ ref.text
179
+ );
180
+ openDocs.add(newDoc);
181
+ fileExists.set(ref.uri, true);
182
+ docs.set(ref.uri, newDoc);
183
+ });
184
+ connection4.onDidChangeTextDocument((params) => {
185
+ const ref = params.textDocument;
186
+ const changes = params.contentChanges;
187
+ const doc = docs.get(ref.uri);
188
+ if (changes.length > 0 && ref.version != null && doc) {
189
+ import_vscode_languageserver_textdocument.TextDocument.update(doc, changes, ref.version);
190
+ emitFileChange(doc);
191
+ }
192
+ });
193
+ connection4.onDidCloseTextDocument((params) => {
194
+ const ref = params.textDocument;
195
+ const doc = docs.get(ref.uri);
196
+ if (doc) {
197
+ projectVersion++;
198
+ openDocs.delete(doc);
199
+ if (import_vscode_uri.URI.parse(ref.uri).scheme !== "file") {
200
+ docs.delete(ref.uri);
683
201
  }
684
- ];
202
+ }
203
+ });
204
+ connection4.onDidChangeWatchedFiles(async (params) => {
205
+ for (const change of params.changes) {
206
+ switch (change.type) {
207
+ case import_vscode_languageserver.FileChangeType.Created:
208
+ fileExists.set(change.uri, true);
209
+ break;
210
+ case import_vscode_languageserver.FileChangeType.Deleted:
211
+ case import_vscode_languageserver.FileChangeType.Changed: {
212
+ fileExists.set(change.uri, change.type === import_vscode_languageserver.FileChangeType.Changed);
213
+ const doc = docs.get(change.uri);
214
+ if (doc && !openDocs.has(doc)) {
215
+ docs.delete(change.uri);
216
+ }
217
+ }
218
+ }
219
+ }
220
+ emitFileChange(void 0);
221
+ });
222
+ }
223
+ function getLanguageId(uri) {
224
+ const ext = uri.slice(uri.lastIndexOf(".") + 1);
225
+ switch (ext) {
226
+ case "cjs":
227
+ case "mjs":
228
+ case "js":
229
+ return "javascript";
230
+ case "cts":
231
+ case "mts":
232
+ case "ts":
233
+ return "typescript";
234
+ default:
235
+ return ext;
685
236
  }
686
237
  }
687
-
688
- // src/service/marko/util/get-tag-name-completion.ts
689
- var import_path2 = __toESM(require("path"));
690
- var import_vscode_languageserver2 = require("vscode-languageserver");
691
- var import_vscode_uri2 = require("vscode-uri");
692
- var deprecated = [import_vscode_languageserver2.CompletionItemTag.Deprecated];
693
- function getTagNameCompletion({
694
- tag,
695
- range,
696
- showAutoComplete,
697
- importer
698
- }) {
699
- var _a;
700
- let label = tag.isNestedTag ? `@${tag.name}` : tag.name;
701
- const fileForTag = tag.template || tag.renderer || tag.filePath;
702
- const fileURIForTag = import_vscode_uri2.URI.file(fileForTag).toString();
703
- const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(
704
- fileForTag
705
- );
706
- const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
707
- const isCoreTag = /^@?marko[/-]/.test(tag.taglibId) || nodeModuleName === "marko";
708
- const documentation = {
709
- kind: import_vscode_languageserver2.MarkupKind.Markdown,
710
- value: tag.html ? `Built in [&lt;${tag.name}&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : isCoreTag ? `Core Marko &lt;${tag.name}&gt; tag.` : nodeModuleName ? `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
711
-
712
- [${importer ? import_path2.default.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
713
- };
714
- if (tag.description) {
715
- documentation.value += `
716
-
717
- ${tag.description}`;
238
+ function emitFileChange(doc) {
239
+ projectVersion++;
240
+ for (const handler of fileChangeHandlers) {
241
+ handler(doc);
718
242
  }
719
- const autocomplete = showAutoComplete ? (_a = tag.autocomplete) == null ? void 0 : _a[0] : void 0;
720
- if (autocomplete) {
721
- if (autocomplete.displayText) {
722
- label = autocomplete.displayText;
723
- }
724
- if (autocomplete.description) {
725
- documentation.value += `
243
+ }
726
244
 
727
- ${autocomplete.description}`;
245
+ // src/utils/workspace.ts
246
+ var connection;
247
+ var configChangeHandlers = /* @__PURE__ */ new Set();
248
+ var settingsCache = /* @__PURE__ */ new Map();
249
+ async function getConfig(section) {
250
+ let cached = settingsCache.get(section);
251
+ if (!cached) {
252
+ try {
253
+ cached = await connection.workspace.getConfiguration(section) || {};
254
+ settingsCache.set(section, cached);
255
+ } catch {
728
256
  }
729
- if (autocomplete.descriptionMoreURL) {
730
- documentation.value += `
257
+ }
258
+ return cached;
259
+ }
260
+ function onConfigChange(handler) {
261
+ configChangeHandlers.add(handler);
262
+ }
263
+ function setup2(_) {
264
+ connection = _;
265
+ connection.onDidChangeConfiguration(() => {
266
+ settingsCache.clear();
267
+ emitConfigChange();
268
+ });
269
+ }
270
+ function emitConfigChange() {
271
+ for (const handler of configChangeHandlers) {
272
+ handler();
273
+ }
274
+ }
731
275
 
732
- [More Info](${autocomplete.descriptionMoreURL})`;
276
+ // src/utils/messages.ts
277
+ var import_util = require("util");
278
+ var connection2;
279
+ var previousMessagesByType = /* @__PURE__ */ new Map();
280
+ function setup3(_) {
281
+ connection2 = _;
282
+ }
283
+ function displayError(data) {
284
+ display("showError", data);
285
+ }
286
+ function display(type, data) {
287
+ const msg = typeof data === "string" ? data : (0, import_util.inspect)(data, { colors: false });
288
+ const previousMessages = previousMessagesByType.get(type);
289
+ if (previousMessages) {
290
+ if (previousMessages.includes(msg))
291
+ return;
292
+ previousMessages.push(msg);
293
+ if (previousMessages.length > 3) {
294
+ previousMessages.unshift();
733
295
  }
296
+ } else {
297
+ previousMessagesByType.set(type, [msg]);
734
298
  }
735
- return {
736
- label,
737
- documentation,
738
- tags: tag.deprecated ? deprecated : void 0,
739
- insertTextFormat: autocomplete ? import_vscode_languageserver2.InsertTextFormat.Snippet : void 0,
740
- kind: tag.html ? import_vscode_languageserver2.CompletionItemKind.Property : import_vscode_languageserver2.CompletionItemKind.Class,
741
- textEdit: range && import_vscode_languageserver2.TextEdit.replace(range, (autocomplete == null ? void 0 : autocomplete.snippet) || label)
742
- };
299
+ setImmediate(() => connection2.sendNotification(type, msg));
743
300
  }
744
301
 
745
- // src/service/marko/complete/OpenTagName.ts
746
- function OpenTagName({
747
- document,
748
- lookup,
749
- parsed,
750
- node
751
- }) {
752
- var _a;
753
- const importer = getDocFile(document);
754
- const tag = node.parent;
755
- const range = parsed.locationAt(node);
756
- const isAttrTag = tag.type === 14 /* AttrTag */;
757
- const result = [];
758
- if (isAttrTag) {
759
- let parentTag = tag.owner;
760
- while ((parentTag == null ? void 0 : parentTag.type) === 14 /* AttrTag */)
761
- parentTag = parentTag.owner;
762
- const parentTagDef = parentTag && parentTag.nameText && lookup.getTag(parentTag.nameText);
763
- if (parentTagDef) {
764
- const { nestedTags } = parentTagDef;
765
- for (const key in nestedTags) {
766
- if (key !== "*") {
767
- const tag2 = nestedTags[key];
768
- result.push(
769
- getTagNameCompletion({
770
- tag: tag2,
771
- range,
772
- importer,
773
- showAutoComplete: true
774
- })
775
- );
776
- }
302
+ // src/utils/file.ts
303
+ var import_path = __toESM(require("path"));
304
+ var import_language_tools = require("@marko/language-tools");
305
+ var import_vscode_uri2 = require("vscode-uri");
306
+ var processorCaches = /* @__PURE__ */ new WeakMap();
307
+ function getFSDir(doc) {
308
+ const filename = getFSPath(doc);
309
+ return filename ? import_path.default.dirname(filename) : void 0;
310
+ }
311
+ function getFSPath(doc) {
312
+ return import_vscode_uri2.URI.parse(doc.uri).fsPath;
313
+ }
314
+ function getMarkoFile(doc) {
315
+ const { uri } = doc;
316
+ const { fsPath: filename, scheme } = import_vscode_uri2.URI.parse(uri);
317
+ const dirname = filename && import_path.default.dirname(filename);
318
+ const project = getMarkoProject(dirname);
319
+ const cache = project.cache;
320
+ let file = cache.get(doc);
321
+ if (!file) {
322
+ const { version } = doc;
323
+ const code = doc.getText();
324
+ const parsed = (0, import_language_tools.parse)(code, filename);
325
+ cache.set(
326
+ doc,
327
+ file = {
328
+ project,
329
+ uri,
330
+ scheme,
331
+ version,
332
+ filename,
333
+ dirname,
334
+ parsed,
335
+ code
777
336
  }
337
+ );
338
+ }
339
+ return file;
340
+ }
341
+ function processDoc(doc, process2) {
342
+ const file = getMarkoFile(doc);
343
+ const cache = processorCaches.get(file.parsed);
344
+ let result;
345
+ if (cache) {
346
+ result = cache.get(process2);
347
+ if (!result) {
348
+ result = process2(file);
349
+ cache.set(process2, result);
778
350
  }
779
351
  } else {
780
- const skipStatements = !(tag.concise && tag.parent.type === 0 /* Program */);
781
- for (const tag2 of lookup.getTagsSorted()) {
782
- if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
783
- result.push(
784
- getTagNameCompletion({
785
- tag: tag2,
786
- range,
787
- importer,
788
- showAutoComplete: true
789
- })
790
- );
791
- }
792
- }
352
+ result = process2(file);
353
+ processorCaches.set(file.parsed, /* @__PURE__ */ new Map([[process2, result]]));
793
354
  }
794
355
  return result;
795
356
  }
796
357
 
358
+ // src/service/index.ts
359
+ var import_vscode_languageserver12 = require("vscode-languageserver");
360
+
361
+ // src/service/marko/complete/index.ts
362
+ var import_language_tools5 = require("@marko/language-tools");
363
+
797
364
  // src/service/marko/complete/AttrName.ts
798
- var import_vscode_languageserver3 = require("vscode-languageserver");
365
+ var import_vscode_languageserver2 = require("vscode-languageserver");
799
366
  function AttrName({
800
367
  offset,
801
368
  node,
802
- parsed,
803
- lookup
369
+ file: {
370
+ parsed,
371
+ project: { lookup }
372
+ }
804
373
  }) {
805
374
  let name = parsed.read(node);
806
- if (name[0] === "{")
807
- return;
808
375
  const modifierIndex = name.indexOf(":");
809
376
  const hasModifier = modifierIndex !== -1;
810
377
  if (hasModifier) {
@@ -812,12 +379,12 @@ function AttrName({
812
379
  return [
813
380
  {
814
381
  label: "scoped",
815
- kind: import_vscode_languageserver3.CompletionItemKind.Keyword,
382
+ kind: import_vscode_languageserver2.CompletionItemKind.Keyword,
816
383
  detail: "Use to prefix with a unique ID"
817
384
  },
818
385
  {
819
386
  label: "no-update",
820
- kind: import_vscode_languageserver3.CompletionItemKind.Keyword,
387
+ kind: import_vscode_languageserver2.CompletionItemKind.Keyword,
821
388
  detail: "Use to skip future updates to this attribute"
822
389
  }
823
390
  ];
@@ -835,25 +402,19 @@ function AttrName({
835
402
  const tagName = node.parent.parent.nameText || "";
836
403
  const tagDef = tagName && lookup.getTag(tagName);
837
404
  const nestedTagAttrs = {};
838
- const neverAttrs = /* @__PURE__ */ new Set();
839
405
  if (tagDef && tagDef.nestedTags) {
840
406
  for (const key in tagDef.nestedTags) {
841
407
  const nestedTagDef = tagDef.nestedTags[key];
842
408
  nestedTagAttrs[nestedTagDef.targetProperty] = true;
843
409
  }
844
410
  }
845
- lookup.forEachAttribute(tagName, (attr) => {
846
- if (attr.type === "never") {
847
- neverAttrs.add(attr.name);
848
- }
849
- });
850
411
  lookup.forEachAttribute(tagName, (attr, parent) => {
851
- if (attr.deprecated || nestedTagAttrs[attr.name] || attr.name === "*" || neverAttrs.has(attr.name) || attr.name[0] === "_" && /\/node_modules\//.test(attr.filePath || parent.filePath)) {
412
+ if (attr.deprecated || nestedTagAttrs[attr.name] || attr.name === "*" || attr.type === "never" || attr.name[0] === "_" && isExternalModule(attr.filePath || parent.filePath)) {
852
413
  return;
853
414
  }
854
415
  const type = attr.type || (attr.html ? "string" : null);
855
416
  const documentation = {
856
- kind: import_vscode_languageserver3.MarkupKind.Markdown,
417
+ kind: import_vscode_languageserver2.MarkupKind.Markdown,
857
418
  value: attr.description || ""
858
419
  };
859
420
  let label = attr.name;
@@ -893,19 +454,23 @@ function AttrName({
893
454
  completions.push({
894
455
  label,
895
456
  documentation: documentation.value ? documentation : void 0,
896
- kind: import_vscode_languageserver3.CompletionItemKind.Property,
897
- insertTextFormat: import_vscode_languageserver3.InsertTextFormat.Snippet,
898
- textEdit: import_vscode_languageserver3.TextEdit.replace(attrNameLoc, snippet)
457
+ kind: import_vscode_languageserver2.CompletionItemKind.Property,
458
+ insertTextFormat: import_vscode_languageserver2.InsertTextFormat.Snippet,
459
+ textEdit: import_vscode_languageserver2.TextEdit.replace(attrNameLoc, snippet)
899
460
  });
900
461
  });
901
462
  return completions;
902
463
  }
464
+ function isExternalModule(file) {
465
+ return /[/\\]node_modules[/\\]/.test(file) || !/^(?:[A-Za-z]:\\|[./\\])/.test(file);
466
+ }
903
467
 
904
468
  // src/service/marko/complete/AttrValue.ts
905
- var import_path3 = __toESM(require("path"));
906
- var import_vscode_languageserver4 = require("vscode-languageserver");
469
+ var import_path2 = __toESM(require("path"));
470
+ var import_vscode_languageserver3 = require("vscode-languageserver");
907
471
 
908
472
  // src/service/marko/util/is-document-link-attr.ts
473
+ var import_language_tools2 = require("@marko/language-tools");
909
474
  var linkedAttrs = /* @__PURE__ */ new Map([
910
475
  [
911
476
  "src",
@@ -925,15 +490,15 @@ var linkedAttrs = /* @__PURE__ */ new Map([
925
490
  ["data", /* @__PURE__ */ new Set(["object"])],
926
491
  ["poster", /* @__PURE__ */ new Set(["video"])]
927
492
  ]);
928
- function isDocumentLinkAttr(doc, tag, attr) {
493
+ function isDocumentLinkAttr(code, tag, attr) {
929
494
  var _a, _b;
930
- return tag.nameText && attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(doc.getText()[attr.value.value.start]) && ((_b = linkedAttrs.get(doc.getText().slice(attr.name.start, attr.name.end))) == null ? void 0 : _b.has(tag.nameText)) || false;
495
+ return tag.nameText && attr.type === import_language_tools2.NodeType.AttrNamed && ((_a = attr.value) == null ? void 0 : _a.type) === import_language_tools2.NodeType.AttrValue && /^['"]$/.test(code[attr.value.value.start]) && ((_b = linkedAttrs.get(code.slice(attr.name.start, attr.name.end))) == null ? void 0 : _b.has(tag.nameText)) || false;
931
496
  }
932
497
 
933
498
  // src/utils/file-system.ts
934
499
  var import_promises = __toESM(require("fs/promises"));
935
- var import_vscode_css_languageservice = require("vscode-css-languageservice");
936
500
  var import_url = require("url");
501
+ var import_vscode_css_languageservice = require("vscode-css-languageservice");
937
502
  var file_system_default = {
938
503
  stat,
939
504
  readDirectory
@@ -962,17 +527,18 @@ async function stat(uri) {
962
527
  };
963
528
  }
964
529
  async function readDirectory(uri) {
530
+ const result = [];
965
531
  try {
966
- const entries = await import_promises.default.readdir((0, import_url.fileURLToPath)(uri));
967
- const base = uri.at(-1) === "/" ? uri : `${uri}/`;
968
- return (await Promise.all(
969
- entries.map(
970
- async (entry) => [entry, (await stat(new URL(entry, base).toString())).type]
971
- )
972
- )).filter(([, type]) => type !== import_vscode_css_languageservice.FileType.Unknown);
532
+ for await (const entry of await import_promises.default.opendir((0, import_url.fileURLToPath)(uri))) {
533
+ if (entry.isFile()) {
534
+ result.push([entry.name, import_vscode_css_languageservice.FileType.File]);
535
+ } else if (entry.isDirectory()) {
536
+ result.push([entry.name, import_vscode_css_languageservice.FileType.Directory]);
537
+ }
538
+ }
973
539
  } catch {
974
- return [];
975
540
  }
541
+ return result;
976
542
  }
977
543
 
978
544
  // src/utils/resolve-url.ts
@@ -988,14 +554,12 @@ function resolveUrl(to, base) {
988
554
 
989
555
  // src/service/marko/complete/AttrValue.ts
990
556
  async function AttrValue({
991
- document,
992
557
  offset,
993
558
  node,
994
- parsed,
995
- code
559
+ file: { uri, parsed, code }
996
560
  }) {
997
561
  const attr = node.parent;
998
- if (isDocumentLinkAttr(document, attr.parent, attr)) {
562
+ if (isDocumentLinkAttr(code, attr.parent, attr)) {
999
563
  const start = node.value.start + 1;
1000
564
  if (code[start] !== ".")
1001
565
  return;
@@ -1009,29 +573,29 @@ async function AttrValue({
1009
573
  if (segmentStart === -1)
1010
574
  return;
1011
575
  const req = rawValue.slice(0, segmentStart);
1012
- const uri = resolveUrl(req, document.uri);
1013
- if (uri) {
576
+ const resolved = resolveUrl(req, uri);
577
+ if (resolved) {
1014
578
  const result = [];
1015
- const curFile = req === "." ? import_path3.default.basename(document.uri) : void 0;
1016
- const replaceRange = import_vscode_languageserver4.Range.create(
1017
- document.positionAt(start + segmentStart + 1),
1018
- document.positionAt(start + rawValue.length)
1019
- );
1020
- for (const [entry, type] of await file_system_default.readDirectory(uri)) {
579
+ const curFile = req === "." ? import_path2.default.basename(uri) : void 0;
580
+ const replaceRange = parsed.locationAt({
581
+ start: start + segmentStart + 1,
582
+ end: start + rawValue.length
583
+ });
584
+ for (const [entry, type] of await file_system_default.readDirectory(resolved)) {
1021
585
  if (entry[0] !== "." && entry !== curFile) {
1022
586
  result.push(
1023
587
  type === import_vscode_css_languageservice.FileType.Directory ? {
1024
588
  label: `${entry}/`,
1025
- kind: import_vscode_languageserver4.CompletionItemKind.Folder,
1026
- textEdit: import_vscode_languageserver4.TextEdit.replace(replaceRange, `${entry}/`),
589
+ kind: import_vscode_languageserver3.CompletionItemKind.Folder,
590
+ textEdit: import_vscode_languageserver3.TextEdit.replace(replaceRange, `${entry}/`),
1027
591
  command: {
1028
592
  title: "Suggest",
1029
593
  command: "editor.action.triggerSuggest"
1030
594
  }
1031
595
  } : {
1032
596
  label: entry,
1033
- kind: import_vscode_languageserver4.CompletionItemKind.File,
1034
- textEdit: import_vscode_languageserver4.TextEdit.replace(replaceRange, entry)
597
+ kind: import_vscode_languageserver3.CompletionItemKind.File,
598
+ textEdit: import_vscode_languageserver3.TextEdit.replace(replaceRange, entry)
1035
599
  }
1036
600
  );
1037
601
  }
@@ -1041,43 +605,200 @@ async function AttrValue({
1041
605
  }
1042
606
  }
1043
607
 
1044
- // src/service/marko/complete/Statement.ts
608
+ // src/service/marko/complete/Import.ts
1045
609
  var import_vscode_languageserver5 = require("vscode-languageserver");
1046
- var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1047
- function Statement({
1048
- code,
610
+
611
+ // src/service/marko/util/get-tag-name-completion.ts
612
+ var import_path3 = __toESM(require("path"));
613
+ var import_vscode_languageserver4 = require("vscode-languageserver");
614
+ var import_vscode_uri3 = require("vscode-uri");
615
+ var deprecated = [import_vscode_languageserver4.CompletionItemTag.Deprecated];
616
+ function getTagNameCompletion({
617
+ tag,
618
+ range,
619
+ showAutoComplete,
620
+ importer
621
+ }) {
622
+ var _a;
623
+ let label = tag.isNestedTag ? `@${tag.name}` : tag.name;
624
+ const fileForTag = tag.template || tag.renderer || tag.filePath;
625
+ const fileURIForTag = import_vscode_uri3.URI.file(fileForTag).toString();
626
+ const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(
627
+ fileForTag
628
+ );
629
+ const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
630
+ const isCoreTag = /^@?marko[/-]/.test(tag.taglibId || tag.filePath) || nodeModuleName === "marko";
631
+ const documentation = {
632
+ kind: import_vscode_languageserver4.MarkupKind.Markdown,
633
+ value: tag.html ? `Built in [&lt;${tag.name}&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : isCoreTag ? `Core Marko &lt;${tag.name}&gt; tag.` : nodeModuleName ? `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
634
+
635
+ [${importer ? import_path3.default.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
636
+ };
637
+ if (tag.description) {
638
+ documentation.value += `
639
+
640
+ ${tag.description}`;
641
+ }
642
+ const autocomplete = showAutoComplete ? (_a = tag.autocomplete) == null ? void 0 : _a[0] : void 0;
643
+ if (autocomplete) {
644
+ if (autocomplete.displayText) {
645
+ label = autocomplete.displayText;
646
+ }
647
+ if (autocomplete.description) {
648
+ documentation.value += `
649
+
650
+ ${autocomplete.description}`;
651
+ }
652
+ if (autocomplete.descriptionMoreURL) {
653
+ documentation.value += `
654
+
655
+ [More Info](${autocomplete.descriptionMoreURL})`;
656
+ }
657
+ }
658
+ return {
659
+ label,
660
+ documentation,
661
+ tags: tag.deprecated ? deprecated : void 0,
662
+ insertTextFormat: autocomplete ? import_vscode_languageserver4.InsertTextFormat.Snippet : void 0,
663
+ kind: tag.html ? import_vscode_languageserver4.CompletionItemKind.Property : import_vscode_languageserver4.CompletionItemKind.Class,
664
+ textEdit: range && import_vscode_languageserver4.TextEdit.replace(range, (autocomplete == null ? void 0 : autocomplete.snippet) || label)
665
+ };
666
+ }
667
+
668
+ // src/service/marko/complete/Import.ts
669
+ var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/;
670
+ function Import({
1049
671
  node,
1050
- parsed,
1051
- lookup,
1052
- document
672
+ file: {
673
+ parsed,
674
+ filename,
675
+ project: { lookup }
676
+ }
1053
677
  }) {
1054
678
  var _a;
1055
- if (code[node.start] === "i") {
1056
- importTagReg.lastIndex = 0;
1057
- const value = parsed.read(node);
1058
- const match = importTagReg.exec(value);
1059
- if (match) {
1060
- const importer = getDocFile(document);
1061
- const [{ length }] = match;
1062
- const range = parsed.locationAt({
1063
- start: node.start + match.index + 1,
1064
- end: node.start + match.index + length - 1
1065
- });
1066
- const result = [];
1067
- for (const tag of lookup.getTagsSorted()) {
1068
- if ((tag.template || tag.renderer) && !(tag.html || tag.parser || tag.translator || tag.isNestedTag || tag.name === "*" || ((_a = tag.parseOptions) == null ? void 0 : _a.statement) || /^@?marko[/-]/.test(tag.taglibId) || tag.name[0] === "_" && /[\\/]node_modules[\\/]/.test(tag.filePath))) {
1069
- const completion = getTagNameCompletion({
1070
- tag,
1071
- importer
1072
- });
1073
- completion.label = `<${completion.label}>`;
1074
- completion.textEdit = import_vscode_languageserver5.TextEdit.replace(range, completion.label);
1075
- result.push(completion);
679
+ const value = parsed.read(node);
680
+ const match = importTagReg.exec(value);
681
+ if (match) {
682
+ const [{ length }] = match;
683
+ const fromStart = node.start + match.index;
684
+ const range = parsed.locationAt({
685
+ start: fromStart + 1,
686
+ end: fromStart + length - 1
687
+ });
688
+ const result = [];
689
+ for (const tag of lookup.getTagsSorted()) {
690
+ if ((tag.template || tag.renderer) && !(tag.html || tag.parser || tag.translator || tag.isNestedTag || tag.name === "*" || ((_a = tag.parseOptions) == null ? void 0 : _a.statement) || /^@?marko[/-]/.test(tag.taglibId) || tag.name[0] === "_" && /[\\/]node_modules[\\/]/.test(tag.filePath))) {
691
+ const completion = getTagNameCompletion({
692
+ tag,
693
+ importer: filename
694
+ });
695
+ completion.label = `<${completion.label}>`;
696
+ completion.textEdit = import_vscode_languageserver5.TextEdit.replace(range, completion.label);
697
+ result.push(completion);
698
+ }
699
+ }
700
+ return result;
701
+ }
702
+ }
703
+
704
+ // src/service/marko/complete/OpenTagName.ts
705
+ var import_language_tools3 = require("@marko/language-tools");
706
+ function OpenTagName({
707
+ node,
708
+ file: {
709
+ parsed,
710
+ filename,
711
+ project: { lookup }
712
+ }
713
+ }) {
714
+ var _a;
715
+ const tag = node.parent;
716
+ const range = parsed.locationAt(node);
717
+ const isAttrTag = tag.type === import_language_tools3.NodeType.AttrTag;
718
+ const result = [];
719
+ if (isAttrTag) {
720
+ let parentTag = tag.owner;
721
+ while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools3.NodeType.AttrTag)
722
+ parentTag = parentTag.owner;
723
+ const parentTagDef = parentTag && parentTag.nameText && lookup.getTag(parentTag.nameText);
724
+ if (parentTagDef) {
725
+ const { nestedTags } = parentTagDef;
726
+ for (const key in nestedTags) {
727
+ if (key !== "*") {
728
+ const tag2 = nestedTags[key];
729
+ result.push(
730
+ getTagNameCompletion({
731
+ tag: tag2,
732
+ range,
733
+ importer: filename,
734
+ showAutoComplete: true
735
+ })
736
+ );
1076
737
  }
1077
738
  }
1078
- return result;
739
+ }
740
+ } else {
741
+ const skipStatements = !(tag.concise && tag.parent.type === import_language_tools3.NodeType.Program);
742
+ for (const tag2 of lookup.getTagsSorted()) {
743
+ if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
744
+ const completion = getTagNameCompletion({
745
+ tag: tag2,
746
+ range,
747
+ importer: filename,
748
+ showAutoComplete: true
749
+ });
750
+ completion.sortText = `0${completion.label}`;
751
+ result.push(completion);
752
+ }
1079
753
  }
1080
754
  }
755
+ return result;
756
+ }
757
+
758
+ // src/service/marko/complete/Tag.ts
759
+ var import_vscode_languageserver6 = require("vscode-languageserver");
760
+ var import_language_tools4 = require("@marko/language-tools");
761
+ var partialCloseTagReg = /<\/(?:[^><]*>)?/iy;
762
+ function Tag({
763
+ node,
764
+ offset,
765
+ file: { parsed, code }
766
+ }) {
767
+ const isClosed = node.end !== import_language_tools4.UNFINISHED;
768
+ if (isClosed || node.concise)
769
+ return;
770
+ const closingTagStr = `</${node.nameText || ""}>`;
771
+ if (offset === node.open.end) {
772
+ return [
773
+ {
774
+ label: closingTagStr,
775
+ kind: import_vscode_languageserver6.CompletionItemKind.Class,
776
+ insertTextFormat: import_vscode_languageserver6.InsertTextFormat.Snippet,
777
+ insertText: `
778
+ $0
779
+ ${closingTagStr}`
780
+ }
781
+ ];
782
+ } else if (node.close && offset >= node.close.start) {
783
+ const start = node.close.start;
784
+ partialCloseTagReg.lastIndex = start;
785
+ const [{ length }] = partialCloseTagReg.exec(code);
786
+ const end = start + length;
787
+ return [
788
+ {
789
+ label: closingTagStr,
790
+ kind: import_vscode_languageserver6.CompletionItemKind.Class,
791
+ insertTextFormat: import_vscode_languageserver6.InsertTextFormat.Snippet,
792
+ textEdit: import_vscode_languageserver6.TextEdit.replace(
793
+ parsed.locationAt({
794
+ start,
795
+ end
796
+ }),
797
+ closingTagStr
798
+ )
799
+ }
800
+ ];
801
+ }
1081
802
  }
1082
803
 
1083
804
  // src/service/marko/complete/index.ts
@@ -1086,37 +807,37 @@ var handlers = {
1086
807
  OpenTagName,
1087
808
  AttrName,
1088
809
  AttrValue,
1089
- Statement
810
+ Import
1090
811
  };
1091
812
  var doComplete = async (doc, params) => {
1092
813
  var _a;
1093
- const parsed = parse2(doc);
814
+ const file = getMarkoFile(doc);
1094
815
  const offset = doc.offsetAt(params.position);
1095
- const node = parsed.nodeAt(offset);
1096
- return import_vscode_languageserver6.CompletionList.create(
1097
- await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
1098
- document: doc,
816
+ const node = file.parsed.nodeAt(offset);
817
+ return {
818
+ items: await ((_a = handlers[import_language_tools5.NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
819
+ file,
1099
820
  params,
1100
- parsed,
1101
821
  offset,
1102
- node,
1103
- code: doc.getText(),
1104
- ...getCompilerInfo(doc)
822
+ node
1105
823
  })) || [],
1106
- true
1107
- );
824
+ isIncomplete: true
825
+ };
1108
826
  };
1109
827
 
1110
828
  // src/service/marko/validate.ts
829
+ var import_path4 = __toESM(require("path"));
1111
830
  var import_vscode_languageserver7 = require("vscode-languageserver");
1112
831
  var markoErrorRegExp = /^(.+?)\.marko(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
1113
832
  var doValidate = (doc) => {
1114
- const fsPath = getDocFile(doc);
833
+ const filename = getFSPath(doc);
1115
834
  const diagnostics = [];
1116
- const { compiler, translator, cache: cache4 } = getCompilerInfo(doc);
835
+ const { compiler, translator, cache } = getMarkoProject(
836
+ filename && import_path4.default.dirname(filename)
837
+ );
1117
838
  try {
1118
- compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
1119
- cache: cache4,
839
+ compiler.compileSync(doc.getText(), filename || "untitled.marko", {
840
+ cache,
1120
841
  translator,
1121
842
  code: false,
1122
843
  output: "source",
@@ -1152,42 +873,43 @@ var doValidate = (doc) => {
1152
873
  return diagnostics;
1153
874
  };
1154
875
 
1155
- // src/utils/utils.ts
1156
- var import_fs = __toESM(require("fs"));
1157
- var import_vscode_uri3 = require("vscode-uri");
1158
- var import_vscode_languageserver8 = require("vscode-languageserver");
1159
- var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
1160
- var START_OF_FILE = import_vscode_languageserver8.Range.create(
1161
- import_vscode_languageserver8.Position.create(0, 0),
1162
- import_vscode_languageserver8.Position.create(0, 0)
1163
- );
1164
- function createTextDocument(filename) {
1165
- const uri = import_vscode_uri3.URI.file(filename).toString();
1166
- const content = import_fs.default.readFileSync(filename, "utf-8");
1167
- return import_vscode_languageserver_textdocument.TextDocument.create(uri, "plaintext", 0, content);
1168
- }
876
+ // src/service/marko/hover/index.ts
877
+ var import_language_tools6 = require("@marko/language-tools");
878
+
879
+ // src/utils/constants.ts
880
+ var START_POSITION = {
881
+ line: 0,
882
+ character: 0
883
+ };
884
+ var START_LOCATION = {
885
+ start: START_POSITION,
886
+ end: START_POSITION
887
+ };
1169
888
 
1170
889
  // src/service/marko/hover/OpenTagName.ts
1171
890
  function OpenTagName2({
1172
- document,
1173
- lookup,
1174
- parsed,
1175
- node
891
+ node,
892
+ file: {
893
+ parsed,
894
+ filename,
895
+ project: { lookup }
896
+ }
1176
897
  }) {
1177
- const importer = getDocFile(document);
1178
898
  const tag = node.parent;
1179
899
  const range = parsed.locationAt(node);
1180
900
  const tagDef = tag.nameText && lookup.getTag(tag.nameText);
1181
901
  if (tagDef) {
1182
902
  const completion = getTagNameCompletion({
1183
903
  tag: tagDef,
1184
- range: START_OF_FILE,
1185
- importer
904
+ range: START_LOCATION,
905
+ importer: filename
1186
906
  });
1187
- return {
1188
- range,
1189
- contents: completion.documentation
1190
- };
907
+ if (completion.documentation) {
908
+ return {
909
+ range,
910
+ contents: completion.documentation
911
+ };
912
+ }
1191
913
  }
1192
914
  }
1193
915
 
@@ -1197,24 +919,24 @@ var handlers2 = {
1197
919
  };
1198
920
  var doHover = async (doc, params) => {
1199
921
  var _a;
1200
- const parsed = parse2(doc);
922
+ const file = getMarkoFile(doc);
1201
923
  const offset = doc.offsetAt(params.position);
1202
- const node = parsed.nodeAt(offset);
1203
- return await ((_a = handlers2[NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1204
- document: doc,
924
+ const node = file.parsed.nodeAt(offset);
925
+ return await ((_a = handlers2[import_language_tools6.NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
926
+ file,
1205
927
  params,
1206
- parsed,
1207
928
  offset,
1208
- node,
1209
- code: doc.getText(),
1210
- ...getCompilerInfo(doc)
929
+ node
1211
930
  }));
1212
931
  };
1213
932
 
1214
- // src/service/marko/definition/OpenTagName.ts
1215
- var import_path4 = __toESM(require("path"));
933
+ // src/service/marko/definition/index.ts
934
+ var import_language_tools9 = require("@marko/language-tools");
935
+
936
+ // src/service/marko/definition/AttrName.ts
937
+ var import_fs2 = __toESM(require("fs"));
1216
938
  var import_vscode_uri4 = require("vscode-uri");
1217
- var import_vscode_languageserver9 = require("vscode-languageserver");
939
+ var import_language_tools7 = require("@marko/language-tools");
1218
940
 
1219
941
  // src/utils/regexp-builder.ts
1220
942
  function RegExpBuilder(strings, ...expressions) {
@@ -1240,18 +962,67 @@ function escape(val) {
1240
962
  return String(val).replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
1241
963
  }
1242
964
 
965
+ // src/service/marko/definition/AttrName.ts
966
+ function AttrName2({
967
+ node,
968
+ file: {
969
+ parsed,
970
+ project: { lookup }
971
+ }
972
+ }) {
973
+ const tagName = node.parent.parent.nameText;
974
+ const attrName = parsed.read(node);
975
+ const tagDef = tagName ? lookup.getTag(tagName) : void 0;
976
+ const attrDef = lookup.getAttribute(tagName || "", attrName);
977
+ let range = START_LOCATION;
978
+ if (!attrDef) {
979
+ return;
980
+ }
981
+ const attrEntryFile = attrDef.filePath || (tagDef == null ? void 0 : tagDef.filePath);
982
+ if (!attrEntryFile) {
983
+ return;
984
+ }
985
+ if (/\.json$/.test(attrEntryFile)) {
986
+ const tagDefSource = import_fs2.default.readFileSync(attrEntryFile, "utf-8");
987
+ const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(
988
+ tagDefSource
989
+ );
990
+ if (match && match.index) {
991
+ range = (0, import_language_tools7.getLocation)(
992
+ (0, import_language_tools7.getLines)(tagDefSource),
993
+ match.index,
994
+ match.index + match[0].length
995
+ );
996
+ }
997
+ return [
998
+ {
999
+ targetUri: import_vscode_uri4.URI.file(attrEntryFile).toString(),
1000
+ targetRange: range,
1001
+ targetSelectionRange: range,
1002
+ originSelectionRange: parsed.locationAt(node)
1003
+ }
1004
+ ];
1005
+ }
1006
+ }
1007
+
1243
1008
  // src/service/marko/definition/OpenTagName.ts
1009
+ var import_fs3 = __toESM(require("fs"));
1010
+ var import_path5 = __toESM(require("path"));
1011
+ var import_vscode_uri5 = require("vscode-uri");
1012
+ var import_language_tools8 = require("@marko/language-tools");
1244
1013
  function OpenTagName3({
1245
- lookup,
1246
- parsed,
1247
- node
1014
+ node,
1015
+ file: {
1016
+ parsed,
1017
+ project: { lookup }
1018
+ }
1248
1019
  }) {
1249
1020
  const tag = node.parent;
1250
1021
  let tagDef;
1251
- let range = START_OF_FILE;
1252
- if (tag.type === 14 /* AttrTag */) {
1022
+ let range = START_LOCATION;
1023
+ if (tag.type === import_language_tools8.NodeType.AttrTag) {
1253
1024
  let parentTag = tag.owner;
1254
- while ((parentTag == null ? void 0 : parentTag.type) === 14 /* AttrTag */)
1025
+ while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools8.NodeType.AttrTag)
1255
1026
  parentTag = parentTag.owner;
1256
1027
  tagDef = parentTag && parentTag.nameText ? lookup.getTag(parentTag.nameText) : void 0;
1257
1028
  } else {
@@ -1261,72 +1032,29 @@ function OpenTagName3({
1261
1032
  return;
1262
1033
  }
1263
1034
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
1264
- if (!import_path4.default.isAbsolute(tagEntryFile)) {
1035
+ if (!import_path5.default.isAbsolute(tagEntryFile)) {
1265
1036
  return;
1266
1037
  }
1267
1038
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
1268
- const tagDefDoc = createTextDocument(tagEntryFile);
1039
+ const tagDefSource = import_fs3.default.readFileSync(tagEntryFile, "utf-8");
1269
1040
  const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(
1270
- tagDefDoc.getText()
1041
+ tagDefSource
1271
1042
  );
1272
1043
  if (match && match.index) {
1273
- range = import_vscode_languageserver9.Range.create(
1274
- tagDefDoc.positionAt(match.index),
1275
- tagDefDoc.positionAt(match.index + match[0].length)
1044
+ range = (0, import_language_tools8.getLocation)(
1045
+ (0, import_language_tools8.getLines)(tagDefSource),
1046
+ match.index,
1047
+ match.index + match[0].length
1276
1048
  );
1277
1049
  }
1278
1050
  }
1279
1051
  return [
1280
- import_vscode_languageserver9.LocationLink.create(
1281
- import_vscode_uri4.URI.file(tagEntryFile).toString(),
1282
- range,
1283
- range,
1284
- parsed.locationAt(node)
1285
- )
1286
- ];
1287
- }
1288
-
1289
- // src/service/marko/definition/AttrName.ts
1290
- var import_vscode_uri5 = require("vscode-uri");
1291
- var import_vscode_languageserver10 = require("vscode-languageserver");
1292
- function AttrName2({
1293
- lookup,
1294
- parsed,
1295
- node
1296
- }) {
1297
- const tagName = node.parent.parent.nameText;
1298
- const attrName = parsed.read(node);
1299
- if (attrName[0] === "{")
1300
- return;
1301
- const tagDef = tagName && lookup.getTag(tagName);
1302
- const attrDef = lookup.getAttribute(tagName || "", attrName);
1303
- let range = START_OF_FILE;
1304
- if (!attrDef) {
1305
- return;
1306
- }
1307
- const attrEntryFile = attrDef.filePath || tagDef && tagDef.filePath;
1308
- if (!attrEntryFile) {
1309
- return;
1310
- }
1311
- if (/\/marko(?:-tag)?\.json$/.test(attrEntryFile)) {
1312
- const tagDefDoc = createTextDocument(attrEntryFile);
1313
- const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(
1314
- tagDefDoc.getText()
1315
- );
1316
- if (match && match.index) {
1317
- range = import_vscode_languageserver10.Range.create(
1318
- tagDefDoc.positionAt(match.index),
1319
- tagDefDoc.positionAt(match.index + match[0].length)
1320
- );
1052
+ {
1053
+ targetUri: import_vscode_uri5.URI.file(tagEntryFile).toString(),
1054
+ targetRange: range,
1055
+ targetSelectionRange: range,
1056
+ originSelectionRange: parsed.locationAt(node)
1321
1057
  }
1322
- }
1323
- return [
1324
- import_vscode_languageserver10.LocationLink.create(
1325
- import_vscode_uri5.URI.file(attrEntryFile).toString(),
1326
- range,
1327
- range,
1328
- parsed.locationAt(node)
1329
- )
1330
1058
  ];
1331
1059
  }
1332
1060
 
@@ -1337,66 +1065,57 @@ var handlers3 = {
1337
1065
  };
1338
1066
  var findDefinition = async (doc, params) => {
1339
1067
  var _a;
1340
- const parsed = parse2(doc);
1068
+ const file = getMarkoFile(doc);
1341
1069
  const offset = doc.offsetAt(params.position);
1342
- const node = parsed.nodeAt(offset);
1343
- return await ((_a = handlers3[NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1344
- document: doc,
1070
+ const node = file.parsed.nodeAt(offset);
1071
+ return await ((_a = handlers3[import_language_tools9.NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1072
+ file,
1345
1073
  params,
1346
- parsed,
1347
1074
  offset,
1348
- node,
1349
- code: doc.getText(),
1350
- ...getCompilerInfo(doc)
1075
+ node
1351
1076
  })) || [];
1352
1077
  };
1353
1078
 
1354
1079
  // src/service/marko/document-links.ts
1355
- var import_vscode_languageserver11 = require("vscode-languageserver");
1356
- var import_vscode_uri6 = require("vscode-uri");
1080
+ var import_language_tools10 = require("@marko/language-tools");
1357
1081
  var importTagReg2 = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1358
- var cache = /* @__PURE__ */ new WeakMap();
1359
1082
  var findDocumentLinks = async (doc) => {
1360
- const parsed = parse2(doc);
1361
- let result = cache.get(parsed);
1362
- if (!result) {
1363
- result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1364
- cache.set(parsed, result);
1365
- }
1366
- return result;
1083
+ return processDoc(doc, extractDocumentLinks);
1367
1084
  };
1368
- function extractDocumentLinks(doc, parsed, lookup) {
1369
- if (import_vscode_uri6.URI.parse(doc.uri).scheme === "untitled") {
1085
+ function extractDocumentLinks({
1086
+ uri,
1087
+ scheme,
1088
+ parsed,
1089
+ code,
1090
+ project: { lookup }
1091
+ }) {
1092
+ if (scheme !== "file") {
1370
1093
  return [];
1371
1094
  }
1372
1095
  const links = [];
1373
- const { program } = parsed;
1374
- const code = doc.getText();
1375
- const read = (range) => code.slice(range.start, range.end);
1096
+ const { program, read } = parsed;
1376
1097
  const visit = (node) => {
1377
1098
  switch (node.type) {
1378
- case 14 /* AttrTag */:
1099
+ case import_language_tools10.NodeType.AttrTag:
1379
1100
  if (node.body) {
1380
1101
  for (const child of node.body) {
1381
1102
  visit(child);
1382
1103
  }
1383
1104
  }
1384
1105
  break;
1385
- case 1 /* Tag */:
1106
+ case import_language_tools10.NodeType.Tag:
1386
1107
  if (node.attrs && node.nameText) {
1387
1108
  for (const attr of node.attrs) {
1388
- if (isDocumentLinkAttr(doc, node, attr)) {
1109
+ if (isDocumentLinkAttr(code, node, attr)) {
1389
1110
  const resolved = resolveUrl(
1390
1111
  read(attr.value.value).slice(1, -1),
1391
- doc.uri
1112
+ uri
1392
1113
  );
1393
1114
  if (resolved) {
1394
- links.push(
1395
- import_vscode_languageserver11.DocumentLink.create(
1396
- parsed.locationAt(attr.value.value),
1397
- resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)
1398
- )
1399
- );
1115
+ links.push({
1116
+ range: parsed.locationAt(attr.value.value),
1117
+ target: resolveUrl(read(attr.value.value).slice(1, -1), uri)
1118
+ });
1400
1119
  }
1401
1120
  }
1402
1121
  }
@@ -1409,50 +1128,44 @@ function extractDocumentLinks(doc, parsed, lookup) {
1409
1128
  break;
1410
1129
  }
1411
1130
  };
1412
- for (const item of program.static) {
1413
- if (item.type === 20 /* Statement */ && code[item.start] === "i") {
1131
+ for (const node of program.static) {
1132
+ if (node.type === import_language_tools10.NodeType.Import) {
1414
1133
  importTagReg2.lastIndex = 0;
1415
- const value = parsed.read(item);
1134
+ const value = parsed.read(node);
1416
1135
  const match = importTagReg2.exec(value);
1417
1136
  if (match) {
1418
1137
  const [{ length }, , tagName] = match;
1419
1138
  const tagDef = lookup.getTag(tagName);
1420
1139
  const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1421
1140
  if (fileForTag) {
1422
- links.push(
1423
- import_vscode_languageserver11.DocumentLink.create(
1424
- parsed.locationAt({
1425
- start: item.start + match.index,
1426
- end: item.start + match.index + length
1427
- }),
1428
- fileForTag
1429
- )
1430
- );
1141
+ links.push({
1142
+ range: parsed.locationAt({
1143
+ start: node.start + match.index,
1144
+ end: node.start + match.index + length
1145
+ }),
1146
+ target: fileForTag
1147
+ });
1431
1148
  }
1432
1149
  }
1433
1150
  }
1434
1151
  }
1435
- for (const item of program.body) {
1436
- visit(item);
1152
+ for (const node of program.body) {
1153
+ visit(node);
1437
1154
  }
1438
1155
  return links;
1439
1156
  }
1440
1157
 
1441
1158
  // src/service/marko/document-symbols.ts
1442
- var import_vscode_uri7 = require("vscode-uri");
1443
- var import_vscode_languageserver12 = require("vscode-languageserver");
1444
- var cache2 = /* @__PURE__ */ new WeakMap();
1445
- var findDocumentSymbols = async (doc) => {
1446
- const parsed = parse2(doc);
1447
- let result = cache2.get(parsed);
1448
- if (!result) {
1449
- result = extractDocumentSymbols(doc, parsed, getCompilerInfo(doc).lookup);
1450
- cache2.set(parsed, result);
1451
- }
1452
- return result;
1453
- };
1454
- function extractDocumentSymbols(doc, parsed, lookup) {
1455
- if (import_vscode_uri7.URI.parse(doc.uri).scheme === "untitled") {
1159
+ var import_vscode_languageserver8 = require("vscode-languageserver");
1160
+ var import_language_tools11 = require("@marko/language-tools");
1161
+ var findDocumentSymbols = async (doc) => processDoc(doc, extractDocumentSymbols);
1162
+ function extractDocumentSymbols({
1163
+ uri,
1164
+ scheme,
1165
+ parsed,
1166
+ project: { lookup }
1167
+ }) {
1168
+ if (scheme !== "file") {
1456
1169
  return [];
1457
1170
  }
1458
1171
  const symbols = [];
@@ -1460,16 +1173,16 @@ function extractDocumentSymbols(doc, parsed, lookup) {
1460
1173
  const visit = (node) => {
1461
1174
  var _a, _b;
1462
1175
  switch (node.type) {
1463
- case 1 /* Tag */:
1464
- case 14 /* AttrTag */:
1465
- symbols.push(
1466
- import_vscode_languageserver12.SymbolInformation.create(
1467
- (node.type === 14 /* AttrTag */ ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>",
1468
- node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html) && import_vscode_languageserver12.SymbolKind.Property || import_vscode_languageserver12.SymbolKind.Class,
1469
- parsed.locationAt(node),
1470
- doc.uri
1471
- )
1472
- );
1176
+ case import_language_tools11.NodeType.Tag:
1177
+ case import_language_tools11.NodeType.AttrTag:
1178
+ symbols.push({
1179
+ name: (node.type === import_language_tools11.NodeType.AttrTag ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>",
1180
+ kind: node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html) && import_vscode_languageserver8.SymbolKind.Property || import_vscode_languageserver8.SymbolKind.Class,
1181
+ location: {
1182
+ uri,
1183
+ range: parsed.locationAt(node)
1184
+ }
1185
+ });
1473
1186
  if (node.body) {
1474
1187
  for (const child of node.body) {
1475
1188
  visit(child);
@@ -1485,32 +1198,35 @@ function extractDocumentSymbols(doc, parsed, lookup) {
1485
1198
  }
1486
1199
 
1487
1200
  // src/service/marko/format.ts
1488
- var import_vscode_languageserver13 = require("vscode-languageserver");
1489
- var import_vscode_uri8 = require("vscode-uri");
1201
+ var import_vscode_languageserver9 = require("vscode-languageserver");
1490
1202
  var prettier = __toESM(require("prettier"));
1491
1203
  var markoPrettier = __toESM(require("prettier-plugin-marko"));
1492
1204
  var format2 = async (doc, params, cancel) => {
1493
1205
  try {
1494
- const { fsPath, scheme } = import_vscode_uri8.URI.parse(doc.uri);
1206
+ const filepath = getFSPath(doc);
1495
1207
  const text = doc.getText();
1496
1208
  const options = {
1497
1209
  parser: "marko",
1498
- filepath: fsPath,
1210
+ filepath,
1499
1211
  plugins: [markoPrettier],
1500
1212
  tabWidth: params.options.tabSize,
1501
1213
  useTabs: params.options.insertSpaces === false,
1502
- ...scheme === "file" ? await prettier.resolveConfig(fsPath, {
1214
+ ...filepath ? await prettier.resolveConfig(filepath, {
1503
1215
  editorconfig: true
1504
1216
  }).catch(() => null) : null
1505
1217
  };
1506
1218
  if (cancel.isCancellationRequested)
1507
1219
  return;
1508
- return [
1509
- import_vscode_languageserver13.TextEdit.replace(
1510
- import_vscode_languageserver13.Range.create(doc.positionAt(0), doc.positionAt(text.length)),
1220
+ const ret = [
1221
+ import_vscode_languageserver9.TextEdit.replace(
1222
+ {
1223
+ start: START_POSITION,
1224
+ end: doc.positionAt(text.length)
1225
+ },
1511
1226
  prettier.format(text, options)
1512
1227
  )
1513
1228
  ];
1229
+ return ret;
1514
1230
  } catch (e) {
1515
1231
  displayError(e);
1516
1232
  }
@@ -1527,181 +1243,932 @@ var marko_default = {
1527
1243
  format: format2
1528
1244
  };
1529
1245
 
1530
- // src/service/stylesheet/index.ts
1531
- var import_vscode_languageserver14 = require("vscode-languageserver");
1532
- var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
1533
- var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
1246
+ // src/service/script/index.ts
1247
+ var import_path9 = __toESM(require("path"));
1248
+ var import_relative_import_path = require("relative-import-path");
1249
+ var import_tsserverlibrary = __toESM(require("typescript/lib/tsserverlibrary"));
1250
+ var import_vscode_languageserver10 = require("vscode-languageserver");
1251
+ var import_vscode_uri6 = require("vscode-uri");
1252
+ var prettier2 = __toESM(require("prettier"));
1253
+ var import_language_tools14 = require("@marko/language-tools");
1534
1254
 
1535
- // src/utils/extractor.ts
1536
- function createExtractor(code) {
1537
- let generated = "";
1538
- const generatedMap = [];
1539
- return {
1540
- write(strs, ...exprs) {
1541
- const len = exprs.length;
1542
- for (let i = 0; i < len; i++) {
1543
- const expr = exprs[i];
1544
- generated += strs[i];
1545
- if (typeof expr === "string") {
1546
- generated += expr;
1547
- } else {
1548
- generatedMap.push(generated.length, expr.start, expr.end);
1549
- generated += code.slice(expr.start, expr.end);
1550
- }
1255
+ // src/ts-plugin/host.ts
1256
+ var import_path8 = __toESM(require("path"));
1257
+ var import_language_tools13 = require("@marko/language-tools");
1258
+
1259
+ // src/utils/get-runtime-types.ts
1260
+ var import_path6 = __toESM(require("path"));
1261
+ var internalTypesFile = import_path6.default.join(__dirname, "marko.internal.d.ts");
1262
+ var defaultMarkoTypesFile = import_path6.default.join(__dirname, "marko.runtime.d.ts");
1263
+ function getProjectTypeLibs(project, ts2, host) {
1264
+ let cached = project.cache.get(getProjectTypeLibs);
1265
+ if (cached === void 0) {
1266
+ const { resolvedTypeReferenceDirective } = ts2.resolveTypeReferenceDirective(
1267
+ project.translator.runtimeTypes || "marko",
1268
+ import_path6.default.join(project.rootDir, "_.d.ts"),
1269
+ host.getCompilationSettings(),
1270
+ host
1271
+ );
1272
+ const markoTypesFile = (resolvedTypeReferenceDirective == null ? void 0 : resolvedTypeReferenceDirective.resolvedFileName) || defaultMarkoTypesFile;
1273
+ cached = {
1274
+ internalTypesFile,
1275
+ markoTypesFile,
1276
+ markoTypesCode: host.readFile(markoTypesFile, "utf-8") || ""
1277
+ };
1278
+ project.cache.set(getProjectTypeLibs, cached);
1279
+ }
1280
+ return cached;
1281
+ }
1282
+
1283
+ // src/utils/get-script-lang.ts
1284
+ var import_language_tools12 = require("@marko/language-tools");
1285
+ function getScriptLang(filename, ts2, host, projectScriptLang) {
1286
+ const configPath = ts2.findConfigFile(
1287
+ filename,
1288
+ host.fileExists.bind(host),
1289
+ "marko.json"
1290
+ );
1291
+ if (configPath) {
1292
+ try {
1293
+ const markoConfig = JSON.parse(
1294
+ host.readFile(configPath, "utf-8") || "{}"
1295
+ );
1296
+ const scriptLang = markoConfig["script-lang"] || markoConfig.scriptLang;
1297
+ if (scriptLang !== void 0) {
1298
+ return scriptLang === import_language_tools12.ScriptLang.ts ? import_language_tools12.ScriptLang.ts : import_language_tools12.ScriptLang.js;
1551
1299
  }
1552
- generated += strs[len];
1553
- },
1554
- end() {
1555
- const sourceMap = generatedMap.slice();
1556
- (function sort(left, right) {
1557
- if (left < right) {
1558
- let next = left;
1559
- for (let i = left; i <= right; i += 3) {
1560
- if (sourceMap[i] <= sourceMap[right]) {
1561
- [sourceMap[next - 1], sourceMap[i - 1]] = [
1562
- sourceMap[i - 1],
1563
- sourceMap[next - 1]
1564
- ];
1565
- [sourceMap[next], sourceMap[i]] = [sourceMap[i], sourceMap[next]];
1566
- [sourceMap[next + 1], sourceMap[i + 1]] = [
1567
- sourceMap[i + 1],
1568
- sourceMap[next + 1]
1569
- ];
1570
- next += 3;
1300
+ } catch {
1301
+ }
1302
+ }
1303
+ return /[/\\]node_modules[/\\]/.test(filename) ? import_language_tools12.ScriptLang.js : projectScriptLang;
1304
+ }
1305
+
1306
+ // src/utils/get-component-filename.ts
1307
+ var import_path7 = __toESM(require("path"));
1308
+ function getComponentFilename(from, host) {
1309
+ const dir = import_path7.default.dirname(from);
1310
+ const nameNoExt = import_path7.default.basename(from, ".marko");
1311
+ const isEntry = nameNoExt === "index";
1312
+ const componentFull = import_path7.default.join(dir, `${nameNoExt}.component.`);
1313
+ const componentBrowserFull = import_path7.default.join(
1314
+ dir,
1315
+ `${nameNoExt}.component-browser.`
1316
+ );
1317
+ const componentPartial = isEntry ? import_path7.default.join(dir, "component.") : void 0;
1318
+ const componentBrowserPartial = isEntry ? import_path7.default.join(dir, "component-browser.") : void 0;
1319
+ for (const entry of host.readDirectory(dir)) {
1320
+ if (entry !== from && (isEntry && entry.startsWith(componentBrowserPartial) || entry.startsWith(componentPartial)) || entry.startsWith(componentBrowserFull) || entry.startsWith(componentFull)) {
1321
+ return entry;
1322
+ }
1323
+ }
1324
+ }
1325
+
1326
+ // src/ts-plugin/host.ts
1327
+ var markoExt = ".marko";
1328
+ var markoExtReg = /\.marko$/;
1329
+ var modulePartsReg = /^((?:@(?:[^/]+)\/)?(?:[^/]+))(.*)$/;
1330
+ var fsPathReg = /^(?:[./\\]|[A-Z]:)/i;
1331
+ function patch(ts2, scriptLang, cache, host) {
1332
+ var _a, _b, _c;
1333
+ const projectTypeLibs = getProjectTypeLibs(
1334
+ getMarkoProject(host.getCurrentDirectory()),
1335
+ ts2,
1336
+ host
1337
+ );
1338
+ const isMarkoTSFile = (fileName) => getScriptLang(fileName, ts2, host, scriptLang) === import_language_tools13.ScriptLang.ts;
1339
+ const getScriptFileNames = host.getScriptFileNames.bind(host);
1340
+ host.getScriptFileNames = () => [
1341
+ .../* @__PURE__ */ new Set([
1342
+ ...getScriptFileNames(),
1343
+ projectTypeLibs.internalTypesFile,
1344
+ projectTypeLibs.markoTypesFile
1345
+ ])
1346
+ ];
1347
+ const getScriptKind = (_a = host.getScriptKind) == null ? void 0 : _a.bind(host);
1348
+ if (getScriptKind) {
1349
+ host.getScriptKind = (fileName) => {
1350
+ return markoExtReg.test(fileName) ? isMarkoTSFile(fileName) ? ts2.ScriptKind.TS : ts2.ScriptKind.JS : getScriptKind(fileName);
1351
+ };
1352
+ }
1353
+ const getScriptSnapshot = host.getScriptSnapshot.bind(host);
1354
+ host.getScriptSnapshot = (filename) => {
1355
+ if (markoExtReg.test(filename)) {
1356
+ let cached = cache.get(filename);
1357
+ if (!cached) {
1358
+ const code = host.readFile(filename, "utf-8") || "";
1359
+ const markoProject = getMarkoProject(import_path8.default.dirname(filename));
1360
+ cached = (0, import_language_tools13.extractScript)({
1361
+ ts: ts2,
1362
+ parsed: (0, import_language_tools13.parse)(code, filename),
1363
+ lookup: markoProject.lookup,
1364
+ scriptLang: getScriptLang(filename, ts2, host, scriptLang),
1365
+ runtimeTypesCode: projectTypeLibs.markoTypesCode,
1366
+ componentFilename: getComponentFilename(filename, host)
1367
+ });
1368
+ cached.snapshot = ts2.ScriptSnapshot.fromString(cached.toString());
1369
+ cache.set(filename, cached);
1370
+ }
1371
+ return cached.snapshot;
1372
+ }
1373
+ return getScriptSnapshot(filename);
1374
+ };
1375
+ const readDirectory2 = (_b = host.readDirectory) == null ? void 0 : _b.bind(host);
1376
+ if (readDirectory2) {
1377
+ host.readDirectory = (path10, extensions, exclude, include, depth) => {
1378
+ return readDirectory2(
1379
+ path10,
1380
+ extensions == null ? void 0 : extensions.concat(markoExt),
1381
+ exclude,
1382
+ include,
1383
+ depth
1384
+ );
1385
+ };
1386
+ }
1387
+ const resolveModuleNames = (_c = host.resolveModuleNames) == null ? void 0 : _c.bind(host);
1388
+ if (resolveModuleNames) {
1389
+ host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, sourceFile) => {
1390
+ const resolvedModules = resolveModuleNames(
1391
+ moduleNames,
1392
+ containingFile,
1393
+ reusedNames,
1394
+ redirectedReference,
1395
+ options,
1396
+ sourceFile
1397
+ );
1398
+ for (let i = resolvedModules.length; i--; ) {
1399
+ const moduleName = moduleNames[i];
1400
+ if (!resolvedModules[i] && markoExtReg.test(moduleName)) {
1401
+ if (fsPathReg.test(moduleName)) {
1402
+ const resolvedFileName = import_path8.default.resolve(
1403
+ containingFile,
1404
+ "..",
1405
+ moduleName
1406
+ );
1407
+ if (host.fileExists(resolvedFileName)) {
1408
+ resolvedModules[i] = {
1409
+ resolvedFileName,
1410
+ extension: isMarkoTSFile(resolvedFileName) ? ts2.Extension.Ts : ts2.Extension.Js,
1411
+ isExternalLibraryImport: false
1412
+ };
1413
+ }
1414
+ } else if (moduleName[0] !== "*") {
1415
+ const [, nodeModuleName, relativeModulePath] = modulePartsReg.exec(moduleName);
1416
+ const { resolvedModule } = ts2.resolveModuleName(
1417
+ `${nodeModuleName}/package.json`,
1418
+ containingFile,
1419
+ options,
1420
+ host
1421
+ );
1422
+ if (resolvedModule) {
1423
+ const resolvedFileName = import_path8.default.join(
1424
+ resolvedModule.resolvedFileName,
1425
+ "..",
1426
+ relativeModulePath
1427
+ );
1428
+ if (host.fileExists(resolvedFileName)) {
1429
+ const isTS = isMarkoTSFile(resolvedFileName);
1430
+ resolvedModules[i] = {
1431
+ resolvedFileName,
1432
+ extension: isTS ? ts2.Extension.Ts : ts2.Extension.Js,
1433
+ isExternalLibraryImport: isTS
1434
+ };
1435
+ }
1571
1436
  }
1572
1437
  }
1573
- next -= 3;
1574
- sort(left, next - 3);
1575
- sort(next + 3, right);
1576
1438
  }
1577
- })(1, sourceMap.length - 2);
1439
+ }
1440
+ return resolvedModules;
1441
+ };
1442
+ }
1443
+ return host;
1444
+ }
1445
+
1446
+ // src/service/script/index.ts
1447
+ var IGNORE_DIAG_REG = /^(?:Expression|Identifier|['"][^\w]['"]) expected.$/;
1448
+ var extractCache = /* @__PURE__ */ new Map();
1449
+ var snapshotCache = /* @__PURE__ */ new Map();
1450
+ var markoFileReg = /\.marko$/;
1451
+ var tsTriggerChars = /* @__PURE__ */ new Set([".", '"', "'", "`", "/", "@", "<", "#", " "]);
1452
+ var optionalModifierReg = /\boptional\b/;
1453
+ var deprecatedModifierReg = /\bdeprecated\b/;
1454
+ var colorModifierReg = /\bcolor\b/;
1455
+ var localInternalsPrefix = "__marko_internal_";
1456
+ var ScriptService = {
1457
+ commands: {
1458
+ "$/showScriptOutput": async (uri) => {
1459
+ const doc = get(uri);
1460
+ if ((doc == null ? void 0 : doc.languageId) !== "marko")
1461
+ return;
1462
+ const filename = getFSPath(doc);
1463
+ if (!filename)
1464
+ return;
1465
+ const project = getTSProject(filename);
1466
+ const extracted = processScript(doc, project);
1467
+ const lang = getScriptLang(
1468
+ filename,
1469
+ import_tsserverlibrary.default,
1470
+ project.host,
1471
+ project.markoScriptLang
1472
+ );
1473
+ const generated = extracted.toString();
1474
+ const content = (() => {
1475
+ try {
1476
+ return prettier2.format(generated, {
1477
+ parser: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "babel"
1478
+ });
1479
+ } catch {
1480
+ return generated;
1481
+ }
1482
+ })();
1578
1483
  return {
1579
- generated,
1580
- sourceOffsetAt(generatedOffset) {
1581
- let max = generatedMap.length / 3;
1582
- let min = 0;
1583
- while (min < max) {
1584
- const mid = 1 + min + max >>> 1;
1585
- if (generatedMap[mid * 3] <= generatedOffset) {
1586
- min = mid;
1587
- } else {
1588
- max = mid - 1;
1589
- }
1484
+ language: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "javascript",
1485
+ content
1486
+ };
1487
+ }
1488
+ },
1489
+ async initialize() {
1490
+ onConfigChange(() => {
1491
+ snapshotCache.clear();
1492
+ });
1493
+ onFileChange((doc) => {
1494
+ if (doc) {
1495
+ const filename = getFSPath(doc);
1496
+ extractCache.delete(filename);
1497
+ snapshotCache.delete(filename);
1498
+ } else {
1499
+ extractCache.clear();
1500
+ snapshotCache.clear();
1501
+ }
1502
+ });
1503
+ },
1504
+ async doComplete(doc, params) {
1505
+ var _a;
1506
+ const fileName = getFSPath(doc);
1507
+ if (!fileName)
1508
+ return;
1509
+ const project = getTSProject(fileName);
1510
+ const extracted = processScript(doc, project);
1511
+ const sourceOffset = doc.offsetAt(params.position);
1512
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1513
+ if (generatedOffset === void 0)
1514
+ return;
1515
+ const completions = project.service.getCompletionsAtPosition(
1516
+ fileName,
1517
+ generatedOffset,
1518
+ {
1519
+ ...await getPreferences(project.markoScriptLang),
1520
+ ...params.context,
1521
+ triggerCharacter: getTSTriggerChar((_a = params.context) == null ? void 0 : _a.triggerCharacter)
1522
+ }
1523
+ );
1524
+ if (!(completions == null ? void 0 : completions.entries.length))
1525
+ return;
1526
+ const result = [];
1527
+ for (const completion of completions.entries) {
1528
+ let { name: label, insertText, sortText } = completion;
1529
+ if (label.startsWith(localInternalsPrefix))
1530
+ continue;
1531
+ const { replacementSpan } = completion;
1532
+ let textEdit;
1533
+ let detail;
1534
+ let kind;
1535
+ let tags;
1536
+ let labelDetails;
1537
+ let source = completion.source;
1538
+ if (source && completion.hasAction) {
1539
+ if (source[0] === ".") {
1540
+ source = import_path9.default.resolve(fileName, "..", source);
1541
+ }
1542
+ detail = (0, import_relative_import_path.relativeImportPath)(fileName, source);
1543
+ sortText = `\uFFFF${sortText}`;
1544
+ } else if (completion.sourceDisplay) {
1545
+ const description = import_tsserverlibrary.default.displayPartsToString(completion.sourceDisplay);
1546
+ if (description !== label) {
1547
+ labelDetails = { description };
1548
+ }
1549
+ }
1550
+ if (completion.kindModifiers) {
1551
+ if (optionalModifierReg.test(completion.kindModifiers)) {
1552
+ insertText = label;
1553
+ label += "?";
1554
+ }
1555
+ if (deprecatedModifierReg.test(completion.kindModifiers)) {
1556
+ tags = [import_vscode_languageserver10.CompletionItemTag.Deprecated];
1557
+ }
1558
+ if (colorModifierReg.test(completion.kindModifiers)) {
1559
+ kind = import_vscode_languageserver10.CompletionItemKind.Color;
1560
+ }
1561
+ }
1562
+ if (replacementSpan) {
1563
+ const sourceRange = sourceLocationAtTextSpan(
1564
+ extracted,
1565
+ replacementSpan
1566
+ );
1567
+ if (sourceRange) {
1568
+ textEdit = {
1569
+ range: sourceRange,
1570
+ newText: insertText || label
1571
+ };
1572
+ } else {
1573
+ continue;
1574
+ }
1575
+ }
1576
+ result.push({
1577
+ tags,
1578
+ label,
1579
+ detail,
1580
+ textEdit,
1581
+ sortText,
1582
+ insertText,
1583
+ labelDetails,
1584
+ filterText: insertText,
1585
+ preselect: completion.isRecommended || void 0,
1586
+ kind: kind || convertCompletionItemKind(completion.kind),
1587
+ insertTextFormat: completion.isSnippet ? import_vscode_languageserver10.InsertTextFormat.Snippet : void 0,
1588
+ data: completion.data && {
1589
+ originalData: completion.data,
1590
+ originalName: completion.name,
1591
+ originalSource: source,
1592
+ generatedOffset,
1593
+ fileName
1594
+ }
1595
+ });
1596
+ }
1597
+ return {
1598
+ isIncomplete: true,
1599
+ items: result
1600
+ };
1601
+ },
1602
+ async doCompletionResolve(item) {
1603
+ const { data } = item;
1604
+ if (!data)
1605
+ return;
1606
+ const { fileName } = data;
1607
+ if (!fileName)
1608
+ return;
1609
+ const doc = get(filenameToURI(fileName));
1610
+ if (!doc)
1611
+ return;
1612
+ const project = getTSProject(fileName);
1613
+ const detail = project.service.getCompletionEntryDetails(
1614
+ fileName,
1615
+ data.generatedOffset,
1616
+ data.originalName,
1617
+ {},
1618
+ data.originalSource,
1619
+ await getPreferences(project.markoScriptLang),
1620
+ data.originalData
1621
+ );
1622
+ if (!(detail == null ? void 0 : detail.codeActions))
1623
+ return;
1624
+ const extracted = processScript(doc, project);
1625
+ const textEdits = item.additionalTextEdits = item.additionalTextEdits || [];
1626
+ for (const action of detail.codeActions) {
1627
+ for (const change of action.changes) {
1628
+ if (change.fileName !== fileName)
1629
+ continue;
1630
+ for (const { span, newText } of change.textChanges) {
1631
+ const sourceRange = /^\s*(?:import|export) /.test(newText) ? (
1632
+ // Ensure import inserts are always in the program root.
1633
+ // TODO: this could probably be updated to more closely reflect
1634
+ // where typescript wants to put the import/export.
1635
+ START_LOCATION
1636
+ ) : sourceLocationAtTextSpan(extracted, span);
1637
+ if (sourceRange) {
1638
+ textEdits.push({
1639
+ newText,
1640
+ range: sourceRange
1641
+ });
1590
1642
  }
1591
- const key = min * 3;
1592
- const generatedStart = generatedMap[key];
1593
- const sourceStart = generatedMap[key + 1];
1594
- const sourceEnd = generatedMap[key + 2];
1595
- return sourceEnd - sourceStart < generatedOffset - generatedStart ? void 0 : sourceStart + (generatedOffset - generatedStart);
1596
- },
1597
- generatedOffsetAt(sourceOffset) {
1598
- let max = sourceMap.length / 3;
1599
- let min = 0;
1600
- while (min < max) {
1601
- const mid = 1 + min + max >>> 1;
1602
- if (sourceMap[mid * 3 + 1] <= sourceOffset) {
1603
- min = mid;
1604
- } else {
1605
- max = mid - 1;
1606
- }
1643
+ }
1644
+ }
1645
+ }
1646
+ return item;
1647
+ },
1648
+ findDefinition(doc, params) {
1649
+ const fileName = getFSPath(doc);
1650
+ if (!fileName)
1651
+ return;
1652
+ const project = getTSProject(fileName);
1653
+ const extracted = processScript(doc, project);
1654
+ const sourceOffset = doc.offsetAt(params.position);
1655
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1656
+ if (generatedOffset === void 0)
1657
+ return;
1658
+ const boundary = project.service.getDefinitionAndBoundSpan(
1659
+ fileName,
1660
+ generatedOffset
1661
+ );
1662
+ if (!(boundary == null ? void 0 : boundary.definitions))
1663
+ return;
1664
+ const originSelectionRange = sourceLocationAtTextSpan(
1665
+ extracted,
1666
+ boundary.textSpan
1667
+ );
1668
+ let result;
1669
+ for (const def of boundary.definitions) {
1670
+ const targetUri = filenameToURI(def.fileName);
1671
+ const defDoc = get(targetUri);
1672
+ if (!defDoc)
1673
+ continue;
1674
+ let link;
1675
+ if (markoFileReg.test(targetUri)) {
1676
+ const extracted2 = processScript(defDoc, project);
1677
+ const targetSelectionRange = sourceLocationAtTextSpan(extracted2, def.textSpan) || START_LOCATION;
1678
+ const targetRange = def.contextSpan && sourceLocationAtTextSpan(extracted2, def.contextSpan) || START_LOCATION;
1679
+ link = {
1680
+ targetUri,
1681
+ targetRange,
1682
+ targetSelectionRange,
1683
+ originSelectionRange
1684
+ };
1685
+ } else {
1686
+ link = {
1687
+ targetUri,
1688
+ targetRange: def.contextSpan ? docLocationAtTextSpan(defDoc, def.contextSpan) : START_LOCATION,
1689
+ targetSelectionRange: docLocationAtTextSpan(defDoc, def.textSpan),
1690
+ originSelectionRange
1691
+ };
1692
+ }
1693
+ if (link) {
1694
+ if (result) {
1695
+ if (Array.isArray(result)) {
1696
+ result.push(link);
1697
+ } else {
1698
+ result = [result, link];
1607
1699
  }
1608
- const key = min * 3;
1609
- const sourceStart = sourceMap[key + 1];
1610
- const sourceEnd = sourceMap[key + 2];
1611
- if (sourceOffset < sourceStart || sourceOffset > sourceEnd)
1612
- return void 0;
1613
- const generatedStart = sourceMap[key];
1614
- return generatedStart + (sourceOffset - sourceStart);
1700
+ } else {
1701
+ result = link;
1615
1702
  }
1616
- };
1703
+ }
1617
1704
  }
1618
- };
1705
+ return result;
1706
+ },
1707
+ doHover(doc, params) {
1708
+ const fileName = getFSPath(doc);
1709
+ if (!fileName)
1710
+ return;
1711
+ const project = getTSProject(fileName);
1712
+ const extracted = processScript(doc, project);
1713
+ const sourceOffset = doc.offsetAt(params.position);
1714
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1715
+ if (generatedOffset === void 0)
1716
+ return;
1717
+ const quickInfo = project.service.getQuickInfoAtPosition(
1718
+ fileName,
1719
+ generatedOffset
1720
+ );
1721
+ if (!quickInfo)
1722
+ return;
1723
+ const sourceRange = sourceLocationAtTextSpan(extracted, quickInfo.textSpan);
1724
+ if (!sourceRange)
1725
+ return;
1726
+ let contents = "";
1727
+ const displayParts = import_tsserverlibrary.default.displayPartsToString(quickInfo.displayParts);
1728
+ if (displayParts) {
1729
+ contents += `\`\`\`typescript
1730
+ ${displayParts}
1731
+ \`\`\``;
1732
+ }
1733
+ const documentation = printDocumentation(
1734
+ quickInfo.documentation,
1735
+ quickInfo.tags
1736
+ );
1737
+ if (documentation) {
1738
+ contents += `
1739
+ ---
1740
+ ${documentation}`;
1741
+ }
1742
+ return {
1743
+ range: sourceRange,
1744
+ contents
1745
+ };
1746
+ },
1747
+ doRename(doc, params) {
1748
+ const fileName = getFSPath(doc);
1749
+ if (!fileName)
1750
+ return;
1751
+ const project = getTSProject(fileName);
1752
+ const extracted = processScript(doc, project);
1753
+ const sourceOffset = doc.offsetAt(params.position);
1754
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1755
+ if (generatedOffset === void 0)
1756
+ return;
1757
+ const renameLocations = project.service.findRenameLocations(
1758
+ fileName,
1759
+ generatedOffset,
1760
+ false,
1761
+ false,
1762
+ false
1763
+ );
1764
+ if (!renameLocations)
1765
+ return;
1766
+ const changes = {};
1767
+ for (const rename of renameLocations) {
1768
+ const renameURI = filenameToURI(rename.fileName);
1769
+ const renameDoc = get(renameURI);
1770
+ let edit;
1771
+ if (!renameDoc)
1772
+ continue;
1773
+ if (markoFileReg.test(renameURI)) {
1774
+ const extracted2 = processScript(renameDoc, project);
1775
+ const sourceRange = sourceLocationAtTextSpan(
1776
+ extracted2,
1777
+ rename.textSpan
1778
+ );
1779
+ if (sourceRange) {
1780
+ edit = {
1781
+ newText: params.newName,
1782
+ range: sourceRange
1783
+ };
1784
+ }
1785
+ } else {
1786
+ edit = {
1787
+ newText: params.newName,
1788
+ range: docLocationAtTextSpan(renameDoc, rename.textSpan)
1789
+ };
1790
+ }
1791
+ if (edit) {
1792
+ if (changes[renameURI]) {
1793
+ changes[renameURI].push(edit);
1794
+ } else {
1795
+ changes[renameURI] = [edit];
1796
+ }
1797
+ }
1798
+ }
1799
+ return {
1800
+ changes
1801
+ };
1802
+ },
1803
+ doValidate(doc) {
1804
+ const fileName = getFSPath(doc);
1805
+ if (!fileName)
1806
+ return;
1807
+ const project = getTSProject(fileName);
1808
+ const extracted = processScript(doc, project);
1809
+ let results;
1810
+ for (const tsDiag of project.service.getSuggestionDiagnostics(fileName)) {
1811
+ addDiag(tsDiag);
1812
+ }
1813
+ for (const tsDiag of project.service.getSyntacticDiagnostics(fileName)) {
1814
+ addDiag(tsDiag);
1815
+ }
1816
+ for (const tsDiag of project.service.getSemanticDiagnostics(fileName)) {
1817
+ addDiag(tsDiag);
1818
+ }
1819
+ return results;
1820
+ function addDiag(tsDiag) {
1821
+ const diag = convertDiag(extracted, tsDiag);
1822
+ if (diag && !IGNORE_DIAG_REG.test(diag.message)) {
1823
+ if (results) {
1824
+ results.push(diag);
1825
+ } else {
1826
+ results = [diag];
1827
+ }
1828
+ }
1829
+ }
1830
+ }
1831
+ };
1832
+ function processScript(doc, tsProject) {
1833
+ return processDoc(doc, ({ parsed, filename, project: markoProject }) => {
1834
+ var _a;
1835
+ const { lookup } = markoProject;
1836
+ const { host, markoScriptLang } = tsProject;
1837
+ return (0, import_language_tools14.extractScript)({
1838
+ ts: import_tsserverlibrary.default,
1839
+ parsed,
1840
+ lookup,
1841
+ scriptLang: getScriptLang(filename, import_tsserverlibrary.default, host, markoScriptLang),
1842
+ runtimeTypesCode: (_a = getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode,
1843
+ componentFilename: getComponentFilename(filename, host)
1844
+ });
1845
+ });
1619
1846
  }
1620
-
1621
- // src/service/stylesheet/extract.ts
1622
- function extractStyleSheets(code, program, lookup) {
1623
- let placeholderId = 0;
1624
- const extractorsByExt = {};
1625
- const read = (range) => code.slice(range.start, range.end);
1626
- const getExtractor = (ext) => extractorsByExt[ext] || (extractorsByExt[ext] = createExtractor(code));
1627
- const getFileExtFromTag = (tag) => {
1628
- const prefixEnd = tag.shorthandClassNames ? tag.shorthandClassNames.at(-1).end : tag.name.end;
1629
- return tag.shorthandClassNames ? read({
1630
- start: tag.shorthandClassNames[0].start,
1631
- end: prefixEnd
1632
- }).replace(/^.*\./, "") : "css";
1847
+ function sourceLocationAtTextSpan(extracted, { start, length }) {
1848
+ if (start === 0 && length === 0)
1849
+ return START_LOCATION;
1850
+ return extracted.sourceLocationAt(start, start + length);
1851
+ }
1852
+ function docLocationAtTextSpan(doc, { start, length }) {
1853
+ return {
1854
+ start: doc.positionAt(start),
1855
+ end: doc.positionAt(start + length)
1633
1856
  };
1634
- const visit = (node) => {
1635
- var _a, _b;
1636
- switch (node.type) {
1637
- case 14 /* AttrTag */:
1638
- if (node.body) {
1639
- for (const child of node.body) {
1640
- visit(child);
1641
- }
1642
- }
1643
- break;
1644
- case 1 /* Tag */:
1645
- if (node.nameText === "style" && node.concise && node.attrs) {
1646
- const block = node.attrs.at(-1);
1647
- if (block.type === 8 /* AttrNamed */ && code[block.start] === "{") {
1648
- getExtractor(getFileExtFromTag(node)).write`${{
1649
- start: block.start + 1,
1650
- end: block.end - 1
1651
- }}`;
1652
- break;
1653
- }
1857
+ }
1858
+ function getTSProject(docFsPath) {
1859
+ var _a;
1860
+ let configPath;
1861
+ let markoScriptLang = import_language_tools14.ScriptLang.js;
1862
+ if (docFsPath) {
1863
+ configPath = import_tsserverlibrary.default.findConfigFile(
1864
+ docFsPath,
1865
+ import_tsserverlibrary.default.sys.fileExists,
1866
+ "tsconfig.json"
1867
+ );
1868
+ if (configPath) {
1869
+ markoScriptLang = import_language_tools14.ScriptLang.ts;
1870
+ } else {
1871
+ configPath = import_tsserverlibrary.default.findConfigFile(
1872
+ docFsPath,
1873
+ import_tsserverlibrary.default.sys.fileExists,
1874
+ "jsconfig.json"
1875
+ );
1876
+ }
1877
+ }
1878
+ const rootDir = configPath && import_path9.default.dirname(configPath) || process.cwd();
1879
+ const markoProject = getMarkoProject(configPath && rootDir);
1880
+ let projectCache = markoProject.cache.get(getTSProject);
1881
+ let cached;
1882
+ if (projectCache) {
1883
+ cached = projectCache.get(rootDir);
1884
+ if (cached)
1885
+ return cached;
1886
+ } else {
1887
+ projectCache = /* @__PURE__ */ new Map();
1888
+ markoProject.cache.set(getTSProject, projectCache);
1889
+ }
1890
+ const { fileNames, options, projectReferences } = import_tsserverlibrary.default.parseJsonConfigFileContent(
1891
+ configPath && import_tsserverlibrary.default.readConfigFile(configPath, import_tsserverlibrary.default.sys.readFile).config || {
1892
+ compilerOptions: { lib: ["dom", "node", "esnext"] }
1893
+ },
1894
+ import_tsserverlibrary.default.sys,
1895
+ rootDir,
1896
+ void 0,
1897
+ configPath,
1898
+ void 0,
1899
+ [
1900
+ {
1901
+ extension: ".marko",
1902
+ isMixedContent: false,
1903
+ scriptKind: import_tsserverlibrary.default.ScriptKind.Deferred
1904
+ }
1905
+ ]
1906
+ );
1907
+ const potentialGlobalFiles = new Set(
1908
+ fileNames.filter((file) => /\.[cm]?ts$/.test(file))
1909
+ );
1910
+ options.rootDir ??= rootDir;
1911
+ options.module = import_tsserverlibrary.default.ModuleKind.ESNext;
1912
+ options.moduleResolution = import_tsserverlibrary.default.ModuleResolutionKind.NodeJs;
1913
+ options.noEmit = options.allowJs = options.declaration = options.skipLibCheck = options.isolatedModules = options.resolveJsonModule = options.skipDefaultLibCheck = options.allowNonTsExtensions = true;
1914
+ const tsPkgFile = configPath && ((_a = import_tsserverlibrary.default.resolveModuleName("typescript/package.json", configPath, options, import_tsserverlibrary.default.sys).resolvedModule) == null ? void 0 : _a.resolvedFileName);
1915
+ const defaultLibFile = import_path9.default.join(
1916
+ tsPkgFile ? import_path9.default.join(tsPkgFile, "../lib") : __dirname,
1917
+ import_tsserverlibrary.default.getDefaultLibFileName(options)
1918
+ );
1919
+ const host = patch(
1920
+ import_tsserverlibrary.default,
1921
+ markoScriptLang,
1922
+ extractCache,
1923
+ {
1924
+ getNewLine() {
1925
+ return import_tsserverlibrary.default.sys.newLine;
1926
+ },
1927
+ useCaseSensitiveFileNames() {
1928
+ return import_tsserverlibrary.default.sys.useCaseSensitiveFileNames;
1929
+ },
1930
+ getCompilationSettings() {
1931
+ return options;
1932
+ },
1933
+ getCurrentDirectory() {
1934
+ return options.rootDir;
1935
+ },
1936
+ getProjectVersion() {
1937
+ return projectVersion.toString(32);
1938
+ },
1939
+ getDefaultLibFileName() {
1940
+ return defaultLibFile;
1941
+ },
1942
+ getProjectReferences() {
1943
+ return projectReferences;
1944
+ },
1945
+ resolveModuleNames(moduleNames, containingFile) {
1946
+ return moduleNames.map((moduleName) => {
1947
+ return import_tsserverlibrary.default.resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
1948
+ });
1949
+ },
1950
+ readDirectory: import_tsserverlibrary.default.sys.readDirectory,
1951
+ readFile: (filename) => {
1952
+ var _a2;
1953
+ return (_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.getText();
1954
+ },
1955
+ fileExists: (filename) => exists(filenameToURI(filename)),
1956
+ getScriptFileNames() {
1957
+ const result = new Set(potentialGlobalFiles);
1958
+ for (const doc of getAllOpen()) {
1959
+ const { scheme, fsPath } = import_vscode_uri6.URI.parse(doc.uri);
1960
+ if (scheme === "file")
1961
+ result.add(fsPath);
1654
1962
  }
1655
- if (node.body) {
1656
- if (node.nameText === "style") {
1657
- const ext = getFileExtFromTag(node);
1658
- for (const child of node.body) {
1659
- switch (child.type) {
1660
- case 15 /* Text */:
1661
- getExtractor(ext).write`${child}`;
1662
- break;
1663
- case 21 /* Placeholder */:
1664
- getExtractor(ext).write`${`var(--_${placeholderId++})`}`;
1665
- break;
1666
- }
1667
- }
1668
- } else {
1669
- for (const child of node.body) {
1670
- visit(child);
1671
- }
1672
- }
1963
+ return [...result];
1964
+ },
1965
+ getScriptVersion(filename) {
1966
+ var _a2;
1967
+ return `${((_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.version) ?? -1}`;
1968
+ },
1969
+ getScriptKind(filename) {
1970
+ switch (import_path9.default.extname(filename)) {
1971
+ case import_tsserverlibrary.default.Extension.Js:
1972
+ return import_tsserverlibrary.default.ScriptKind.JS;
1973
+ case import_tsserverlibrary.default.Extension.Jsx:
1974
+ return import_tsserverlibrary.default.ScriptKind.JSX;
1975
+ case import_tsserverlibrary.default.Extension.Ts:
1976
+ return import_tsserverlibrary.default.ScriptKind.TS;
1977
+ case import_tsserverlibrary.default.Extension.Tsx:
1978
+ return import_tsserverlibrary.default.ScriptKind.TSX;
1979
+ case import_tsserverlibrary.default.Extension.Json:
1980
+ return import_tsserverlibrary.default.ScriptKind.JSON;
1981
+ default:
1982
+ return import_tsserverlibrary.default.ScriptKind.Unknown;
1673
1983
  }
1674
- if (node.attrs) {
1675
- for (const attr of node.attrs) {
1676
- if (attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
1677
- const name = read(attr.name);
1678
- if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1679
- getExtractor("css").write`:root{${{
1680
- start: attr.value.value.start + 1,
1681
- end: attr.value.value.end - 1
1682
- }}}`;
1683
- }
1684
- }
1685
- }
1984
+ },
1985
+ getScriptSnapshot(filename) {
1986
+ let snapshot = snapshotCache.get(filename);
1987
+ if (!snapshot) {
1988
+ const doc = get(filenameToURI(filename));
1989
+ if (!doc)
1990
+ return;
1991
+ snapshot = import_tsserverlibrary.default.ScriptSnapshot.fromString(doc.getText());
1992
+ snapshotCache.set(filename, snapshot);
1686
1993
  }
1687
- break;
1994
+ return snapshot;
1995
+ }
1688
1996
  }
1997
+ );
1998
+ const tsProject = {
1999
+ host,
2000
+ rootDir: options.rootDir,
2001
+ service: import_tsserverlibrary.default.createLanguageService(host),
2002
+ markoProject,
2003
+ markoScriptLang,
2004
+ markoProjectTypeLibs: getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)
1689
2005
  };
1690
- for (const node of program.body)
1691
- visit(node);
1692
- const resultsByExt = {};
1693
- for (const ext in extractorsByExt) {
1694
- resultsByExt[ext] = extractorsByExt[ext].end();
2006
+ projectCache.set(rootDir, tsProject);
2007
+ return tsProject;
2008
+ }
2009
+ function filenameToURI(filename) {
2010
+ return import_vscode_uri6.URI.file(filename).toString();
2011
+ }
2012
+ async function getPreferences(scriptLang) {
2013
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2014
+ const configName = scriptLang === import_language_tools14.ScriptLang.js ? "javascript" : "typescript";
2015
+ const [preferencesConfig, suggestConfig, inlayHintsConfig] = await Promise.all([
2016
+ getConfig(`${configName}.preferences`),
2017
+ getConfig(`${configName}.suggest`),
2018
+ getConfig(`${configName}.inlayHints`)
2019
+ ]);
2020
+ return {
2021
+ disableSuggestions: suggestConfig.enabled === false,
2022
+ quotePreference: preferencesConfig.quoteStyle || "auto",
2023
+ includeCompletionsForModuleExports: suggestConfig.autoImports ?? true,
2024
+ includeCompletionsForImportStatements: suggestConfig.includeCompletionsForImportStatements ?? true,
2025
+ includeCompletionsWithSnippetText: suggestConfig.includeCompletionsWithSnippetText ?? true,
2026
+ includeAutomaticOptionalChainCompletions: suggestConfig.includeAutomaticOptionalChainCompletions ?? true,
2027
+ includeCompletionsWithInsertText: true,
2028
+ includeCompletionsWithClassMemberSnippets: ((_a = suggestConfig.classMemberSnippets) == null ? void 0 : _a.enabled) ?? true,
2029
+ includeCompletionsWithObjectLiteralMethodSnippets: ((_b = suggestConfig.objectLiteralMethodSnippets) == null ? void 0 : _b.enabled) ?? true,
2030
+ useLabelDetailsInCompletionEntries: true,
2031
+ allowIncompleteCompletions: true,
2032
+ importModuleSpecifierPreference: preferencesConfig.importModuleSpecifierPreference,
2033
+ importModuleSpecifierEnding: preferencesConfig.importModuleSpecifierEnding || "auto",
2034
+ allowTextChangesInNewFiles: true,
2035
+ providePrefixAndSuffixTextForRename: true,
2036
+ includePackageJsonAutoImports: preferencesConfig.includePackageJsonAutoImports ?? true,
2037
+ provideRefactorNotApplicableReason: true,
2038
+ jsxAttributeCompletionStyle: preferencesConfig.jsxAttributeCompletionStyle ?? "auto",
2039
+ includeInlayParameterNameHints: ((_c = inlayHintsConfig.parameterNames) == null ? void 0 : _c.enabled) ?? "none",
2040
+ includeInlayParameterNameHintsWhenArgumentMatchesName: !((_d = inlayHintsConfig.parameterNames) == null ? void 0 : _d.suppressWhenArgumentMatchesName),
2041
+ includeInlayFunctionParameterTypeHints: ((_e = inlayHintsConfig.parameterTypes) == null ? void 0 : _e.enabled) ?? true,
2042
+ includeInlayVariableTypeHints: ((_f = inlayHintsConfig.variableTypes) == null ? void 0 : _f.enabled) ?? true,
2043
+ includeInlayPropertyDeclarationTypeHints: ((_g = inlayHintsConfig.propertyDeclarationTypes) == null ? void 0 : _g.enabled) ?? true,
2044
+ includeInlayFunctionLikeReturnTypeHints: ((_h = inlayHintsConfig.functionLikeReturnTypes) == null ? void 0 : _h.enabled) ?? true,
2045
+ includeInlayEnumMemberValueHints: ((_i = inlayHintsConfig.enumMemberValues) == null ? void 0 : _i.enabled) ?? true
2046
+ };
2047
+ }
2048
+ function printDocumentation(docs2, tags) {
2049
+ let result = "";
2050
+ if (docs2) {
2051
+ result += import_tsserverlibrary.default.displayPartsToString(docs2);
2052
+ }
2053
+ if (tags) {
2054
+ for (const tag of tags) {
2055
+ const text = import_tsserverlibrary.default.displayPartsToString(tag.text);
2056
+ result += `*@${tag.name}*${text ? /\n/.test(text) ? `
2057
+ ${text}` : `- ${text}` : ""}`;
2058
+ }
2059
+ }
2060
+ return result;
2061
+ }
2062
+ function convertDiag(extracted, tsDiag) {
2063
+ const sourceRange = tsDiag.start === void 0 ? START_LOCATION : sourceLocationAtTextSpan(extracted, tsDiag);
2064
+ if (sourceRange) {
2065
+ return {
2066
+ range: sourceRange,
2067
+ source: "script",
2068
+ code: tsDiag.code,
2069
+ tags: convertDiagTags(tsDiag),
2070
+ severity: convertDiagSeverity(tsDiag),
2071
+ message: import_tsserverlibrary.default.flattenDiagnosticMessageText(tsDiag.messageText, "\n")
2072
+ };
2073
+ }
2074
+ }
2075
+ function convertDiagSeverity(tsDiag) {
2076
+ switch (tsDiag.category) {
2077
+ case import_tsserverlibrary.default.DiagnosticCategory.Error:
2078
+ return import_vscode_languageserver10.DiagnosticSeverity.Error;
2079
+ case import_tsserverlibrary.default.DiagnosticCategory.Warning:
2080
+ return import_vscode_languageserver10.DiagnosticSeverity.Warning;
2081
+ case import_tsserverlibrary.default.DiagnosticCategory.Suggestion:
2082
+ return import_vscode_languageserver10.DiagnosticSeverity.Hint;
2083
+ default:
2084
+ return import_vscode_languageserver10.DiagnosticSeverity.Information;
2085
+ }
2086
+ }
2087
+ function convertDiagTags(tsDiag) {
2088
+ let tags;
2089
+ if (tsDiag.reportsDeprecated) {
2090
+ tags = [import_vscode_languageserver10.DiagnosticTag.Deprecated];
2091
+ }
2092
+ if (tsDiag.reportsUnnecessary) {
2093
+ if (tags)
2094
+ tags.push(import_vscode_languageserver10.DiagnosticTag.Unnecessary);
2095
+ else
2096
+ tags = [import_vscode_languageserver10.DiagnosticTag.Unnecessary];
2097
+ }
2098
+ return tags;
2099
+ }
2100
+ function convertCompletionItemKind(kind) {
2101
+ switch (kind) {
2102
+ case import_tsserverlibrary.default.ScriptElementKind.warning:
2103
+ case import_tsserverlibrary.default.ScriptElementKind.linkText:
2104
+ return import_vscode_languageserver10.CompletionItemKind.Text;
2105
+ case import_tsserverlibrary.default.ScriptElementKind.keyword:
2106
+ case import_tsserverlibrary.default.ScriptElementKind.primitiveType:
2107
+ return import_vscode_languageserver10.CompletionItemKind.Keyword;
2108
+ case import_tsserverlibrary.default.ScriptElementKind.scriptElement:
2109
+ return import_vscode_languageserver10.CompletionItemKind.File;
2110
+ case import_tsserverlibrary.default.ScriptElementKind.directory:
2111
+ return import_vscode_languageserver10.CompletionItemKind.Folder;
2112
+ case import_tsserverlibrary.default.ScriptElementKind.label:
2113
+ case import_tsserverlibrary.default.ScriptElementKind.string:
2114
+ return import_vscode_languageserver10.CompletionItemKind.Constant;
2115
+ case import_tsserverlibrary.default.ScriptElementKind.moduleElement:
2116
+ case import_tsserverlibrary.default.ScriptElementKind.externalModuleName:
2117
+ return import_vscode_languageserver10.CompletionItemKind.Module;
2118
+ case import_tsserverlibrary.default.ScriptElementKind.typeElement:
2119
+ case import_tsserverlibrary.default.ScriptElementKind.classElement:
2120
+ case import_tsserverlibrary.default.ScriptElementKind.localClassElement:
2121
+ return import_vscode_languageserver10.CompletionItemKind.Class;
2122
+ case import_tsserverlibrary.default.ScriptElementKind.interfaceElement:
2123
+ return import_vscode_languageserver10.CompletionItemKind.Interface;
2124
+ case import_tsserverlibrary.default.ScriptElementKind.enumElement:
2125
+ return import_vscode_languageserver10.CompletionItemKind.Enum;
2126
+ case import_tsserverlibrary.default.ScriptElementKind.enumMemberElement:
2127
+ return import_vscode_languageserver10.CompletionItemKind.EnumMember;
2128
+ case import_tsserverlibrary.default.ScriptElementKind.alias:
2129
+ case import_tsserverlibrary.default.ScriptElementKind.letElement:
2130
+ case import_tsserverlibrary.default.ScriptElementKind.constElement:
2131
+ case import_tsserverlibrary.default.ScriptElementKind.variableElement:
2132
+ case import_tsserverlibrary.default.ScriptElementKind.parameterElement:
2133
+ case import_tsserverlibrary.default.ScriptElementKind.localVariableElement:
2134
+ return import_vscode_languageserver10.CompletionItemKind.Variable;
2135
+ case import_tsserverlibrary.default.ScriptElementKind.functionElement:
2136
+ case import_tsserverlibrary.default.ScriptElementKind.localFunctionElement:
2137
+ return import_vscode_languageserver10.CompletionItemKind.Function;
2138
+ case import_tsserverlibrary.default.ScriptElementKind.callSignatureElement:
2139
+ case import_tsserverlibrary.default.ScriptElementKind.memberFunctionElement:
2140
+ case import_tsserverlibrary.default.ScriptElementKind.indexSignatureElement:
2141
+ case import_tsserverlibrary.default.ScriptElementKind.constructSignatureElement:
2142
+ return import_vscode_languageserver10.CompletionItemKind.Method;
2143
+ case import_tsserverlibrary.default.ScriptElementKind.memberGetAccessorElement:
2144
+ case import_tsserverlibrary.default.ScriptElementKind.memberSetAccessorElement:
2145
+ case import_tsserverlibrary.default.ScriptElementKind.memberVariableElement:
2146
+ return import_vscode_languageserver10.CompletionItemKind.Field;
2147
+ case import_tsserverlibrary.default.ScriptElementKind.constructorImplementationElement:
2148
+ return import_vscode_languageserver10.CompletionItemKind.Constructor;
2149
+ case import_tsserverlibrary.default.ScriptElementKind.typeParameterElement:
2150
+ return import_vscode_languageserver10.CompletionItemKind.TypeParameter;
2151
+ case import_tsserverlibrary.default.ScriptElementKind.link:
2152
+ case import_tsserverlibrary.default.ScriptElementKind.linkName:
2153
+ return import_vscode_languageserver10.CompletionItemKind.Reference;
2154
+ default:
2155
+ return import_vscode_languageserver10.CompletionItemKind.Property;
1695
2156
  }
1696
- return resultsByExt;
2157
+ }
2158
+ function getTSTriggerChar(char) {
2159
+ if (char && tsTriggerChars.has(char))
2160
+ return char;
1697
2161
  }
1698
2162
 
1699
- // src/service/stylesheet/index.ts
1700
- var cache3 = /* @__PURE__ */ new WeakMap();
2163
+ // src/service/style/index.ts
2164
+ var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
2165
+ var import_vscode_languageserver11 = require("vscode-languageserver");
2166
+ var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
2167
+ var import_language_tools15 = require("@marko/language-tools");
1701
2168
  var services = {
1702
- css: import_vscode_css_languageservice2.getCSSLanguageService,
1703
- less: import_vscode_css_languageservice2.getLESSLanguageService,
1704
- scss: import_vscode_css_languageservice2.getSCSSLanguageService
2169
+ ".css": import_vscode_css_languageservice2.getCSSLanguageService,
2170
+ ".less": import_vscode_css_languageservice2.getLESSLanguageService,
2171
+ ".scss": import_vscode_css_languageservice2.getSCSSLanguageService
1705
2172
  };
1706
2173
  var clientCapabilities;
1707
2174
  var StyleSheetService = {
@@ -1709,70 +2176,58 @@ var StyleSheetService = {
1709
2176
  clientCapabilities = params.capabilities;
1710
2177
  },
1711
2178
  async doComplete(doc, params) {
1712
- const infoByExt = getStyleSheetInfo(doc);
1713
2179
  const sourceOffset = doc.offsetAt(params.position);
1714
- for (const ext in infoByExt) {
1715
- const info = infoByExt[ext];
1716
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
1717
- if (generatedOffset === void 0)
2180
+ for (const style of processStyle(doc)) {
2181
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2182
+ if (generatedPos === void 0)
1718
2183
  continue;
1719
- const { service: service2, virtualDoc } = info;
1720
- const result = await service2.doComplete2(
1721
- virtualDoc,
1722
- virtualDoc.positionAt(generatedOffset),
1723
- info.parsed,
2184
+ const result = await style.service.doComplete2(
2185
+ style.virtualDoc,
2186
+ generatedPos,
2187
+ style.parsed,
1724
2188
  { resolveReference: resolveUrl }
1725
2189
  );
1726
2190
  if (result.itemDefaults) {
1727
2191
  const { editRange } = result.itemDefaults;
1728
2192
  if (editRange) {
1729
2193
  if ("start" in editRange) {
1730
- result.itemDefaults.editRange = getSourceRange(
1731
- doc,
1732
- info,
1733
- editRange
1734
- );
2194
+ result.itemDefaults.editRange = getSourceRange(style, editRange);
1735
2195
  } else {
1736
- editRange.insert = getSourceRange(doc, info, editRange.insert);
1737
- editRange.replace = getSourceRange(doc, info, editRange.replace);
2196
+ editRange.insert = getSourceRange(style, editRange.insert);
2197
+ editRange.replace = getSourceRange(style, editRange.replace);
1738
2198
  }
1739
2199
  }
1740
2200
  }
1741
2201
  for (const item of result.items) {
1742
2202
  if (item.textEdit) {
1743
- item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
2203
+ item.textEdit = getSourceInsertReplaceEdit(style, item.textEdit);
1744
2204
  }
1745
2205
  if (item.additionalTextEdits) {
1746
2206
  item.additionalTextEdits = getSourceEdits(
1747
- doc,
1748
- info,
2207
+ style,
1749
2208
  item.additionalTextEdits
1750
2209
  );
1751
2210
  }
1752
2211
  }
1753
2212
  return result;
1754
2213
  }
1755
- return import_vscode_languageserver14.CompletionList.create([], true);
1756
2214
  },
1757
2215
  findDefinition(doc, params) {
1758
- const infoByExt = getStyleSheetInfo(doc);
1759
2216
  const sourceOffset = doc.offsetAt(params.position);
1760
- for (const ext in infoByExt) {
1761
- const info = infoByExt[ext];
1762
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
1763
- if (generatedOffset === void 0)
2217
+ for (const style of processStyle(doc)) {
2218
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2219
+ if (generatedPos === void 0)
1764
2220
  continue;
1765
- const { service: service2, virtualDoc } = info;
1766
- const result = service2.findDefinition(
1767
- virtualDoc,
1768
- virtualDoc.positionAt(generatedOffset),
1769
- info.parsed
2221
+ const result = style.service.findDefinition(
2222
+ style.virtualDoc,
2223
+ generatedPos,
2224
+ style.parsed
1770
2225
  );
1771
2226
  if (result) {
1772
- const range = getSourceRange(doc, info, result.range);
1773
- if (range) {
2227
+ const sourceRange = getSourceRange(style, result.range);
2228
+ if (sourceRange) {
1774
2229
  return {
1775
- range,
2230
+ range: sourceRange,
1776
2231
  uri: doc.uri
1777
2232
  };
1778
2233
  }
@@ -1781,24 +2236,21 @@ var StyleSheetService = {
1781
2236
  }
1782
2237
  },
1783
2238
  findReferences(doc, params) {
1784
- const infoByExt = getStyleSheetInfo(doc);
1785
2239
  const sourceOffset = doc.offsetAt(params.position);
1786
- for (const ext in infoByExt) {
1787
- const info = infoByExt[ext];
1788
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
1789
- if (generatedOffset === void 0)
2240
+ for (const style of processStyle(doc)) {
2241
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2242
+ if (generatedPos === void 0)
1790
2243
  continue;
1791
- const { service: service2, virtualDoc } = info;
1792
2244
  const result = [];
1793
- for (const location of service2.findReferences(
1794
- virtualDoc,
1795
- virtualDoc.positionAt(generatedOffset),
1796
- info.parsed
2245
+ for (const location of style.service.findReferences(
2246
+ style.virtualDoc,
2247
+ generatedPos,
2248
+ style.parsed
1797
2249
  )) {
1798
- const range = getSourceRange(doc, info, location.range);
1799
- if (range) {
2250
+ const sourceRange = getSourceRange(style, location.range);
2251
+ if (sourceRange) {
1800
2252
  result.push({
1801
- range,
2253
+ range: sourceRange,
1802
2254
  uri: location.uri
1803
2255
  });
1804
2256
  }
@@ -1807,25 +2259,22 @@ var StyleSheetService = {
1807
2259
  }
1808
2260
  },
1809
2261
  findDocumentSymbols(doc) {
1810
- const infoByExt = getStyleSheetInfo(doc);
1811
2262
  const result = [];
1812
- for (const ext in infoByExt) {
1813
- const info = infoByExt[ext];
1814
- const { service: service2, virtualDoc } = info;
1815
- for (const symbol of service2.findDocumentSymbols(
1816
- virtualDoc,
1817
- info.parsed
2263
+ for (const extracted of processStyle(doc)) {
2264
+ for (const symbol of extracted.service.findDocumentSymbols(
2265
+ extracted.virtualDoc,
2266
+ extracted.parsed
1818
2267
  )) {
1819
2268
  if (symbol.location.uri === doc.uri) {
1820
- const range = getSourceRange(doc, info, symbol.location.range);
1821
- if (range) {
2269
+ const sourceRange = getSourceRange(extracted, symbol.location.range);
2270
+ if (sourceRange) {
1822
2271
  result.push({
1823
2272
  kind: symbol.kind,
1824
2273
  name: symbol.name,
1825
2274
  tags: symbol.tags,
1826
2275
  deprecated: symbol.deprecated,
1827
2276
  containerName: symbol.containerName,
1828
- location: { uri: doc.uri, range }
2277
+ location: { uri: doc.uri, range: sourceRange }
1829
2278
  });
1830
2279
  }
1831
2280
  } else {
@@ -1836,20 +2285,17 @@ var StyleSheetService = {
1836
2285
  return result.length ? result : void 0;
1837
2286
  },
1838
2287
  async findDocumentLinks(doc) {
1839
- const infoByExt = getStyleSheetInfo(doc);
1840
2288
  const result = [];
1841
- for (const ext in infoByExt) {
1842
- const info = infoByExt[ext];
1843
- const { service: service2, virtualDoc } = info;
1844
- for (const link of await service2.findDocumentLinks2(
1845
- virtualDoc,
1846
- info.parsed,
2289
+ for (const extracted of processStyle(doc)) {
2290
+ for (const link of await extracted.service.findDocumentLinks2(
2291
+ extracted.virtualDoc,
2292
+ extracted.parsed,
1847
2293
  { resolveReference: resolveUrl }
1848
2294
  )) {
1849
- const range = getSourceRange(doc, info, link.range);
1850
- if (range) {
2295
+ const sourceRange = getSourceRange(extracted, link.range);
2296
+ if (sourceRange) {
1851
2297
  result.push({
1852
- range,
2298
+ range: sourceRange,
1853
2299
  target: link.target,
1854
2300
  tooltip: link.tooltip,
1855
2301
  data: link.data
@@ -1860,24 +2306,21 @@ var StyleSheetService = {
1860
2306
  return result.length ? result : void 0;
1861
2307
  },
1862
2308
  findDocumentHighlights(doc, params) {
1863
- const infoByExt = getStyleSheetInfo(doc);
1864
2309
  const sourceOffset = doc.offsetAt(params.position);
1865
- for (const ext in infoByExt) {
1866
- const info = infoByExt[ext];
1867
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
1868
- if (generatedOffset === void 0)
2310
+ for (const style of processStyle(doc)) {
2311
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2312
+ if (generatedPos === void 0)
1869
2313
  continue;
1870
- const { service: service2, virtualDoc } = info;
1871
2314
  const result = [];
1872
- for (const highlight of service2.findDocumentHighlights(
1873
- virtualDoc,
1874
- virtualDoc.positionAt(generatedOffset),
1875
- info.parsed
2315
+ for (const highlight of style.service.findDocumentHighlights(
2316
+ style.virtualDoc,
2317
+ generatedPos,
2318
+ style.parsed
1876
2319
  )) {
1877
- const range = getSourceRange(doc, info, highlight.range);
1878
- if (range) {
2320
+ const sourceRange = getSourceRange(style, highlight.range);
2321
+ if (sourceRange) {
1879
2322
  result.push({
1880
- range,
2323
+ range: sourceRange,
1881
2324
  kind: highlight.kind
1882
2325
  });
1883
2326
  }
@@ -1886,19 +2329,16 @@ var StyleSheetService = {
1886
2329
  }
1887
2330
  },
1888
2331
  findDocumentColors(doc) {
1889
- const infoByExt = getStyleSheetInfo(doc);
1890
2332
  const result = [];
1891
- for (const ext in infoByExt) {
1892
- const info = infoByExt[ext];
1893
- const { service: service2, virtualDoc } = info;
1894
- for (const colorInfo of service2.findDocumentColors(
1895
- virtualDoc,
1896
- info.parsed
2333
+ for (const extracted of processStyle(doc)) {
2334
+ for (const colorInfo of extracted.service.findDocumentColors(
2335
+ extracted.virtualDoc,
2336
+ extracted.parsed
1897
2337
  )) {
1898
- const range = getSourceRange(doc, info, colorInfo.range);
1899
- if (range) {
2338
+ const sourceRange = getSourceRange(extracted, colorInfo.range);
2339
+ if (sourceRange) {
1900
2340
  result.push({
1901
- range,
2341
+ range: sourceRange,
1902
2342
  color: colorInfo.color
1903
2343
  });
1904
2344
  }
@@ -1907,31 +2347,19 @@ var StyleSheetService = {
1907
2347
  return result.length ? result : void 0;
1908
2348
  },
1909
2349
  getColorPresentations(doc, params) {
1910
- const infoByExt = getStyleSheetInfo(doc);
1911
- const sourceOffset = doc.offsetAt(params.range.start);
1912
- for (const ext in infoByExt) {
1913
- const info = infoByExt[ext];
1914
- const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
1915
- if (generatedOffsetStart === void 0)
1916
- continue;
1917
- const generatedOffsetEnd = info.generatedOffsetAt(
1918
- doc.offsetAt(params.range.end)
1919
- );
1920
- if (generatedOffsetEnd === void 0)
2350
+ for (const extracted of processStyle(doc)) {
2351
+ const generatedRange = getGeneratedRange(doc, extracted, params.range);
2352
+ if (generatedRange === void 0)
1921
2353
  continue;
1922
- const { service: service2, virtualDoc } = info;
1923
2354
  const result = [];
1924
- for (const colorPresentation of service2.getColorPresentations(
1925
- virtualDoc,
1926
- info.parsed,
2355
+ for (const colorPresentation of extracted.service.getColorPresentations(
2356
+ extracted.virtualDoc,
2357
+ extracted.parsed,
1927
2358
  params.color,
1928
- import_vscode_languageserver14.Range.create(
1929
- virtualDoc.positionAt(generatedOffsetStart),
1930
- virtualDoc.positionAt(generatedOffsetEnd)
1931
- )
2359
+ generatedRange
1932
2360
  )) {
1933
- const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1934
- const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
2361
+ const textEdit = colorPresentation.textEdit && getSourceEdit(extracted, colorPresentation.textEdit);
2362
+ const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(extracted, colorPresentation.additionalTextEdits);
1935
2363
  if (textEdit || additionalTextEdits) {
1936
2364
  result.push({
1937
2365
  label: colorPresentation.label,
@@ -1944,25 +2372,22 @@ var StyleSheetService = {
1944
2372
  }
1945
2373
  },
1946
2374
  doHover(doc, params) {
1947
- const infoByExt = getStyleSheetInfo(doc);
1948
2375
  const sourceOffset = doc.offsetAt(params.position);
1949
- for (const ext in infoByExt) {
1950
- const info = infoByExt[ext];
1951
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
1952
- if (generatedOffset === void 0)
2376
+ for (const style of processStyle(doc)) {
2377
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2378
+ if (generatedPos === void 0)
1953
2379
  continue;
1954
- const { service: service2, virtualDoc } = info;
1955
- const result = service2.doHover(
1956
- virtualDoc,
1957
- virtualDoc.positionAt(generatedOffset),
1958
- info.parsed
2380
+ const result = style.service.doHover(
2381
+ style.virtualDoc,
2382
+ generatedPos,
2383
+ style.parsed
1959
2384
  );
1960
2385
  if (result) {
1961
2386
  if (result.range) {
1962
- const range = getSourceRange(doc, info, result.range);
1963
- if (range) {
2387
+ const sourceRange = getSourceRange(style, result.range);
2388
+ if (sourceRange) {
1964
2389
  return {
1965
- range,
2390
+ range: sourceRange,
1966
2391
  contents: result.contents
1967
2392
  };
1968
2393
  }
@@ -1973,32 +2398,29 @@ var StyleSheetService = {
1973
2398
  }
1974
2399
  },
1975
2400
  async doRename(doc, params) {
1976
- const infoByExt = getStyleSheetInfo(doc);
1977
2401
  const sourceOffset = doc.offsetAt(params.position);
1978
- for (const ext in infoByExt) {
1979
- const info = infoByExt[ext];
1980
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
2402
+ for (const style of processStyle(doc)) {
2403
+ const generatedOffset = style.extracted.generatedOffsetAt(sourceOffset);
1981
2404
  if (generatedOffset === void 0)
1982
2405
  continue;
1983
- const { service: service2, virtualDoc } = info;
1984
- const result = service2.doRename(
1985
- virtualDoc,
1986
- virtualDoc.positionAt(generatedOffset),
2406
+ const result = style.service.doRename(
2407
+ style.virtualDoc,
2408
+ style.virtualDoc.positionAt(generatedOffset),
1987
2409
  params.newName,
1988
- info.parsed
2410
+ style.parsed
1989
2411
  );
1990
2412
  if (result.changes) {
1991
2413
  for (const uri in result.changes) {
1992
2414
  if (uri === doc.uri) {
1993
- result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
2415
+ result.changes[uri] = getSourceEdits(style, result.changes[uri]) || [];
1994
2416
  }
1995
2417
  }
1996
2418
  }
1997
2419
  if (result.documentChanges) {
1998
2420
  for (const change of result.documentChanges) {
1999
- if (import_vscode_languageserver14.TextDocumentEdit.is(change)) {
2421
+ if (import_vscode_languageserver11.TextDocumentEdit.is(change)) {
2000
2422
  if (change.textDocument.uri === doc.uri) {
2001
- change.edits = getSourceEdits(doc, info, change.edits) || [];
2423
+ change.edits = getSourceEdits(style, change.edits) || [];
2002
2424
  }
2003
2425
  }
2004
2426
  }
@@ -2008,49 +2430,36 @@ var StyleSheetService = {
2008
2430
  },
2009
2431
  doCodeActions(doc, params) {
2010
2432
  var _a;
2011
- const infoByExt = getStyleSheetInfo(doc);
2012
- const sourceOffset = doc.offsetAt(params.range.start);
2013
- for (const ext in infoByExt) {
2014
- const info = infoByExt[ext];
2015
- const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
2016
- if (generatedOffsetStart === void 0)
2017
- continue;
2018
- const generatedOffsetEnd = info.generatedOffsetAt(
2019
- doc.offsetAt(params.range.end)
2020
- );
2021
- if (generatedOffsetEnd === void 0)
2433
+ for (const extracted of processStyle(doc)) {
2434
+ const generatedRange = getGeneratedRange(doc, extracted, params.range);
2435
+ if (generatedRange === void 0)
2022
2436
  continue;
2023
- const { service: service2, virtualDoc } = info;
2024
- const result = service2.doCodeActions(
2025
- virtualDoc,
2026
- import_vscode_languageserver14.Range.create(
2027
- virtualDoc.positionAt(generatedOffsetStart),
2028
- virtualDoc.positionAt(generatedOffsetEnd)
2029
- ),
2437
+ const result = extracted.service.doCodeActions(
2438
+ extracted.virtualDoc,
2439
+ generatedRange,
2030
2440
  params.context,
2031
- info.parsed
2441
+ extracted.parsed
2032
2442
  );
2033
2443
  for (const command of result) {
2034
2444
  const edits = (_a = command.arguments) == null ? void 0 : _a[2];
2035
2445
  if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
2036
- command.arguments[2] = getSourceEdits(doc, info, edits);
2446
+ command.arguments[2] = getSourceEdits(extracted, edits);
2037
2447
  }
2038
2448
  }
2039
2449
  return result;
2040
2450
  }
2041
2451
  },
2042
2452
  doValidate(doc) {
2043
- const infoByExt = getStyleSheetInfo(doc);
2044
2453
  const result = [];
2045
- for (const ext in infoByExt) {
2046
- const info = infoByExt[ext];
2047
- for (const diag of info.service.doValidation(
2048
- info.virtualDoc,
2049
- info.parsed
2454
+ for (const extracted of processStyle(doc)) {
2455
+ for (const diag of extracted.service.doValidation(
2456
+ extracted.virtualDoc,
2457
+ extracted.parsed
2050
2458
  )) {
2051
- const range = getSourceRange(doc, info, diag.range);
2052
- if (range) {
2053
- diag.range = range;
2459
+ const sourceRange = getSourceRange(extracted, diag.range);
2460
+ if (sourceRange) {
2461
+ diag.source = "style";
2462
+ diag.range = sourceRange;
2054
2463
  result.push(diag);
2055
2464
  }
2056
2465
  }
@@ -2058,123 +2467,112 @@ var StyleSheetService = {
2058
2467
  return result.length ? result : void 0;
2059
2468
  }
2060
2469
  };
2061
- function getSourceEdits(doc, info, edits) {
2470
+ function processStyle(doc) {
2471
+ return processDoc(doc, ({ uri, version, parsed, project: { lookup } }) => {
2472
+ var _a;
2473
+ const result = [];
2474
+ for (const [ext, extracted] of (0, import_language_tools15.extractStyle)({
2475
+ parsed,
2476
+ lookup
2477
+ })) {
2478
+ const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
2479
+ fileSystemProvider: file_system_default,
2480
+ clientCapabilities
2481
+ });
2482
+ if (service2) {
2483
+ const virtualDoc = import_vscode_languageserver_textdocument2.TextDocument.create(
2484
+ uri,
2485
+ "css",
2486
+ version,
2487
+ extracted.toString()
2488
+ );
2489
+ result.push({
2490
+ service: service2,
2491
+ extracted,
2492
+ virtualDoc,
2493
+ parsed: service2.parseStylesheet(virtualDoc)
2494
+ });
2495
+ }
2496
+ }
2497
+ return result;
2498
+ });
2499
+ }
2500
+ function getSourceEdits(extracted, edits) {
2062
2501
  const result = [];
2063
2502
  for (const edit of edits) {
2064
- const sourceEdit = getSourceEdit(doc, info, edit);
2503
+ const sourceEdit = getSourceEdit(extracted, edit);
2065
2504
  if (sourceEdit) {
2066
2505
  result.push(sourceEdit);
2067
2506
  }
2068
2507
  }
2069
2508
  return result.length ? result : void 0;
2070
2509
  }
2071
- function getSourceEdit(doc, info, textEdit) {
2072
- const range = getSourceRange(doc, info, textEdit.range);
2073
- if (range) {
2510
+ function getSourceEdit(extracted, textEdit) {
2511
+ const sourceRange = getSourceRange(extracted, textEdit.range);
2512
+ if (sourceRange) {
2074
2513
  return {
2075
2514
  newText: textEdit.newText,
2076
- range
2515
+ range: sourceRange
2077
2516
  };
2078
2517
  }
2079
2518
  }
2080
- function getSourceInsertReplaceEdit(doc, info, textEdit) {
2519
+ function getSourceInsertReplaceEdit(extracted, textEdit) {
2081
2520
  if (isTextEdit(textEdit)) {
2082
- return getSourceEdit(doc, info, textEdit);
2521
+ return getSourceEdit(extracted, textEdit);
2083
2522
  } else if (textEdit.replace) {
2084
- const range = getSourceRange(doc, info, textEdit.replace);
2085
- if (range) {
2523
+ const sourceRange = getSourceRange(extracted, textEdit.replace);
2524
+ if (sourceRange) {
2086
2525
  return {
2087
2526
  newText: textEdit.newText,
2088
- replace: range
2527
+ replace: sourceRange
2089
2528
  };
2090
2529
  }
2091
2530
  } else {
2092
- const range = getSourceRange(doc, info, textEdit.insert);
2093
- if (range) {
2531
+ const sourceRange = getSourceRange(extracted, textEdit.insert);
2532
+ if (sourceRange) {
2094
2533
  return {
2095
2534
  newText: textEdit.newText,
2096
- insert: range
2535
+ insert: sourceRange
2097
2536
  };
2098
2537
  }
2099
2538
  }
2100
2539
  }
2101
- function getSourceRange(doc, info, range) {
2102
- const start = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.start));
2103
- if (start === void 0)
2104
- return;
2105
- let end = start;
2106
- if (range.start.line !== range.end.line || range.start.character !== range.end.character) {
2107
- end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
2108
- if (end === void 0)
2109
- return;
2110
- }
2111
- const pos = doc.positionAt(start);
2112
- return {
2113
- start: pos,
2114
- end: start === end ? pos : doc.positionAt(end)
2115
- };
2540
+ function getSourceRange(style, range) {
2541
+ return style.extracted.sourceLocationAt(
2542
+ style.virtualDoc.offsetAt(range.start),
2543
+ style.virtualDoc.offsetAt(range.end)
2544
+ );
2116
2545
  }
2117
- function getStyleSheetInfo(doc) {
2118
- var _a;
2119
- const parsed = parse2(doc);
2120
- let cached = cache3.get(parsed);
2121
- if (!cached) {
2122
- const results = extractStyleSheets(
2123
- doc.getText(),
2124
- parsed.program,
2125
- getCompilerInfo(doc).lookup
2126
- );
2127
- cached = {};
2128
- for (const ext in results) {
2129
- const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
2130
- fileSystemProvider: file_system_default,
2131
- clientCapabilities
2132
- });
2133
- if (!service2)
2134
- continue;
2135
- const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
2136
- const virtualDoc = import_vscode_languageserver_textdocument2.TextDocument.create(
2137
- doc.uri,
2138
- "css",
2139
- doc.version,
2140
- generated
2141
- );
2142
- cached[ext] = {
2143
- service: service2,
2144
- virtualDoc,
2145
- sourceOffsetAt,
2146
- generatedOffsetAt,
2147
- parsed: service2.parseStylesheet(virtualDoc)
2148
- };
2149
- }
2150
- cache3.set(parsed, cached);
2151
- }
2152
- return cached;
2546
+ function getGeneratedRange(doc, style, range) {
2547
+ return style.extracted.generatedLocationAt(
2548
+ doc.offsetAt(range.start),
2549
+ doc.offsetAt(range.end)
2550
+ );
2153
2551
  }
2154
2552
  function isTextEdit(edit) {
2155
2553
  return edit.range !== void 0;
2156
2554
  }
2157
2555
 
2158
2556
  // src/service/index.ts
2159
- var plugins = [marko_default, StyleSheetService];
2557
+ var REG_MARKDOWN_CHARS = /[\\`*_{}[\]<>()#+.!|-]/g;
2558
+ var plugins = [marko_default, ScriptService, StyleSheetService];
2160
2559
  var service = {
2560
+ commands: Object.assign({}, ...plugins.map(({ commands }) => commands)),
2161
2561
  async initialize(params) {
2162
- await Promise.all(plugins.map((plugin) => {
2163
- var _a;
2164
- return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
2165
- }));
2562
+ await Promise.allSettled(
2563
+ plugins.map((plugin) => {
2564
+ var _a;
2565
+ return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
2566
+ })
2567
+ );
2166
2568
  },
2167
2569
  async doComplete(doc, params, cancel) {
2168
- let items;
2169
2570
  let isIncomplete = false;
2170
- try {
2171
- for (const pending of plugins.map(
2172
- (plugin) => {
2173
- var _a;
2174
- return (_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2175
- }
2176
- )) {
2177
- const cur = await pending;
2571
+ const itemsByLabel = /* @__PURE__ */ new Map();
2572
+ await Promise.allSettled(
2573
+ plugins.map(async (plugin) => {
2574
+ var _a;
2575
+ const cur = await ((_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2178
2576
  if (cancel.isCancellationRequested)
2179
2577
  return;
2180
2578
  if (cur) {
@@ -2183,185 +2581,181 @@ var service = {
2183
2581
  curItems = cur;
2184
2582
  } else {
2185
2583
  curItems = cur.items;
2186
- isIncomplete || (isIncomplete = cur.isIncomplete);
2584
+ isIncomplete ||= cur.isIncomplete;
2585
+ }
2586
+ for (const item of curItems) {
2587
+ const { label } = item;
2588
+ const existingItem = itemsByLabel.get(label);
2589
+ if (existingItem) {
2590
+ if ((existingItem.sortText || label) < (item.sortText || label)) {
2591
+ itemsByLabel.set(label, item);
2592
+ }
2593
+ } else {
2594
+ itemsByLabel.set(label, item);
2595
+ }
2187
2596
  }
2188
- items = items ? items.concat(curItems) : curItems;
2189
2597
  }
2190
- }
2191
- } catch (err) {
2192
- isIncomplete = true;
2193
- displayError(err);
2598
+ })
2599
+ );
2600
+ if (cancel.isCancellationRequested)
2601
+ return;
2602
+ if (itemsByLabel.size) {
2603
+ return { items: [...itemsByLabel.values()], isIncomplete };
2194
2604
  }
2195
- if (items) {
2196
- return import_vscode_languageserver15.CompletionList.create(items, isIncomplete);
2605
+ },
2606
+ async doCompletionResolve(item, cancel) {
2607
+ var _a;
2608
+ for (const plugin of plugins) {
2609
+ try {
2610
+ const result = await ((_a = plugin.doCompletionResolve) == null ? void 0 : _a.call(plugin, item, cancel));
2611
+ if (cancel.isCancellationRequested)
2612
+ return;
2613
+ if (result)
2614
+ return result;
2615
+ } catch {
2616
+ }
2197
2617
  }
2198
2618
  },
2199
2619
  async findDefinition(doc, params, cancel) {
2200
2620
  let result;
2201
- try {
2202
- for (const pending of plugins.map(
2203
- (plugin) => {
2204
- var _a;
2205
- return (_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2206
- }
2207
- )) {
2208
- const cur = await pending;
2621
+ await Promise.allSettled(
2622
+ plugins.map(async (plugin) => {
2623
+ var _a;
2624
+ const cur = await ((_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2209
2625
  if (cancel.isCancellationRequested)
2210
2626
  return;
2211
2627
  if (cur)
2212
2628
  result = (result || []).concat(cur);
2213
- }
2214
- } catch (err) {
2215
- displayError(err);
2216
- }
2629
+ })
2630
+ );
2631
+ if (cancel.isCancellationRequested)
2632
+ return;
2217
2633
  return result;
2218
2634
  },
2219
2635
  async findReferences(doc, params, cancel) {
2220
2636
  let result;
2221
- try {
2222
- for (const pending of plugins.map(
2223
- (plugin) => {
2224
- var _a;
2225
- return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2226
- }
2227
- )) {
2228
- const cur = await pending;
2637
+ await Promise.allSettled(
2638
+ plugins.map(async (plugin) => {
2639
+ var _a;
2640
+ const cur = await ((_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2229
2641
  if (cancel.isCancellationRequested)
2230
2642
  return;
2231
2643
  if (cur)
2232
- result = result ? result.concat(cur) : cur;
2233
- }
2234
- } catch (err) {
2235
- displayError(err);
2236
- }
2644
+ result = (result || []).concat(cur);
2645
+ })
2646
+ );
2647
+ if (cancel.isCancellationRequested)
2648
+ return;
2237
2649
  return result;
2238
2650
  },
2239
2651
  async findDocumentSymbols(doc, params, cancel) {
2240
2652
  let result;
2241
- try {
2242
- for (const pending of plugins.map(
2243
- (plugin) => {
2244
- var _a;
2245
- return (_a = plugin.findDocumentSymbols) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2246
- }
2247
- )) {
2248
- const cur = await pending;
2653
+ await Promise.allSettled(
2654
+ plugins.map(async (plugin) => {
2655
+ var _a;
2656
+ const cur = await ((_a = plugin.findDocumentSymbols) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2249
2657
  if (cancel.isCancellationRequested)
2250
2658
  return;
2251
2659
  if (cur)
2252
- result = result ? result.concat(cur) : cur;
2253
- }
2254
- } catch (err) {
2255
- displayError(err);
2256
- }
2660
+ result = (result || []).concat(cur);
2661
+ })
2662
+ );
2663
+ if (cancel.isCancellationRequested)
2664
+ return;
2257
2665
  return result;
2258
2666
  },
2259
2667
  async findDocumentLinks(doc, params, cancel) {
2260
2668
  let result;
2261
- try {
2262
- for (const pending of plugins.map(
2263
- (plugin) => {
2264
- var _a;
2265
- return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2266
- }
2267
- )) {
2268
- const cur = await pending;
2669
+ await Promise.allSettled(
2670
+ plugins.map(async (plugin) => {
2671
+ var _a;
2672
+ const cur = await ((_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2269
2673
  if (cancel.isCancellationRequested)
2270
2674
  return;
2271
2675
  if (cur)
2272
- result = result ? result.concat(cur) : cur;
2273
- }
2274
- } catch (err) {
2275
- displayError(err);
2276
- }
2676
+ result = (result || []).concat(cur);
2677
+ })
2678
+ );
2679
+ if (cancel.isCancellationRequested)
2680
+ return;
2277
2681
  return result;
2278
2682
  },
2279
2683
  async findDocumentHighlights(doc, params, cancel) {
2280
2684
  let result;
2281
- try {
2282
- for (const pending of plugins.map(
2283
- (plugin) => {
2284
- var _a;
2285
- return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2286
- }
2287
- )) {
2288
- const cur = await pending;
2685
+ await Promise.allSettled(
2686
+ plugins.map(async (plugin) => {
2687
+ var _a;
2688
+ const cur = await ((_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2289
2689
  if (cancel.isCancellationRequested)
2290
2690
  return;
2291
2691
  if (cur)
2292
- result = result ? result.concat(cur) : cur;
2293
- }
2294
- } catch (err) {
2295
- displayError(err);
2296
- }
2692
+ result = (result || []).concat(cur);
2693
+ })
2694
+ );
2695
+ if (cancel.isCancellationRequested)
2696
+ return;
2297
2697
  return result;
2298
2698
  },
2299
2699
  async findDocumentColors(doc, params, cancel) {
2300
2700
  let result;
2301
- try {
2302
- for (const pending of plugins.map(
2303
- (plugin) => {
2304
- var _a;
2305
- return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2306
- }
2307
- )) {
2308
- const cur = await pending;
2701
+ await Promise.allSettled(
2702
+ plugins.map(async (plugin) => {
2703
+ var _a;
2704
+ const cur = await ((_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2309
2705
  if (cancel.isCancellationRequested)
2310
2706
  return;
2311
2707
  if (cur)
2312
- result = result ? result.concat(cur) : cur;
2313
- }
2314
- } catch (err) {
2315
- displayError(err);
2316
- }
2708
+ result = (result || []).concat(cur);
2709
+ })
2710
+ );
2711
+ if (cancel.isCancellationRequested)
2712
+ return;
2317
2713
  return result;
2318
2714
  },
2319
2715
  async getColorPresentations(doc, params, cancel) {
2320
2716
  let result;
2321
- try {
2322
- for (const pending of plugins.map(
2323
- (plugin) => {
2324
- var _a;
2325
- return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2326
- }
2327
- )) {
2328
- const cur = await pending;
2717
+ await Promise.allSettled(
2718
+ plugins.map(async (plugin) => {
2719
+ var _a;
2720
+ const cur = await ((_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2329
2721
  if (cancel.isCancellationRequested)
2330
2722
  return;
2331
2723
  if (cur)
2332
- result = result ? result.concat(cur) : cur;
2333
- }
2334
- } catch (err) {
2335
- displayError(err);
2336
- }
2724
+ result = (result || []).concat(cur);
2725
+ })
2726
+ );
2727
+ if (cancel.isCancellationRequested)
2728
+ return;
2337
2729
  return result;
2338
2730
  },
2339
2731
  async doHover(doc, params, cancel) {
2340
- var _a;
2341
- try {
2342
- for (const plugin of plugins) {
2343
- const result = await ((_a = plugin.doHover) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2732
+ let result;
2733
+ await Promise.allSettled(
2734
+ plugins.map(async (plugin) => {
2735
+ var _a;
2736
+ const cur = await ((_a = plugin.doHover) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2344
2737
  if (cancel.isCancellationRequested)
2345
2738
  return;
2346
- if (result)
2347
- return result;
2348
- }
2349
- } catch (err) {
2350
- displayError(err);
2351
- }
2739
+ if (cur) {
2740
+ if (result) {
2741
+ result.range = maxRange(result.range, cur.range);
2742
+ result.contents = mergeHoverContents(result.contents, cur.contents);
2743
+ } else {
2744
+ result = cur;
2745
+ }
2746
+ }
2747
+ })
2748
+ );
2749
+ return result;
2352
2750
  },
2353
2751
  async doRename(doc, params, cancel) {
2354
2752
  let changes;
2355
2753
  let changeAnnotations;
2356
2754
  let documentChanges;
2357
- try {
2358
- for (const pending of plugins.map(
2359
- (plugin) => {
2360
- var _a;
2361
- return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2362
- }
2363
- )) {
2364
- const cur = await pending;
2755
+ await Promise.allSettled(
2756
+ plugins.map(async (plugin) => {
2757
+ var _a;
2758
+ const cur = await ((_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2365
2759
  if (cancel.isCancellationRequested)
2366
2760
  return;
2367
2761
  if (cur) {
@@ -2385,10 +2779,10 @@ var service = {
2385
2779
  documentChanges = documentChanges ? documentChanges.concat(cur.documentChanges) : cur.documentChanges;
2386
2780
  }
2387
2781
  }
2388
- }
2389
- } catch (err) {
2390
- displayError(err);
2391
- }
2782
+ })
2783
+ );
2784
+ if (cancel.isCancellationRequested)
2785
+ return;
2392
2786
  if (changes || changeAnnotations || documentChanges) {
2393
2787
  return {
2394
2788
  changes,
@@ -2399,62 +2793,112 @@ var service = {
2399
2793
  },
2400
2794
  async doCodeActions(doc, params, cancel) {
2401
2795
  let result;
2402
- try {
2403
- for (const pending of plugins.map(
2404
- (plugin) => {
2405
- var _a;
2406
- return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2407
- }
2408
- )) {
2409
- const cur = await pending;
2796
+ await Promise.allSettled(
2797
+ plugins.map(async (plugin) => {
2798
+ var _a;
2799
+ const cur = await ((_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2410
2800
  if (cancel.isCancellationRequested)
2411
2801
  return;
2412
2802
  if (cur)
2413
- result = result ? result.concat(cur) : cur;
2414
- }
2415
- } catch (err) {
2416
- displayError(err);
2417
- }
2803
+ result = (result || []).concat(cur);
2804
+ })
2805
+ );
2806
+ if (cancel.isCancellationRequested)
2807
+ return;
2418
2808
  return result;
2419
2809
  },
2420
2810
  async doValidate(doc) {
2421
2811
  let result;
2422
- try {
2423
- for (const pending of plugins.map((plugin) => {
2812
+ await Promise.allSettled(
2813
+ plugins.map(async (plugin) => {
2424
2814
  var _a;
2425
- return (_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc);
2426
- })) {
2427
- const cur = await pending;
2815
+ const cur = await ((_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc));
2428
2816
  if (cur)
2429
- result = result ? result.concat(cur) : cur;
2430
- }
2431
- } catch (err) {
2432
- displayError(err);
2433
- }
2817
+ result = (result || []).concat(cur);
2818
+ })
2819
+ );
2434
2820
  return result;
2435
2821
  },
2436
2822
  format: marko_default.format
2437
2823
  };
2824
+ function maxRange(a, b) {
2825
+ if (!a)
2826
+ return b;
2827
+ if (!b)
2828
+ return a;
2829
+ return {
2830
+ start: {
2831
+ line: Math.min(a.start.line, b.start.line),
2832
+ character: Math.min(a.start.character, b.start.character)
2833
+ },
2834
+ end: {
2835
+ line: Math.max(a.end.line, b.end.line),
2836
+ character: Math.max(a.end.character, b.end.character)
2837
+ }
2838
+ };
2839
+ }
2840
+ function mergeHoverContents(a, b) {
2841
+ if (!a)
2842
+ return b;
2843
+ if (!b)
2844
+ return a;
2845
+ if (!import_vscode_languageserver12.MarkupContent.is(a)) {
2846
+ a = markedStringToMarkupContent(a);
2847
+ }
2848
+ if (!import_vscode_languageserver12.MarkupContent.is(b)) {
2849
+ b = markedStringToMarkupContent(b);
2850
+ }
2851
+ if (a.kind === b.kind) {
2852
+ return {
2853
+ kind: a.kind,
2854
+ value: `${a.value}
2855
+ ${b.value}`
2856
+ };
2857
+ }
2858
+ return {
2859
+ kind: import_vscode_languageserver12.MarkupKind.Markdown,
2860
+ value: `${markupContentToMarkdown(a)}
2861
+ ${markupContentToMarkdown(b)}`
2862
+ };
2863
+ }
2864
+ function markedStringToMarkupContent(markedString) {
2865
+ return {
2866
+ kind: import_vscode_languageserver12.MarkupKind.Markdown,
2867
+ value: Array.isArray(markedString) ? markedString.map((it) => markedStringToString(it)).join("\n") : markedStringToString(markedString)
2868
+ };
2869
+ }
2870
+ function markedStringToString(markedString) {
2871
+ if (typeof markedString === "string") {
2872
+ return markedString;
2873
+ }
2874
+ return `\`\`\`${markedString.language}
2875
+ ${markedString.value}
2876
+ \`\`\``;
2877
+ }
2878
+ function markupContentToMarkdown(content) {
2879
+ return content.kind === import_vscode_languageserver12.MarkupKind.Markdown ? content.value : escapeMarkdown(content.value);
2880
+ }
2881
+ function escapeMarkdown(str) {
2882
+ return str.replace(REG_MARKDOWN_CHARS, "$1");
2883
+ }
2438
2884
 
2439
2885
  // src/index.ts
2440
2886
  if (typeof require !== "undefined" && require.extensions && !(".ts" in require.extensions)) {
2441
2887
  require.extensions[".ts"] = void 0;
2442
2888
  }
2443
- var documents = new import_node.TextDocuments(import_vscode_languageserver_textdocument3.TextDocument);
2444
- var connection2 = (0, import_node.createConnection)(import_node.ProposedFeatures.all);
2889
+ var connection3 = (0, import_node.createConnection)(import_node.ProposedFeatures.all);
2445
2890
  var prevDiags = /* @__PURE__ */ new WeakMap();
2446
- var pendingDiags = /* @__PURE__ */ new WeakSet();
2447
2891
  var diagnosticTimeout;
2448
2892
  console.log = (...args) => {
2449
- connection2.console.log(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2893
+ connection3.console.log(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2450
2894
  };
2451
2895
  console.error = (...args) => {
2452
- connection2.console.error(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2896
+ connection3.console.error(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2453
2897
  };
2454
2898
  process.on("uncaughtException", console.error);
2455
2899
  process.on("unhandledRejection", console.error);
2456
- connection2.onInitialize(async (params) => {
2457
- setup(connection2);
2900
+ connection3.onInitialize(async (params) => {
2901
+ setup3(connection3);
2458
2902
  await service.initialize(params);
2459
2903
  return {
2460
2904
  capabilities: {
@@ -2470,6 +2914,7 @@ connection2.onInitialize(async (params) => {
2470
2914
  documentHighlightProvider: true,
2471
2915
  documentSymbolProvider: true,
2472
2916
  completionProvider: {
2917
+ resolveProvider: true,
2473
2918
  triggerCharacters: [
2474
2919
  ".",
2475
2920
  ":",
@@ -2495,111 +2940,123 @@ connection2.onInitialize(async (params) => {
2495
2940
  }
2496
2941
  };
2497
2942
  });
2498
- connection2.onDidChangeConfiguration(validateDocs);
2499
- connection2.onDidChangeWatchedFiles(validateDocs);
2500
- documents.onDidChangeContent(({ document }) => {
2501
- queueDiagnostic();
2502
- pendingDiags.add(document);
2503
- clearCompilerCache(document);
2943
+ setup2(connection3);
2944
+ onConfigChange(validateDocs);
2945
+ setup(connection3);
2946
+ onFileChange((changeDoc) => {
2947
+ if (changeDoc) {
2948
+ queueDiagnostic();
2949
+ getMarkoProject(getFSDir(changeDoc)).cache.delete(changeDoc);
2950
+ } else {
2951
+ validateDocs();
2952
+ }
2504
2953
  });
2505
- connection2.onCompletion(async (params, cancel) => {
2954
+ connection3.onCompletion(async (params, cancel) => {
2506
2955
  return await service.doComplete(
2507
- documents.get(params.textDocument.uri),
2956
+ get(params.textDocument.uri),
2508
2957
  params,
2509
2958
  cancel
2510
2959
  ) || null;
2511
2960
  });
2512
- connection2.onDefinition(async (params, cancel) => {
2961
+ connection3.onCompletionResolve(async (item, cancel) => {
2962
+ return await service.doCompletionResolve(item, cancel) || item;
2963
+ });
2964
+ connection3.onDefinition(async (params, cancel) => {
2513
2965
  return await service.findDefinition(
2514
- documents.get(params.textDocument.uri),
2966
+ get(params.textDocument.uri),
2515
2967
  params,
2516
2968
  cancel
2517
2969
  ) || null;
2518
2970
  });
2519
- connection2.onReferences(async (params, cancel) => {
2971
+ connection3.onReferences(async (params, cancel) => {
2520
2972
  return await service.findReferences(
2521
- documents.get(params.textDocument.uri),
2973
+ get(params.textDocument.uri),
2522
2974
  params,
2523
2975
  cancel
2524
2976
  ) || null;
2525
2977
  });
2526
- connection2.onDocumentLinks(async (params, cancel) => {
2978
+ connection3.onDocumentLinks(async (params, cancel) => {
2527
2979
  return await service.findDocumentLinks(
2528
- documents.get(params.textDocument.uri),
2980
+ get(params.textDocument.uri),
2529
2981
  params,
2530
2982
  cancel
2531
2983
  ) || null;
2532
2984
  });
2533
- connection2.onDocumentSymbol(async (params, cancel) => {
2985
+ connection3.onDocumentSymbol(async (params, cancel) => {
2534
2986
  return await service.findDocumentSymbols(
2535
- documents.get(params.textDocument.uri),
2987
+ get(params.textDocument.uri),
2536
2988
  params,
2537
2989
  cancel
2538
2990
  ) || null;
2539
2991
  });
2540
- connection2.onDocumentHighlight(async (params, cancel) => {
2992
+ connection3.onDocumentHighlight(async (params, cancel) => {
2541
2993
  return await service.findDocumentHighlights(
2542
- documents.get(params.textDocument.uri),
2994
+ get(params.textDocument.uri),
2543
2995
  params,
2544
2996
  cancel
2545
2997
  ) || null;
2546
2998
  });
2547
- connection2.onDocumentColor(async (params, cancel) => {
2999
+ connection3.onDocumentColor(async (params, cancel) => {
2548
3000
  return await service.findDocumentColors(
2549
- documents.get(params.textDocument.uri),
3001
+ get(params.textDocument.uri),
2550
3002
  params,
2551
3003
  cancel
2552
3004
  ) || null;
2553
3005
  });
2554
- connection2.onColorPresentation(async (params, cancel) => {
3006
+ connection3.onColorPresentation(async (params, cancel) => {
2555
3007
  return await service.getColorPresentations(
2556
- documents.get(params.textDocument.uri),
3008
+ get(params.textDocument.uri),
2557
3009
  params,
2558
3010
  cancel
2559
3011
  ) || null;
2560
3012
  });
2561
- connection2.onHover(async (params, cancel) => {
3013
+ connection3.onHover(async (params, cancel) => {
2562
3014
  return await service.doHover(
2563
- documents.get(params.textDocument.uri),
3015
+ get(params.textDocument.uri),
2564
3016
  params,
2565
3017
  cancel
2566
3018
  ) || null;
2567
3019
  });
2568
- connection2.onRenameRequest(async (params, cancel) => {
3020
+ connection3.onRenameRequest(async (params, cancel) => {
2569
3021
  return await service.doRename(
2570
- documents.get(params.textDocument.uri),
3022
+ get(params.textDocument.uri),
2571
3023
  params,
2572
3024
  cancel
2573
3025
  ) || null;
2574
3026
  });
2575
- connection2.onCodeAction(async (params, cancel) => {
3027
+ connection3.onCodeAction(async (params, cancel) => {
2576
3028
  return await service.doCodeActions(
2577
- documents.get(params.textDocument.uri),
3029
+ get(params.textDocument.uri),
2578
3030
  params,
2579
3031
  cancel
2580
3032
  ) || null;
2581
3033
  });
2582
- connection2.onDocumentFormatting(async (params, cancel) => {
3034
+ connection3.onDocumentFormatting(async (params, cancel) => {
2583
3035
  return await service.format(
2584
- documents.get(params.textDocument.uri),
3036
+ get(params.textDocument.uri),
2585
3037
  params,
2586
3038
  cancel
2587
3039
  ) || null;
2588
3040
  });
3041
+ for (const command in service.commands) {
3042
+ connection3.onRequest(command, service.commands[command]);
3043
+ }
2589
3044
  function validateDocs() {
2590
3045
  queueDiagnostic();
2591
- clearCompilerCache();
2592
- for (const doc of documents.all()) {
2593
- pendingDiags.add(doc);
3046
+ for (const project of getMarkoProjects()) {
3047
+ project.cache.clear();
3048
+ project.compiler.taglib.clearCaches();
2594
3049
  }
2595
3050
  }
2596
3051
  function queueDiagnostic() {
2597
3052
  clearTimeout(diagnosticTimeout);
2598
3053
  const id = diagnosticTimeout = setTimeout(async () => {
2599
3054
  const results = await Promise.all(
2600
- documents.all().map(async (doc) => {
2601
- if (!pendingDiags.delete(doc))
3055
+ Array.from(getAllOpen()).map(async (doc) => {
3056
+ if (!isOpen(doc)) {
3057
+ prevDiags.delete(doc);
2602
3058
  return;
3059
+ }
2603
3060
  const prevDiag = prevDiags.get(doc) || [];
2604
3061
  const nextDiag = await service.doValidate(doc) || [];
2605
3062
  if ((0, import_util2.isDeepStrictEqual)(prevDiag, nextDiag))
@@ -2612,7 +3069,7 @@ function queueDiagnostic() {
2612
3069
  if (result) {
2613
3070
  const [doc, diag] = result;
2614
3071
  prevDiags.set(doc, diag);
2615
- connection2.sendDiagnostics({
3072
+ connection3.sendDiagnostics({
2616
3073
  uri: doc.uri,
2617
3074
  diagnostics: diag
2618
3075
  });
@@ -2621,6 +3078,5 @@ function queueDiagnostic() {
2621
3078
  }
2622
3079
  }, 400);
2623
3080
  }
2624
- documents.listen(connection2);
2625
- connection2.listen();
3081
+ connection3.listen();
2626
3082
  //# sourceMappingURL=index.js.map