@marko/language-server 0.12.17 → 1.0.1

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 +2071 -1567
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.mjs +2103 -1593
  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 += `
726
-
727
- ${autocomplete.description}`;
728
- }
729
- if (autocomplete.descriptionMoreURL) {
730
- documentation.value += `
243
+ }
731
244
 
732
- [More Info](${autocomplete.descriptionMoreURL})`;
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 {
733
256
  }
734
257
  }
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
- };
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
+ }
743
274
  }
744
275
 
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
- }
777
- }
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();
778
295
  }
779
296
  } 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
- );
297
+ previousMessagesByType.set(type, [msg]);
298
+ }
299
+ setImmediate(() => connection2.sendNotification(type, msg));
300
+ }
301
+
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
791
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);
792
350
  }
351
+ } else {
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,42 +605,199 @@ 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;
1079
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
+ }
753
+ }
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
+ ];
1080
801
  }
1081
802
  }
1082
803
 
@@ -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,93 +962,99 @@ function escape(val) {
1240
962
  return String(val).replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
1241
963
  }
1242
964
 
1243
- // src/service/marko/definition/OpenTagName.ts
1244
- function OpenTagName3({
1245
- lookup,
1246
- parsed,
1247
- node
1248
- }) {
1249
- const tag = node.parent;
1250
- let tagDef;
1251
- let range = START_OF_FILE;
1252
- if (tag.type === 14 /* AttrTag */) {
1253
- let parentTag = tag.owner;
1254
- while ((parentTag == null ? void 0 : parentTag.type) === 14 /* AttrTag */)
1255
- parentTag = parentTag.owner;
1256
- tagDef = parentTag && parentTag.nameText ? lookup.getTag(parentTag.nameText) : void 0;
1257
- } else {
1258
- tagDef = tag.nameText ? lookup.getTag(tag.nameText) : void 0;
965
+ // src/service/marko/definition/AttrName.ts
966
+ function AttrName2({
967
+ node,
968
+ file: {
969
+ parsed,
970
+ project: { lookup }
1259
971
  }
1260
- if (!tagDef) {
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) {
1261
979
  return;
1262
980
  }
1263
- const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
1264
- if (!import_path4.default.isAbsolute(tagEntryFile)) {
981
+ const attrEntryFile = attrDef.filePath || (tagDef == null ? void 0 : tagDef.filePath);
982
+ if (!attrEntryFile) {
1265
983
  return;
1266
984
  }
1267
- if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
1268
- const tagDefDoc = createTextDocument(tagEntryFile);
1269
- const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(
1270
- tagDefDoc.getText()
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
1271
989
  );
1272
990
  if (match && match.index) {
1273
- range = import_vscode_languageserver9.Range.create(
1274
- tagDefDoc.positionAt(match.index),
1275
- tagDefDoc.positionAt(match.index + match[0].length)
991
+ range = (0, import_language_tools7.getLocation)(
992
+ (0, import_language_tools7.getLines)(tagDefSource),
993
+ match.index,
994
+ match.index + match[0].length
1276
995
  );
1277
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
+ ];
1278
1005
  }
1279
- 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
1006
  }
1288
1007
 
1289
- // src/service/marko/definition/AttrName.ts
1008
+ // src/service/marko/definition/OpenTagName.ts
1009
+ var import_fs3 = __toESM(require("fs"));
1010
+ var import_path5 = __toESM(require("path"));
1290
1011
  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) {
1012
+ var import_language_tools8 = require("@marko/language-tools");
1013
+ function OpenTagName3({
1014
+ node,
1015
+ file: {
1016
+ parsed,
1017
+ project: { lookup }
1018
+ }
1019
+ }) {
1020
+ const tag = node.parent;
1021
+ let tagDef;
1022
+ let range = START_LOCATION;
1023
+ if (tag.type === import_language_tools8.NodeType.AttrTag) {
1024
+ let parentTag = tag.owner;
1025
+ while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools8.NodeType.AttrTag)
1026
+ parentTag = parentTag.owner;
1027
+ tagDef = parentTag && parentTag.nameText ? lookup.getTag(parentTag.nameText) : void 0;
1028
+ } else {
1029
+ tagDef = tag.nameText ? lookup.getTag(tag.nameText) : void 0;
1030
+ }
1031
+ if (!tagDef) {
1305
1032
  return;
1306
1033
  }
1307
- const attrEntryFile = attrDef.filePath || tagDef && tagDef.filePath;
1308
- if (!attrEntryFile) {
1034
+ const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
1035
+ if (!import_path5.default.isAbsolute(tagEntryFile)) {
1309
1036
  return;
1310
1037
  }
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()
1038
+ if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
1039
+ const tagDefSource = import_fs3.default.readFileSync(tagEntryFile, "utf-8");
1040
+ const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(
1041
+ tagDefSource
1315
1042
  );
1316
1043
  if (match && match.index) {
1317
- range = import_vscode_languageserver10.Range.create(
1318
- tagDefDoc.positionAt(match.index),
1319
- 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
1320
1048
  );
1321
1049
  }
1322
1050
  }
1323
1051
  return [
1324
- import_vscode_languageserver10.LocationLink.create(
1325
- import_vscode_uri5.URI.file(attrEntryFile).toString(),
1326
- range,
1327
- range,
1328
- parsed.locationAt(node)
1329
- )
1052
+ {
1053
+ targetUri: import_vscode_uri5.URI.file(tagEntryFile).toString(),
1054
+ targetRange: range,
1055
+ targetSelectionRange: range,
1056
+ originSelectionRange: parsed.locationAt(node)
1057
+ }
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,980 @@ 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 insertModuleStatementLocCache = /* @__PURE__ */ new WeakMap();
1451
+ var markoFileReg = /\.marko$/;
1452
+ var tsTriggerChars = /* @__PURE__ */ new Set([".", '"', "'", "`", "/", "@", "<", "#", " "]);
1453
+ var optionalModifierReg = /\boptional\b/;
1454
+ var deprecatedModifierReg = /\bdeprecated\b/;
1455
+ var colorModifierReg = /\bcolor\b/;
1456
+ var localInternalsPrefix = "__marko_internal_";
1457
+ var ScriptService = {
1458
+ commands: {
1459
+ "$/showScriptOutput": async (uri) => {
1460
+ const doc = get(uri);
1461
+ if ((doc == null ? void 0 : doc.languageId) !== "marko")
1462
+ return;
1463
+ const filename = getFSPath(doc);
1464
+ if (!filename)
1465
+ return;
1466
+ const project = getTSProject(filename);
1467
+ const extracted = processScript(doc, project);
1468
+ const lang = getScriptLang(
1469
+ filename,
1470
+ import_tsserverlibrary.default,
1471
+ project.host,
1472
+ project.markoScriptLang
1473
+ );
1474
+ const generated = extracted.toString();
1475
+ const content = (() => {
1476
+ try {
1477
+ return prettier2.format(generated, {
1478
+ parser: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "babel"
1479
+ });
1480
+ } catch {
1481
+ return generated;
1482
+ }
1483
+ })();
1578
1484
  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;
1485
+ language: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "javascript",
1486
+ content
1487
+ };
1488
+ }
1489
+ },
1490
+ async initialize() {
1491
+ onConfigChange(() => {
1492
+ snapshotCache.clear();
1493
+ });
1494
+ onFileChange((doc) => {
1495
+ if (doc) {
1496
+ const filename = getFSPath(doc);
1497
+ extractCache.delete(filename);
1498
+ snapshotCache.delete(filename);
1499
+ } else {
1500
+ extractCache.clear();
1501
+ snapshotCache.clear();
1502
+ }
1503
+ });
1504
+ },
1505
+ async doComplete(doc, params) {
1506
+ var _a;
1507
+ const fileName = getFSPath(doc);
1508
+ if (!fileName)
1509
+ return;
1510
+ const project = getTSProject(fileName);
1511
+ const extracted = processScript(doc, project);
1512
+ const sourceOffset = doc.offsetAt(params.position);
1513
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1514
+ if (generatedOffset === void 0)
1515
+ return;
1516
+ const completions = project.service.getCompletionsAtPosition(
1517
+ fileName,
1518
+ generatedOffset,
1519
+ {
1520
+ ...await getPreferences(project.markoScriptLang),
1521
+ ...params.context,
1522
+ triggerCharacter: getTSTriggerChar((_a = params.context) == null ? void 0 : _a.triggerCharacter)
1523
+ }
1524
+ );
1525
+ if (!(completions == null ? void 0 : completions.entries.length))
1526
+ return;
1527
+ const result = [];
1528
+ for (const completion of completions.entries) {
1529
+ let { name: label, insertText, sortText } = completion;
1530
+ if (label.startsWith(localInternalsPrefix))
1531
+ continue;
1532
+ const { replacementSpan } = completion;
1533
+ let textEdit;
1534
+ let detail;
1535
+ let kind;
1536
+ let tags;
1537
+ let labelDetails;
1538
+ let source = completion.source;
1539
+ if (source && completion.hasAction) {
1540
+ if (source[0] === ".") {
1541
+ source = import_path9.default.resolve(fileName, "..", source);
1542
+ }
1543
+ detail = (0, import_relative_import_path.relativeImportPath)(fileName, source);
1544
+ sortText = `\uFFFF${sortText}`;
1545
+ } else if (completion.sourceDisplay) {
1546
+ const description = import_tsserverlibrary.default.displayPartsToString(completion.sourceDisplay);
1547
+ if (description !== label) {
1548
+ labelDetails = { description };
1549
+ }
1550
+ }
1551
+ if (completion.kindModifiers) {
1552
+ if (optionalModifierReg.test(completion.kindModifiers)) {
1553
+ insertText = label;
1554
+ label += "?";
1555
+ }
1556
+ if (deprecatedModifierReg.test(completion.kindModifiers)) {
1557
+ tags = [import_vscode_languageserver10.CompletionItemTag.Deprecated];
1558
+ }
1559
+ if (colorModifierReg.test(completion.kindModifiers)) {
1560
+ kind = import_vscode_languageserver10.CompletionItemKind.Color;
1561
+ }
1562
+ }
1563
+ if (replacementSpan) {
1564
+ const sourceRange = sourceLocationAtTextSpan(
1565
+ extracted,
1566
+ replacementSpan
1567
+ );
1568
+ if (sourceRange) {
1569
+ textEdit = {
1570
+ range: sourceRange,
1571
+ newText: insertText || label
1572
+ };
1573
+ } else {
1574
+ continue;
1575
+ }
1576
+ }
1577
+ result.push({
1578
+ tags,
1579
+ label,
1580
+ detail,
1581
+ textEdit,
1582
+ sortText,
1583
+ insertText,
1584
+ labelDetails,
1585
+ filterText: insertText,
1586
+ preselect: completion.isRecommended || void 0,
1587
+ kind: kind || convertCompletionItemKind(completion.kind),
1588
+ insertTextFormat: completion.isSnippet ? import_vscode_languageserver10.InsertTextFormat.Snippet : void 0,
1589
+ data: completion.data && {
1590
+ originalData: completion.data,
1591
+ originalName: completion.name,
1592
+ originalSource: source,
1593
+ generatedOffset,
1594
+ fileName
1595
+ }
1596
+ });
1597
+ }
1598
+ return {
1599
+ isIncomplete: true,
1600
+ items: result
1601
+ };
1602
+ },
1603
+ async doCompletionResolve(item) {
1604
+ const { data } = item;
1605
+ if (!data)
1606
+ return;
1607
+ const { fileName } = data;
1608
+ if (!fileName)
1609
+ return;
1610
+ const doc = get(filenameToURI(fileName));
1611
+ if (!doc)
1612
+ return;
1613
+ const project = getTSProject(fileName);
1614
+ const detail = project.service.getCompletionEntryDetails(
1615
+ fileName,
1616
+ data.generatedOffset,
1617
+ data.originalName,
1618
+ {},
1619
+ data.originalSource,
1620
+ await getPreferences(project.markoScriptLang),
1621
+ data.originalData
1622
+ );
1623
+ if (!(detail == null ? void 0 : detail.codeActions))
1624
+ return;
1625
+ const extracted = processScript(doc, project);
1626
+ const textEdits = item.additionalTextEdits = item.additionalTextEdits || [];
1627
+ for (const action of detail.codeActions) {
1628
+ for (const change of action.changes) {
1629
+ if (change.fileName !== fileName)
1630
+ continue;
1631
+ for (const { span, newText: rawText } of change.textChanges) {
1632
+ let range;
1633
+ let newText = rawText;
1634
+ if (span.length === 0 && /^\s*(?:import|export) /.test(newText)) {
1635
+ const cached = insertModuleStatementLocCache.get(extracted);
1636
+ newText = newText.replace(/\n\s*$/, "\n");
1637
+ if (cached) {
1638
+ range = cached;
1587
1639
  } else {
1588
- max = mid - 1;
1640
+ const { parsed } = getMarkoFile(doc);
1641
+ const offset = getInsertModuleStatementOffset(parsed);
1642
+ const start = parsed.positionAt(offset);
1643
+ range = {
1644
+ start,
1645
+ end: start
1646
+ };
1647
+ insertModuleStatementLocCache.set(extracted, range);
1589
1648
  }
1649
+ } else {
1650
+ range = sourceLocationAtTextSpan(extracted, span);
1590
1651
  }
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
- }
1652
+ if (range) {
1653
+ textEdits.push({ newText, range });
1607
1654
  }
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);
1615
1655
  }
1616
- };
1656
+ }
1617
1657
  }
1618
- };
1619
- }
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";
1633
- };
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);
1658
+ return item;
1659
+ },
1660
+ findDefinition(doc, params) {
1661
+ const fileName = getFSPath(doc);
1662
+ if (!fileName)
1663
+ return;
1664
+ const project = getTSProject(fileName);
1665
+ const extracted = processScript(doc, project);
1666
+ const sourceOffset = doc.offsetAt(params.position);
1667
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1668
+ if (generatedOffset === void 0)
1669
+ return;
1670
+ const boundary = project.service.getDefinitionAndBoundSpan(
1671
+ fileName,
1672
+ generatedOffset
1673
+ );
1674
+ if (!(boundary == null ? void 0 : boundary.definitions))
1675
+ return;
1676
+ const originSelectionRange = sourceLocationAtTextSpan(
1677
+ extracted,
1678
+ boundary.textSpan
1679
+ );
1680
+ let result;
1681
+ for (const def of boundary.definitions) {
1682
+ const targetUri = filenameToURI(def.fileName);
1683
+ const defDoc = get(targetUri);
1684
+ if (!defDoc)
1685
+ continue;
1686
+ let link;
1687
+ if (markoFileReg.test(targetUri)) {
1688
+ const extracted2 = processScript(defDoc, project);
1689
+ const targetSelectionRange = sourceLocationAtTextSpan(extracted2, def.textSpan) || START_LOCATION;
1690
+ const targetRange = def.contextSpan && sourceLocationAtTextSpan(extracted2, def.contextSpan) || START_LOCATION;
1691
+ link = {
1692
+ targetUri,
1693
+ targetRange,
1694
+ targetSelectionRange,
1695
+ originSelectionRange
1696
+ };
1697
+ } else {
1698
+ link = {
1699
+ targetUri,
1700
+ targetRange: def.contextSpan ? docLocationAtTextSpan(defDoc, def.contextSpan) : START_LOCATION,
1701
+ targetSelectionRange: docLocationAtTextSpan(defDoc, def.textSpan),
1702
+ originSelectionRange
1703
+ };
1704
+ }
1705
+ if (link) {
1706
+ if (result) {
1707
+ if (Array.isArray(result)) {
1708
+ result.push(link);
1709
+ } else {
1710
+ result = [result, link];
1641
1711
  }
1712
+ } else {
1713
+ result = link;
1642
1714
  }
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
- }
1715
+ }
1716
+ }
1717
+ return result;
1718
+ },
1719
+ doHover(doc, params) {
1720
+ const fileName = getFSPath(doc);
1721
+ if (!fileName)
1722
+ return;
1723
+ const project = getTSProject(fileName);
1724
+ const extracted = processScript(doc, project);
1725
+ const sourceOffset = doc.offsetAt(params.position);
1726
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1727
+ if (generatedOffset === void 0)
1728
+ return;
1729
+ const quickInfo = project.service.getQuickInfoAtPosition(
1730
+ fileName,
1731
+ generatedOffset
1732
+ );
1733
+ if (!quickInfo)
1734
+ return;
1735
+ const sourceRange = sourceLocationAtTextSpan(extracted, quickInfo.textSpan);
1736
+ if (!sourceRange)
1737
+ return;
1738
+ let contents = "";
1739
+ const displayParts = import_tsserverlibrary.default.displayPartsToString(quickInfo.displayParts);
1740
+ if (displayParts) {
1741
+ contents += `\`\`\`typescript
1742
+ ${displayParts}
1743
+ \`\`\``;
1744
+ }
1745
+ const documentation = printDocumentation(
1746
+ quickInfo.documentation,
1747
+ quickInfo.tags
1748
+ );
1749
+ if (documentation) {
1750
+ contents += `
1751
+ ---
1752
+ ${documentation}`;
1753
+ }
1754
+ return {
1755
+ range: sourceRange,
1756
+ contents
1757
+ };
1758
+ },
1759
+ doRename(doc, params) {
1760
+ const fileName = getFSPath(doc);
1761
+ if (!fileName)
1762
+ return;
1763
+ const project = getTSProject(fileName);
1764
+ const extracted = processScript(doc, project);
1765
+ const sourceOffset = doc.offsetAt(params.position);
1766
+ const generatedOffset = extracted.generatedOffsetAt(sourceOffset);
1767
+ if (generatedOffset === void 0)
1768
+ return;
1769
+ const renameLocations = project.service.findRenameLocations(
1770
+ fileName,
1771
+ generatedOffset,
1772
+ false,
1773
+ false,
1774
+ false
1775
+ );
1776
+ if (!renameLocations)
1777
+ return;
1778
+ const changes = {};
1779
+ for (const rename of renameLocations) {
1780
+ const renameURI = filenameToURI(rename.fileName);
1781
+ const renameDoc = get(renameURI);
1782
+ let edit;
1783
+ if (!renameDoc)
1784
+ continue;
1785
+ if (markoFileReg.test(renameURI)) {
1786
+ const extracted2 = processScript(renameDoc, project);
1787
+ const sourceRange = sourceLocationAtTextSpan(
1788
+ extracted2,
1789
+ rename.textSpan
1790
+ );
1791
+ if (sourceRange) {
1792
+ edit = {
1793
+ newText: params.newName,
1794
+ range: sourceRange
1795
+ };
1796
+ }
1797
+ } else {
1798
+ edit = {
1799
+ newText: params.newName,
1800
+ range: docLocationAtTextSpan(renameDoc, rename.textSpan)
1801
+ };
1802
+ }
1803
+ if (edit) {
1804
+ if (changes[renameURI]) {
1805
+ changes[renameURI].push(edit);
1806
+ } else {
1807
+ changes[renameURI] = [edit];
1808
+ }
1809
+ }
1810
+ }
1811
+ return {
1812
+ changes
1813
+ };
1814
+ },
1815
+ doValidate(doc) {
1816
+ const fileName = getFSPath(doc);
1817
+ if (!fileName)
1818
+ return;
1819
+ const project = getTSProject(fileName);
1820
+ const extracted = processScript(doc, project);
1821
+ let results;
1822
+ for (const tsDiag of project.service.getSuggestionDiagnostics(fileName)) {
1823
+ addDiag(tsDiag);
1824
+ }
1825
+ for (const tsDiag of project.service.getSyntacticDiagnostics(fileName)) {
1826
+ addDiag(tsDiag);
1827
+ }
1828
+ for (const tsDiag of project.service.getSemanticDiagnostics(fileName)) {
1829
+ addDiag(tsDiag);
1830
+ }
1831
+ return results;
1832
+ function addDiag(tsDiag) {
1833
+ const diag = convertDiag(extracted, tsDiag);
1834
+ if (diag && !IGNORE_DIAG_REG.test(diag.message)) {
1835
+ if (results) {
1836
+ results.push(diag);
1837
+ } else {
1838
+ results = [diag];
1839
+ }
1840
+ }
1841
+ }
1842
+ }
1843
+ };
1844
+ function processScript(doc, tsProject) {
1845
+ return processDoc(doc, ({ parsed, filename, project: markoProject }) => {
1846
+ var _a;
1847
+ const { lookup } = markoProject;
1848
+ const { host, markoScriptLang } = tsProject;
1849
+ return (0, import_language_tools14.extractScript)({
1850
+ ts: import_tsserverlibrary.default,
1851
+ parsed,
1852
+ lookup,
1853
+ scriptLang: getScriptLang(filename, import_tsserverlibrary.default, host, markoScriptLang),
1854
+ runtimeTypesCode: (_a = getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode,
1855
+ componentFilename: getComponentFilename(filename, host)
1856
+ });
1857
+ });
1858
+ }
1859
+ function getInsertModuleStatementOffset(parsed) {
1860
+ const { program } = parsed;
1861
+ let firstNode;
1862
+ if (program.static.length) {
1863
+ let lastImport;
1864
+ for (const node of program.static) {
1865
+ switch (node.type) {
1866
+ case import_language_tools14.NodeType.Export:
1867
+ return node.start;
1868
+ case import_language_tools14.NodeType.Import:
1869
+ lastImport = node;
1870
+ break;
1871
+ }
1872
+ }
1873
+ if (lastImport) {
1874
+ return lastImport.end + 1;
1875
+ }
1876
+ firstNode = program.static[0];
1877
+ }
1878
+ if (program.body.length) {
1879
+ if (!firstNode || firstNode.start > program.body[0].start) {
1880
+ firstNode = program.body[0];
1881
+ }
1882
+ }
1883
+ if (firstNode) {
1884
+ return getOffsetAfterComments(firstNode);
1885
+ }
1886
+ return 0;
1887
+ }
1888
+ function getOffsetAfterComments(node) {
1889
+ const { comments } = node;
1890
+ if (comments) {
1891
+ return comments.at(-1).end + 1;
1892
+ }
1893
+ return Math.max(0, node.start - 1);
1894
+ }
1895
+ function sourceLocationAtTextSpan(extracted, { start, length }) {
1896
+ if (start === 0 && length === 0)
1897
+ return START_LOCATION;
1898
+ return extracted.sourceLocationAt(start, start + length);
1899
+ }
1900
+ function docLocationAtTextSpan(doc, { start, length }) {
1901
+ return {
1902
+ start: doc.positionAt(start),
1903
+ end: doc.positionAt(start + length)
1904
+ };
1905
+ }
1906
+ function getTSProject(docFsPath) {
1907
+ var _a;
1908
+ let configPath;
1909
+ let markoScriptLang = import_language_tools14.ScriptLang.js;
1910
+ if (docFsPath) {
1911
+ configPath = import_tsserverlibrary.default.findConfigFile(
1912
+ docFsPath,
1913
+ import_tsserverlibrary.default.sys.fileExists,
1914
+ "tsconfig.json"
1915
+ );
1916
+ if (configPath) {
1917
+ markoScriptLang = import_language_tools14.ScriptLang.ts;
1918
+ } else {
1919
+ configPath = import_tsserverlibrary.default.findConfigFile(
1920
+ docFsPath,
1921
+ import_tsserverlibrary.default.sys.fileExists,
1922
+ "jsconfig.json"
1923
+ );
1924
+ }
1925
+ }
1926
+ const rootDir = configPath && import_path9.default.dirname(configPath) || process.cwd();
1927
+ const markoProject = getMarkoProject(configPath && rootDir);
1928
+ let projectCache = markoProject.cache.get(getTSProject);
1929
+ let cached;
1930
+ if (projectCache) {
1931
+ cached = projectCache.get(rootDir);
1932
+ if (cached)
1933
+ return cached;
1934
+ } else {
1935
+ projectCache = /* @__PURE__ */ new Map();
1936
+ markoProject.cache.set(getTSProject, projectCache);
1937
+ }
1938
+ const { fileNames, options, projectReferences } = import_tsserverlibrary.default.parseJsonConfigFileContent(
1939
+ configPath && import_tsserverlibrary.default.readConfigFile(configPath, import_tsserverlibrary.default.sys.readFile).config || {
1940
+ compilerOptions: { lib: ["dom", "node", "esnext"] }
1941
+ },
1942
+ import_tsserverlibrary.default.sys,
1943
+ rootDir,
1944
+ void 0,
1945
+ configPath,
1946
+ void 0,
1947
+ [
1948
+ {
1949
+ extension: ".marko",
1950
+ isMixedContent: false,
1951
+ scriptKind: import_tsserverlibrary.default.ScriptKind.Deferred
1952
+ }
1953
+ ]
1954
+ );
1955
+ const potentialGlobalFiles = new Set(
1956
+ fileNames.filter((file) => /\.[cm]?ts$/.test(file))
1957
+ );
1958
+ options.rootDir ??= rootDir;
1959
+ options.module = import_tsserverlibrary.default.ModuleKind.ESNext;
1960
+ options.moduleResolution = import_tsserverlibrary.default.ModuleResolutionKind.NodeJs;
1961
+ options.noEmit = options.allowJs = options.declaration = options.skipLibCheck = options.isolatedModules = options.resolveJsonModule = options.skipDefaultLibCheck = options.allowNonTsExtensions = true;
1962
+ const tsPkgFile = configPath && ((_a = import_tsserverlibrary.default.resolveModuleName("typescript/package.json", configPath, options, import_tsserverlibrary.default.sys).resolvedModule) == null ? void 0 : _a.resolvedFileName);
1963
+ const defaultLibFile = import_path9.default.join(
1964
+ tsPkgFile ? import_path9.default.join(tsPkgFile, "../lib") : __dirname,
1965
+ import_tsserverlibrary.default.getDefaultLibFileName(options)
1966
+ );
1967
+ const host = patch(
1968
+ import_tsserverlibrary.default,
1969
+ markoScriptLang,
1970
+ extractCache,
1971
+ {
1972
+ getNewLine() {
1973
+ return import_tsserverlibrary.default.sys.newLine;
1974
+ },
1975
+ useCaseSensitiveFileNames() {
1976
+ return import_tsserverlibrary.default.sys.useCaseSensitiveFileNames;
1977
+ },
1978
+ getCompilationSettings() {
1979
+ return options;
1980
+ },
1981
+ getCurrentDirectory() {
1982
+ return options.rootDir;
1983
+ },
1984
+ getProjectVersion() {
1985
+ return projectVersion.toString(32);
1986
+ },
1987
+ getDefaultLibFileName() {
1988
+ return defaultLibFile;
1989
+ },
1990
+ getProjectReferences() {
1991
+ return projectReferences;
1992
+ },
1993
+ resolveModuleNames(moduleNames, containingFile) {
1994
+ return moduleNames.map((moduleName) => {
1995
+ return import_tsserverlibrary.default.resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
1996
+ });
1997
+ },
1998
+ readDirectory: import_tsserverlibrary.default.sys.readDirectory,
1999
+ readFile: (filename) => {
2000
+ var _a2;
2001
+ return (_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.getText();
2002
+ },
2003
+ fileExists: (filename) => exists(filenameToURI(filename)),
2004
+ getScriptFileNames() {
2005
+ const result = new Set(potentialGlobalFiles);
2006
+ for (const doc of getAllOpen()) {
2007
+ const { scheme, fsPath } = import_vscode_uri6.URI.parse(doc.uri);
2008
+ if (scheme === "file")
2009
+ result.add(fsPath);
1654
2010
  }
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
- }
2011
+ return [...result];
2012
+ },
2013
+ getScriptVersion(filename) {
2014
+ var _a2;
2015
+ return `${((_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.version) ?? -1}`;
2016
+ },
2017
+ getScriptKind(filename) {
2018
+ switch (import_path9.default.extname(filename)) {
2019
+ case import_tsserverlibrary.default.Extension.Js:
2020
+ return import_tsserverlibrary.default.ScriptKind.JS;
2021
+ case import_tsserverlibrary.default.Extension.Jsx:
2022
+ return import_tsserverlibrary.default.ScriptKind.JSX;
2023
+ case import_tsserverlibrary.default.Extension.Ts:
2024
+ return import_tsserverlibrary.default.ScriptKind.TS;
2025
+ case import_tsserverlibrary.default.Extension.Tsx:
2026
+ return import_tsserverlibrary.default.ScriptKind.TSX;
2027
+ case import_tsserverlibrary.default.Extension.Json:
2028
+ return import_tsserverlibrary.default.ScriptKind.JSON;
2029
+ default:
2030
+ return import_tsserverlibrary.default.ScriptKind.Unknown;
1673
2031
  }
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
- }
2032
+ },
2033
+ getScriptSnapshot(filename) {
2034
+ let snapshot = snapshotCache.get(filename);
2035
+ if (!snapshot) {
2036
+ const doc = get(filenameToURI(filename));
2037
+ if (!doc)
2038
+ return;
2039
+ snapshot = import_tsserverlibrary.default.ScriptSnapshot.fromString(doc.getText());
2040
+ snapshotCache.set(filename, snapshot);
1686
2041
  }
1687
- break;
2042
+ return snapshot;
2043
+ }
1688
2044
  }
2045
+ );
2046
+ const tsProject = {
2047
+ host,
2048
+ rootDir: options.rootDir,
2049
+ service: import_tsserverlibrary.default.createLanguageService(host),
2050
+ markoProject,
2051
+ markoScriptLang,
2052
+ markoProjectTypeLibs: getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)
1689
2053
  };
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();
2054
+ projectCache.set(rootDir, tsProject);
2055
+ return tsProject;
2056
+ }
2057
+ function filenameToURI(filename) {
2058
+ return import_vscode_uri6.URI.file(filename).toString();
2059
+ }
2060
+ async function getPreferences(scriptLang) {
2061
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2062
+ const configName = scriptLang === import_language_tools14.ScriptLang.js ? "javascript" : "typescript";
2063
+ const [preferencesConfig, suggestConfig, inlayHintsConfig] = await Promise.all([
2064
+ getConfig(`${configName}.preferences`),
2065
+ getConfig(`${configName}.suggest`),
2066
+ getConfig(`${configName}.inlayHints`)
2067
+ ]);
2068
+ return {
2069
+ disableSuggestions: suggestConfig.enabled === false,
2070
+ quotePreference: preferencesConfig.quoteStyle || "auto",
2071
+ includeCompletionsForModuleExports: suggestConfig.autoImports ?? true,
2072
+ includeCompletionsForImportStatements: suggestConfig.includeCompletionsForImportStatements ?? true,
2073
+ includeCompletionsWithSnippetText: suggestConfig.includeCompletionsWithSnippetText ?? true,
2074
+ includeAutomaticOptionalChainCompletions: suggestConfig.includeAutomaticOptionalChainCompletions ?? true,
2075
+ includeCompletionsWithInsertText: true,
2076
+ includeCompletionsWithClassMemberSnippets: ((_a = suggestConfig.classMemberSnippets) == null ? void 0 : _a.enabled) ?? true,
2077
+ includeCompletionsWithObjectLiteralMethodSnippets: ((_b = suggestConfig.objectLiteralMethodSnippets) == null ? void 0 : _b.enabled) ?? true,
2078
+ useLabelDetailsInCompletionEntries: true,
2079
+ allowIncompleteCompletions: true,
2080
+ importModuleSpecifierPreference: preferencesConfig.importModuleSpecifierPreference,
2081
+ importModuleSpecifierEnding: preferencesConfig.importModuleSpecifierEnding || "auto",
2082
+ allowTextChangesInNewFiles: true,
2083
+ providePrefixAndSuffixTextForRename: true,
2084
+ includePackageJsonAutoImports: preferencesConfig.includePackageJsonAutoImports ?? true,
2085
+ provideRefactorNotApplicableReason: true,
2086
+ jsxAttributeCompletionStyle: preferencesConfig.jsxAttributeCompletionStyle ?? "auto",
2087
+ includeInlayParameterNameHints: ((_c = inlayHintsConfig.parameterNames) == null ? void 0 : _c.enabled) ?? "none",
2088
+ includeInlayParameterNameHintsWhenArgumentMatchesName: !((_d = inlayHintsConfig.parameterNames) == null ? void 0 : _d.suppressWhenArgumentMatchesName),
2089
+ includeInlayFunctionParameterTypeHints: ((_e = inlayHintsConfig.parameterTypes) == null ? void 0 : _e.enabled) ?? true,
2090
+ includeInlayVariableTypeHints: ((_f = inlayHintsConfig.variableTypes) == null ? void 0 : _f.enabled) ?? true,
2091
+ includeInlayPropertyDeclarationTypeHints: ((_g = inlayHintsConfig.propertyDeclarationTypes) == null ? void 0 : _g.enabled) ?? true,
2092
+ includeInlayFunctionLikeReturnTypeHints: ((_h = inlayHintsConfig.functionLikeReturnTypes) == null ? void 0 : _h.enabled) ?? true,
2093
+ includeInlayEnumMemberValueHints: ((_i = inlayHintsConfig.enumMemberValues) == null ? void 0 : _i.enabled) ?? true
2094
+ };
2095
+ }
2096
+ function printDocumentation(docs2, tags) {
2097
+ let result = "";
2098
+ if (docs2) {
2099
+ result += import_tsserverlibrary.default.displayPartsToString(docs2);
2100
+ }
2101
+ if (tags) {
2102
+ for (const tag of tags) {
2103
+ const text = import_tsserverlibrary.default.displayPartsToString(tag.text);
2104
+ result += `*@${tag.name}*${text ? /\n/.test(text) ? `
2105
+ ${text}` : `- ${text}` : ""}`;
2106
+ }
2107
+ }
2108
+ return result;
2109
+ }
2110
+ function convertDiag(extracted, tsDiag) {
2111
+ const sourceRange = tsDiag.start === void 0 ? START_LOCATION : sourceLocationAtTextSpan(extracted, tsDiag);
2112
+ if (sourceRange) {
2113
+ return {
2114
+ range: sourceRange,
2115
+ source: "script",
2116
+ code: tsDiag.code,
2117
+ tags: convertDiagTags(tsDiag),
2118
+ severity: convertDiagSeverity(tsDiag),
2119
+ message: import_tsserverlibrary.default.flattenDiagnosticMessageText(tsDiag.messageText, "\n")
2120
+ };
2121
+ }
2122
+ }
2123
+ function convertDiagSeverity(tsDiag) {
2124
+ switch (tsDiag.category) {
2125
+ case import_tsserverlibrary.default.DiagnosticCategory.Error:
2126
+ return import_vscode_languageserver10.DiagnosticSeverity.Error;
2127
+ case import_tsserverlibrary.default.DiagnosticCategory.Warning:
2128
+ return import_vscode_languageserver10.DiagnosticSeverity.Warning;
2129
+ case import_tsserverlibrary.default.DiagnosticCategory.Suggestion:
2130
+ return import_vscode_languageserver10.DiagnosticSeverity.Hint;
2131
+ default:
2132
+ return import_vscode_languageserver10.DiagnosticSeverity.Information;
1695
2133
  }
1696
- return resultsByExt;
2134
+ }
2135
+ function convertDiagTags(tsDiag) {
2136
+ let tags;
2137
+ if (tsDiag.reportsDeprecated) {
2138
+ tags = [import_vscode_languageserver10.DiagnosticTag.Deprecated];
2139
+ }
2140
+ if (tsDiag.reportsUnnecessary) {
2141
+ if (tags)
2142
+ tags.push(import_vscode_languageserver10.DiagnosticTag.Unnecessary);
2143
+ else
2144
+ tags = [import_vscode_languageserver10.DiagnosticTag.Unnecessary];
2145
+ }
2146
+ return tags;
2147
+ }
2148
+ function convertCompletionItemKind(kind) {
2149
+ switch (kind) {
2150
+ case import_tsserverlibrary.default.ScriptElementKind.warning:
2151
+ case import_tsserverlibrary.default.ScriptElementKind.linkText:
2152
+ return import_vscode_languageserver10.CompletionItemKind.Text;
2153
+ case import_tsserverlibrary.default.ScriptElementKind.keyword:
2154
+ case import_tsserverlibrary.default.ScriptElementKind.primitiveType:
2155
+ return import_vscode_languageserver10.CompletionItemKind.Keyword;
2156
+ case import_tsserverlibrary.default.ScriptElementKind.scriptElement:
2157
+ return import_vscode_languageserver10.CompletionItemKind.File;
2158
+ case import_tsserverlibrary.default.ScriptElementKind.directory:
2159
+ return import_vscode_languageserver10.CompletionItemKind.Folder;
2160
+ case import_tsserverlibrary.default.ScriptElementKind.label:
2161
+ case import_tsserverlibrary.default.ScriptElementKind.string:
2162
+ return import_vscode_languageserver10.CompletionItemKind.Constant;
2163
+ case import_tsserverlibrary.default.ScriptElementKind.moduleElement:
2164
+ case import_tsserverlibrary.default.ScriptElementKind.externalModuleName:
2165
+ return import_vscode_languageserver10.CompletionItemKind.Module;
2166
+ case import_tsserverlibrary.default.ScriptElementKind.typeElement:
2167
+ case import_tsserverlibrary.default.ScriptElementKind.classElement:
2168
+ case import_tsserverlibrary.default.ScriptElementKind.localClassElement:
2169
+ return import_vscode_languageserver10.CompletionItemKind.Class;
2170
+ case import_tsserverlibrary.default.ScriptElementKind.interfaceElement:
2171
+ return import_vscode_languageserver10.CompletionItemKind.Interface;
2172
+ case import_tsserverlibrary.default.ScriptElementKind.enumElement:
2173
+ return import_vscode_languageserver10.CompletionItemKind.Enum;
2174
+ case import_tsserverlibrary.default.ScriptElementKind.enumMemberElement:
2175
+ return import_vscode_languageserver10.CompletionItemKind.EnumMember;
2176
+ case import_tsserverlibrary.default.ScriptElementKind.alias:
2177
+ case import_tsserverlibrary.default.ScriptElementKind.letElement:
2178
+ case import_tsserverlibrary.default.ScriptElementKind.constElement:
2179
+ case import_tsserverlibrary.default.ScriptElementKind.variableElement:
2180
+ case import_tsserverlibrary.default.ScriptElementKind.parameterElement:
2181
+ case import_tsserverlibrary.default.ScriptElementKind.localVariableElement:
2182
+ return import_vscode_languageserver10.CompletionItemKind.Variable;
2183
+ case import_tsserverlibrary.default.ScriptElementKind.functionElement:
2184
+ case import_tsserverlibrary.default.ScriptElementKind.localFunctionElement:
2185
+ return import_vscode_languageserver10.CompletionItemKind.Function;
2186
+ case import_tsserverlibrary.default.ScriptElementKind.callSignatureElement:
2187
+ case import_tsserverlibrary.default.ScriptElementKind.memberFunctionElement:
2188
+ case import_tsserverlibrary.default.ScriptElementKind.indexSignatureElement:
2189
+ case import_tsserverlibrary.default.ScriptElementKind.constructSignatureElement:
2190
+ return import_vscode_languageserver10.CompletionItemKind.Method;
2191
+ case import_tsserverlibrary.default.ScriptElementKind.memberGetAccessorElement:
2192
+ case import_tsserverlibrary.default.ScriptElementKind.memberSetAccessorElement:
2193
+ case import_tsserverlibrary.default.ScriptElementKind.memberVariableElement:
2194
+ return import_vscode_languageserver10.CompletionItemKind.Field;
2195
+ case import_tsserverlibrary.default.ScriptElementKind.constructorImplementationElement:
2196
+ return import_vscode_languageserver10.CompletionItemKind.Constructor;
2197
+ case import_tsserverlibrary.default.ScriptElementKind.typeParameterElement:
2198
+ return import_vscode_languageserver10.CompletionItemKind.TypeParameter;
2199
+ case import_tsserverlibrary.default.ScriptElementKind.link:
2200
+ case import_tsserverlibrary.default.ScriptElementKind.linkName:
2201
+ return import_vscode_languageserver10.CompletionItemKind.Reference;
2202
+ default:
2203
+ return import_vscode_languageserver10.CompletionItemKind.Property;
2204
+ }
2205
+ }
2206
+ function getTSTriggerChar(char) {
2207
+ if (char && tsTriggerChars.has(char))
2208
+ return char;
1697
2209
  }
1698
2210
 
1699
- // src/service/stylesheet/index.ts
1700
- var cache3 = /* @__PURE__ */ new WeakMap();
2211
+ // src/service/style/index.ts
2212
+ var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
2213
+ var import_vscode_languageserver11 = require("vscode-languageserver");
2214
+ var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
2215
+ var import_language_tools15 = require("@marko/language-tools");
1701
2216
  var services = {
1702
- css: import_vscode_css_languageservice2.getCSSLanguageService,
1703
- less: import_vscode_css_languageservice2.getLESSLanguageService,
1704
- scss: import_vscode_css_languageservice2.getSCSSLanguageService
2217
+ ".css": import_vscode_css_languageservice2.getCSSLanguageService,
2218
+ ".less": import_vscode_css_languageservice2.getLESSLanguageService,
2219
+ ".scss": import_vscode_css_languageservice2.getSCSSLanguageService
1705
2220
  };
1706
2221
  var clientCapabilities;
1707
2222
  var StyleSheetService = {
@@ -1709,70 +2224,58 @@ var StyleSheetService = {
1709
2224
  clientCapabilities = params.capabilities;
1710
2225
  },
1711
2226
  async doComplete(doc, params) {
1712
- const infoByExt = getStyleSheetInfo(doc);
1713
2227
  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)
2228
+ for (const style of processStyle(doc)) {
2229
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2230
+ if (generatedPos === void 0)
1718
2231
  continue;
1719
- const { service: service2, virtualDoc } = info;
1720
- const result = await service2.doComplete2(
1721
- virtualDoc,
1722
- virtualDoc.positionAt(generatedOffset),
1723
- info.parsed,
2232
+ const result = await style.service.doComplete2(
2233
+ style.virtualDoc,
2234
+ generatedPos,
2235
+ style.parsed,
1724
2236
  { resolveReference: resolveUrl }
1725
2237
  );
1726
2238
  if (result.itemDefaults) {
1727
2239
  const { editRange } = result.itemDefaults;
1728
2240
  if (editRange) {
1729
2241
  if ("start" in editRange) {
1730
- result.itemDefaults.editRange = getSourceRange(
1731
- doc,
1732
- info,
1733
- editRange
1734
- );
2242
+ result.itemDefaults.editRange = getSourceRange(style, editRange);
1735
2243
  } else {
1736
- editRange.insert = getSourceRange(doc, info, editRange.insert);
1737
- editRange.replace = getSourceRange(doc, info, editRange.replace);
2244
+ editRange.insert = getSourceRange(style, editRange.insert);
2245
+ editRange.replace = getSourceRange(style, editRange.replace);
1738
2246
  }
1739
2247
  }
1740
2248
  }
1741
2249
  for (const item of result.items) {
1742
2250
  if (item.textEdit) {
1743
- item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
2251
+ item.textEdit = getSourceInsertReplaceEdit(style, item.textEdit);
1744
2252
  }
1745
2253
  if (item.additionalTextEdits) {
1746
2254
  item.additionalTextEdits = getSourceEdits(
1747
- doc,
1748
- info,
2255
+ style,
1749
2256
  item.additionalTextEdits
1750
2257
  );
1751
2258
  }
1752
2259
  }
1753
2260
  return result;
1754
2261
  }
1755
- return import_vscode_languageserver14.CompletionList.create([], true);
1756
2262
  },
1757
2263
  findDefinition(doc, params) {
1758
- const infoByExt = getStyleSheetInfo(doc);
1759
2264
  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)
2265
+ for (const style of processStyle(doc)) {
2266
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2267
+ if (generatedPos === void 0)
1764
2268
  continue;
1765
- const { service: service2, virtualDoc } = info;
1766
- const result = service2.findDefinition(
1767
- virtualDoc,
1768
- virtualDoc.positionAt(generatedOffset),
1769
- info.parsed
2269
+ const result = style.service.findDefinition(
2270
+ style.virtualDoc,
2271
+ generatedPos,
2272
+ style.parsed
1770
2273
  );
1771
2274
  if (result) {
1772
- const range = getSourceRange(doc, info, result.range);
1773
- if (range) {
2275
+ const sourceRange = getSourceRange(style, result.range);
2276
+ if (sourceRange) {
1774
2277
  return {
1775
- range,
2278
+ range: sourceRange,
1776
2279
  uri: doc.uri
1777
2280
  };
1778
2281
  }
@@ -1781,24 +2284,21 @@ var StyleSheetService = {
1781
2284
  }
1782
2285
  },
1783
2286
  findReferences(doc, params) {
1784
- const infoByExt = getStyleSheetInfo(doc);
1785
2287
  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)
2288
+ for (const style of processStyle(doc)) {
2289
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2290
+ if (generatedPos === void 0)
1790
2291
  continue;
1791
- const { service: service2, virtualDoc } = info;
1792
2292
  const result = [];
1793
- for (const location of service2.findReferences(
1794
- virtualDoc,
1795
- virtualDoc.positionAt(generatedOffset),
1796
- info.parsed
2293
+ for (const location of style.service.findReferences(
2294
+ style.virtualDoc,
2295
+ generatedPos,
2296
+ style.parsed
1797
2297
  )) {
1798
- const range = getSourceRange(doc, info, location.range);
1799
- if (range) {
2298
+ const sourceRange = getSourceRange(style, location.range);
2299
+ if (sourceRange) {
1800
2300
  result.push({
1801
- range,
2301
+ range: sourceRange,
1802
2302
  uri: location.uri
1803
2303
  });
1804
2304
  }
@@ -1807,25 +2307,22 @@ var StyleSheetService = {
1807
2307
  }
1808
2308
  },
1809
2309
  findDocumentSymbols(doc) {
1810
- const infoByExt = getStyleSheetInfo(doc);
1811
2310
  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
2311
+ for (const extracted of processStyle(doc)) {
2312
+ for (const symbol of extracted.service.findDocumentSymbols(
2313
+ extracted.virtualDoc,
2314
+ extracted.parsed
1818
2315
  )) {
1819
2316
  if (symbol.location.uri === doc.uri) {
1820
- const range = getSourceRange(doc, info, symbol.location.range);
1821
- if (range) {
2317
+ const sourceRange = getSourceRange(extracted, symbol.location.range);
2318
+ if (sourceRange) {
1822
2319
  result.push({
1823
2320
  kind: symbol.kind,
1824
2321
  name: symbol.name,
1825
2322
  tags: symbol.tags,
1826
2323
  deprecated: symbol.deprecated,
1827
2324
  containerName: symbol.containerName,
1828
- location: { uri: doc.uri, range }
2325
+ location: { uri: doc.uri, range: sourceRange }
1829
2326
  });
1830
2327
  }
1831
2328
  } else {
@@ -1836,20 +2333,17 @@ var StyleSheetService = {
1836
2333
  return result.length ? result : void 0;
1837
2334
  },
1838
2335
  async findDocumentLinks(doc) {
1839
- const infoByExt = getStyleSheetInfo(doc);
1840
2336
  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,
2337
+ for (const extracted of processStyle(doc)) {
2338
+ for (const link of await extracted.service.findDocumentLinks2(
2339
+ extracted.virtualDoc,
2340
+ extracted.parsed,
1847
2341
  { resolveReference: resolveUrl }
1848
2342
  )) {
1849
- const range = getSourceRange(doc, info, link.range);
1850
- if (range) {
2343
+ const sourceRange = getSourceRange(extracted, link.range);
2344
+ if (sourceRange) {
1851
2345
  result.push({
1852
- range,
2346
+ range: sourceRange,
1853
2347
  target: link.target,
1854
2348
  tooltip: link.tooltip,
1855
2349
  data: link.data
@@ -1860,24 +2354,21 @@ var StyleSheetService = {
1860
2354
  return result.length ? result : void 0;
1861
2355
  },
1862
2356
  findDocumentHighlights(doc, params) {
1863
- const infoByExt = getStyleSheetInfo(doc);
1864
2357
  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)
2358
+ for (const style of processStyle(doc)) {
2359
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2360
+ if (generatedPos === void 0)
1869
2361
  continue;
1870
- const { service: service2, virtualDoc } = info;
1871
2362
  const result = [];
1872
- for (const highlight of service2.findDocumentHighlights(
1873
- virtualDoc,
1874
- virtualDoc.positionAt(generatedOffset),
1875
- info.parsed
2363
+ for (const highlight of style.service.findDocumentHighlights(
2364
+ style.virtualDoc,
2365
+ generatedPos,
2366
+ style.parsed
1876
2367
  )) {
1877
- const range = getSourceRange(doc, info, highlight.range);
1878
- if (range) {
2368
+ const sourceRange = getSourceRange(style, highlight.range);
2369
+ if (sourceRange) {
1879
2370
  result.push({
1880
- range,
2371
+ range: sourceRange,
1881
2372
  kind: highlight.kind
1882
2373
  });
1883
2374
  }
@@ -1886,19 +2377,16 @@ var StyleSheetService = {
1886
2377
  }
1887
2378
  },
1888
2379
  findDocumentColors(doc) {
1889
- const infoByExt = getStyleSheetInfo(doc);
1890
2380
  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
2381
+ for (const extracted of processStyle(doc)) {
2382
+ for (const colorInfo of extracted.service.findDocumentColors(
2383
+ extracted.virtualDoc,
2384
+ extracted.parsed
1897
2385
  )) {
1898
- const range = getSourceRange(doc, info, colorInfo.range);
1899
- if (range) {
2386
+ const sourceRange = getSourceRange(extracted, colorInfo.range);
2387
+ if (sourceRange) {
1900
2388
  result.push({
1901
- range,
2389
+ range: sourceRange,
1902
2390
  color: colorInfo.color
1903
2391
  });
1904
2392
  }
@@ -1907,31 +2395,19 @@ var StyleSheetService = {
1907
2395
  return result.length ? result : void 0;
1908
2396
  },
1909
2397
  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)
2398
+ for (const extracted of processStyle(doc)) {
2399
+ const generatedRange = getGeneratedRange(doc, extracted, params.range);
2400
+ if (generatedRange === void 0)
1916
2401
  continue;
1917
- const generatedOffsetEnd = info.generatedOffsetAt(
1918
- doc.offsetAt(params.range.end)
1919
- );
1920
- if (generatedOffsetEnd === void 0)
1921
- continue;
1922
- const { service: service2, virtualDoc } = info;
1923
2402
  const result = [];
1924
- for (const colorPresentation of service2.getColorPresentations(
1925
- virtualDoc,
1926
- info.parsed,
2403
+ for (const colorPresentation of extracted.service.getColorPresentations(
2404
+ extracted.virtualDoc,
2405
+ extracted.parsed,
1927
2406
  params.color,
1928
- import_vscode_languageserver14.Range.create(
1929
- virtualDoc.positionAt(generatedOffsetStart),
1930
- virtualDoc.positionAt(generatedOffsetEnd)
1931
- )
2407
+ generatedRange
1932
2408
  )) {
1933
- const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1934
- const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
2409
+ const textEdit = colorPresentation.textEdit && getSourceEdit(extracted, colorPresentation.textEdit);
2410
+ const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(extracted, colorPresentation.additionalTextEdits);
1935
2411
  if (textEdit || additionalTextEdits) {
1936
2412
  result.push({
1937
2413
  label: colorPresentation.label,
@@ -1944,25 +2420,22 @@ var StyleSheetService = {
1944
2420
  }
1945
2421
  },
1946
2422
  doHover(doc, params) {
1947
- const infoByExt = getStyleSheetInfo(doc);
1948
2423
  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)
2424
+ for (const style of processStyle(doc)) {
2425
+ const generatedPos = style.extracted.generatedPositionAt(sourceOffset);
2426
+ if (generatedPos === void 0)
1953
2427
  continue;
1954
- const { service: service2, virtualDoc } = info;
1955
- const result = service2.doHover(
1956
- virtualDoc,
1957
- virtualDoc.positionAt(generatedOffset),
1958
- info.parsed
2428
+ const result = style.service.doHover(
2429
+ style.virtualDoc,
2430
+ generatedPos,
2431
+ style.parsed
1959
2432
  );
1960
2433
  if (result) {
1961
2434
  if (result.range) {
1962
- const range = getSourceRange(doc, info, result.range);
1963
- if (range) {
2435
+ const sourceRange = getSourceRange(style, result.range);
2436
+ if (sourceRange) {
1964
2437
  return {
1965
- range,
2438
+ range: sourceRange,
1966
2439
  contents: result.contents
1967
2440
  };
1968
2441
  }
@@ -1973,32 +2446,29 @@ var StyleSheetService = {
1973
2446
  }
1974
2447
  },
1975
2448
  async doRename(doc, params) {
1976
- const infoByExt = getStyleSheetInfo(doc);
1977
2449
  const sourceOffset = doc.offsetAt(params.position);
1978
- for (const ext in infoByExt) {
1979
- const info = infoByExt[ext];
1980
- const generatedOffset = info.generatedOffsetAt(sourceOffset);
2450
+ for (const style of processStyle(doc)) {
2451
+ const generatedOffset = style.extracted.generatedOffsetAt(sourceOffset);
1981
2452
  if (generatedOffset === void 0)
1982
2453
  continue;
1983
- const { service: service2, virtualDoc } = info;
1984
- const result = service2.doRename(
1985
- virtualDoc,
1986
- virtualDoc.positionAt(generatedOffset),
2454
+ const result = style.service.doRename(
2455
+ style.virtualDoc,
2456
+ style.virtualDoc.positionAt(generatedOffset),
1987
2457
  params.newName,
1988
- info.parsed
2458
+ style.parsed
1989
2459
  );
1990
2460
  if (result.changes) {
1991
2461
  for (const uri in result.changes) {
1992
2462
  if (uri === doc.uri) {
1993
- result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
2463
+ result.changes[uri] = getSourceEdits(style, result.changes[uri]) || [];
1994
2464
  }
1995
2465
  }
1996
2466
  }
1997
2467
  if (result.documentChanges) {
1998
2468
  for (const change of result.documentChanges) {
1999
- if (import_vscode_languageserver14.TextDocumentEdit.is(change)) {
2469
+ if (import_vscode_languageserver11.TextDocumentEdit.is(change)) {
2000
2470
  if (change.textDocument.uri === doc.uri) {
2001
- change.edits = getSourceEdits(doc, info, change.edits) || [];
2471
+ change.edits = getSourceEdits(style, change.edits) || [];
2002
2472
  }
2003
2473
  }
2004
2474
  }
@@ -2008,49 +2478,36 @@ var StyleSheetService = {
2008
2478
  },
2009
2479
  doCodeActions(doc, params) {
2010
2480
  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)
2481
+ for (const extracted of processStyle(doc)) {
2482
+ const generatedRange = getGeneratedRange(doc, extracted, params.range);
2483
+ if (generatedRange === void 0)
2022
2484
  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
- ),
2485
+ const result = extracted.service.doCodeActions(
2486
+ extracted.virtualDoc,
2487
+ generatedRange,
2030
2488
  params.context,
2031
- info.parsed
2489
+ extracted.parsed
2032
2490
  );
2033
2491
  for (const command of result) {
2034
2492
  const edits = (_a = command.arguments) == null ? void 0 : _a[2];
2035
2493
  if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
2036
- command.arguments[2] = getSourceEdits(doc, info, edits);
2494
+ command.arguments[2] = getSourceEdits(extracted, edits);
2037
2495
  }
2038
2496
  }
2039
2497
  return result;
2040
2498
  }
2041
2499
  },
2042
2500
  doValidate(doc) {
2043
- const infoByExt = getStyleSheetInfo(doc);
2044
2501
  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
2502
+ for (const extracted of processStyle(doc)) {
2503
+ for (const diag of extracted.service.doValidation(
2504
+ extracted.virtualDoc,
2505
+ extracted.parsed
2050
2506
  )) {
2051
- const range = getSourceRange(doc, info, diag.range);
2052
- if (range) {
2053
- diag.range = range;
2507
+ const sourceRange = getSourceRange(extracted, diag.range);
2508
+ if (sourceRange) {
2509
+ diag.source = "style";
2510
+ diag.range = sourceRange;
2054
2511
  result.push(diag);
2055
2512
  }
2056
2513
  }
@@ -2058,123 +2515,112 @@ var StyleSheetService = {
2058
2515
  return result.length ? result : void 0;
2059
2516
  }
2060
2517
  };
2061
- function getSourceEdits(doc, info, edits) {
2518
+ function processStyle(doc) {
2519
+ return processDoc(doc, ({ uri, version, parsed, project: { lookup } }) => {
2520
+ var _a;
2521
+ const result = [];
2522
+ for (const [ext, extracted] of (0, import_language_tools15.extractStyle)({
2523
+ parsed,
2524
+ lookup
2525
+ })) {
2526
+ const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
2527
+ fileSystemProvider: file_system_default,
2528
+ clientCapabilities
2529
+ });
2530
+ if (service2) {
2531
+ const virtualDoc = import_vscode_languageserver_textdocument2.TextDocument.create(
2532
+ uri,
2533
+ "css",
2534
+ version,
2535
+ extracted.toString()
2536
+ );
2537
+ result.push({
2538
+ service: service2,
2539
+ extracted,
2540
+ virtualDoc,
2541
+ parsed: service2.parseStylesheet(virtualDoc)
2542
+ });
2543
+ }
2544
+ }
2545
+ return result;
2546
+ });
2547
+ }
2548
+ function getSourceEdits(extracted, edits) {
2062
2549
  const result = [];
2063
2550
  for (const edit of edits) {
2064
- const sourceEdit = getSourceEdit(doc, info, edit);
2551
+ const sourceEdit = getSourceEdit(extracted, edit);
2065
2552
  if (sourceEdit) {
2066
2553
  result.push(sourceEdit);
2067
2554
  }
2068
2555
  }
2069
2556
  return result.length ? result : void 0;
2070
2557
  }
2071
- function getSourceEdit(doc, info, textEdit) {
2072
- const range = getSourceRange(doc, info, textEdit.range);
2073
- if (range) {
2558
+ function getSourceEdit(extracted, textEdit) {
2559
+ const sourceRange = getSourceRange(extracted, textEdit.range);
2560
+ if (sourceRange) {
2074
2561
  return {
2075
2562
  newText: textEdit.newText,
2076
- range
2563
+ range: sourceRange
2077
2564
  };
2078
2565
  }
2079
2566
  }
2080
- function getSourceInsertReplaceEdit(doc, info, textEdit) {
2567
+ function getSourceInsertReplaceEdit(extracted, textEdit) {
2081
2568
  if (isTextEdit(textEdit)) {
2082
- return getSourceEdit(doc, info, textEdit);
2569
+ return getSourceEdit(extracted, textEdit);
2083
2570
  } else if (textEdit.replace) {
2084
- const range = getSourceRange(doc, info, textEdit.replace);
2085
- if (range) {
2571
+ const sourceRange = getSourceRange(extracted, textEdit.replace);
2572
+ if (sourceRange) {
2086
2573
  return {
2087
2574
  newText: textEdit.newText,
2088
- replace: range
2575
+ replace: sourceRange
2089
2576
  };
2090
2577
  }
2091
2578
  } else {
2092
- const range = getSourceRange(doc, info, textEdit.insert);
2093
- if (range) {
2579
+ const sourceRange = getSourceRange(extracted, textEdit.insert);
2580
+ if (sourceRange) {
2094
2581
  return {
2095
2582
  newText: textEdit.newText,
2096
- insert: range
2583
+ insert: sourceRange
2097
2584
  };
2098
2585
  }
2099
2586
  }
2100
2587
  }
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
- };
2588
+ function getSourceRange(style, range) {
2589
+ return style.extracted.sourceLocationAt(
2590
+ style.virtualDoc.offsetAt(range.start),
2591
+ style.virtualDoc.offsetAt(range.end)
2592
+ );
2116
2593
  }
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;
2594
+ function getGeneratedRange(doc, style, range) {
2595
+ return style.extracted.generatedLocationAt(
2596
+ doc.offsetAt(range.start),
2597
+ doc.offsetAt(range.end)
2598
+ );
2153
2599
  }
2154
2600
  function isTextEdit(edit) {
2155
2601
  return edit.range !== void 0;
2156
2602
  }
2157
2603
 
2158
2604
  // src/service/index.ts
2159
- var plugins = [marko_default, StyleSheetService];
2605
+ var REG_MARKDOWN_CHARS = /[\\`*_{}[\]<>()#+.!|-]/g;
2606
+ var plugins = [marko_default, ScriptService, StyleSheetService];
2160
2607
  var service = {
2608
+ commands: Object.assign({}, ...plugins.map(({ commands }) => commands)),
2161
2609
  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
- }));
2610
+ await Promise.allSettled(
2611
+ plugins.map((plugin) => {
2612
+ var _a;
2613
+ return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
2614
+ })
2615
+ );
2166
2616
  },
2167
2617
  async doComplete(doc, params, cancel) {
2168
- let items;
2169
2618
  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;
2619
+ const itemsByLabel = /* @__PURE__ */ new Map();
2620
+ await Promise.allSettled(
2621
+ plugins.map(async (plugin) => {
2622
+ var _a;
2623
+ const cur = await ((_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2178
2624
  if (cancel.isCancellationRequested)
2179
2625
  return;
2180
2626
  if (cur) {
@@ -2183,185 +2629,181 @@ var service = {
2183
2629
  curItems = cur;
2184
2630
  } else {
2185
2631
  curItems = cur.items;
2186
- isIncomplete || (isIncomplete = cur.isIncomplete);
2632
+ isIncomplete ||= cur.isIncomplete;
2633
+ }
2634
+ for (const item of curItems) {
2635
+ const { label } = item;
2636
+ const existingItem = itemsByLabel.get(label);
2637
+ if (existingItem) {
2638
+ if ((existingItem.sortText || label) < (item.sortText || label)) {
2639
+ itemsByLabel.set(label, item);
2640
+ }
2641
+ } else {
2642
+ itemsByLabel.set(label, item);
2643
+ }
2187
2644
  }
2188
- items = items ? items.concat(curItems) : curItems;
2189
2645
  }
2190
- }
2191
- } catch (err) {
2192
- isIncomplete = true;
2193
- displayError(err);
2646
+ })
2647
+ );
2648
+ if (cancel.isCancellationRequested)
2649
+ return;
2650
+ if (itemsByLabel.size) {
2651
+ return { items: [...itemsByLabel.values()], isIncomplete };
2194
2652
  }
2195
- if (items) {
2196
- return import_vscode_languageserver15.CompletionList.create(items, isIncomplete);
2653
+ },
2654
+ async doCompletionResolve(item, cancel) {
2655
+ var _a;
2656
+ for (const plugin of plugins) {
2657
+ try {
2658
+ const result = await ((_a = plugin.doCompletionResolve) == null ? void 0 : _a.call(plugin, item, cancel));
2659
+ if (cancel.isCancellationRequested)
2660
+ return;
2661
+ if (result)
2662
+ return result;
2663
+ } catch {
2664
+ }
2197
2665
  }
2198
2666
  },
2199
2667
  async findDefinition(doc, params, cancel) {
2200
2668
  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;
2669
+ await Promise.allSettled(
2670
+ plugins.map(async (plugin) => {
2671
+ var _a;
2672
+ const cur = await ((_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2209
2673
  if (cancel.isCancellationRequested)
2210
2674
  return;
2211
2675
  if (cur)
2212
2676
  result = (result || []).concat(cur);
2213
- }
2214
- } catch (err) {
2215
- displayError(err);
2216
- }
2677
+ })
2678
+ );
2679
+ if (cancel.isCancellationRequested)
2680
+ return;
2217
2681
  return result;
2218
2682
  },
2219
2683
  async findReferences(doc, params, cancel) {
2220
2684
  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;
2685
+ await Promise.allSettled(
2686
+ plugins.map(async (plugin) => {
2687
+ var _a;
2688
+ const cur = await ((_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2229
2689
  if (cancel.isCancellationRequested)
2230
2690
  return;
2231
2691
  if (cur)
2232
- result = result ? result.concat(cur) : cur;
2233
- }
2234
- } catch (err) {
2235
- displayError(err);
2236
- }
2692
+ result = (result || []).concat(cur);
2693
+ })
2694
+ );
2695
+ if (cancel.isCancellationRequested)
2696
+ return;
2237
2697
  return result;
2238
2698
  },
2239
2699
  async findDocumentSymbols(doc, params, cancel) {
2240
2700
  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;
2701
+ await Promise.allSettled(
2702
+ plugins.map(async (plugin) => {
2703
+ var _a;
2704
+ const cur = await ((_a = plugin.findDocumentSymbols) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2249
2705
  if (cancel.isCancellationRequested)
2250
2706
  return;
2251
2707
  if (cur)
2252
- result = result ? result.concat(cur) : cur;
2253
- }
2254
- } catch (err) {
2255
- displayError(err);
2256
- }
2708
+ result = (result || []).concat(cur);
2709
+ })
2710
+ );
2711
+ if (cancel.isCancellationRequested)
2712
+ return;
2257
2713
  return result;
2258
2714
  },
2259
2715
  async findDocumentLinks(doc, params, cancel) {
2260
2716
  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;
2717
+ await Promise.allSettled(
2718
+ plugins.map(async (plugin) => {
2719
+ var _a;
2720
+ const cur = await ((_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2269
2721
  if (cancel.isCancellationRequested)
2270
2722
  return;
2271
2723
  if (cur)
2272
- result = result ? result.concat(cur) : cur;
2273
- }
2274
- } catch (err) {
2275
- displayError(err);
2276
- }
2724
+ result = (result || []).concat(cur);
2725
+ })
2726
+ );
2727
+ if (cancel.isCancellationRequested)
2728
+ return;
2277
2729
  return result;
2278
2730
  },
2279
2731
  async findDocumentHighlights(doc, params, cancel) {
2280
2732
  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;
2733
+ await Promise.allSettled(
2734
+ plugins.map(async (plugin) => {
2735
+ var _a;
2736
+ const cur = await ((_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2289
2737
  if (cancel.isCancellationRequested)
2290
2738
  return;
2291
2739
  if (cur)
2292
- result = result ? result.concat(cur) : cur;
2293
- }
2294
- } catch (err) {
2295
- displayError(err);
2296
- }
2740
+ result = (result || []).concat(cur);
2741
+ })
2742
+ );
2743
+ if (cancel.isCancellationRequested)
2744
+ return;
2297
2745
  return result;
2298
2746
  },
2299
2747
  async findDocumentColors(doc, params, cancel) {
2300
2748
  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;
2749
+ await Promise.allSettled(
2750
+ plugins.map(async (plugin) => {
2751
+ var _a;
2752
+ const cur = await ((_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2309
2753
  if (cancel.isCancellationRequested)
2310
2754
  return;
2311
2755
  if (cur)
2312
- result = result ? result.concat(cur) : cur;
2313
- }
2314
- } catch (err) {
2315
- displayError(err);
2316
- }
2756
+ result = (result || []).concat(cur);
2757
+ })
2758
+ );
2759
+ if (cancel.isCancellationRequested)
2760
+ return;
2317
2761
  return result;
2318
2762
  },
2319
2763
  async getColorPresentations(doc, params, cancel) {
2320
2764
  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;
2765
+ await Promise.allSettled(
2766
+ plugins.map(async (plugin) => {
2767
+ var _a;
2768
+ const cur = await ((_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2329
2769
  if (cancel.isCancellationRequested)
2330
2770
  return;
2331
2771
  if (cur)
2332
- result = result ? result.concat(cur) : cur;
2333
- }
2334
- } catch (err) {
2335
- displayError(err);
2336
- }
2772
+ result = (result || []).concat(cur);
2773
+ })
2774
+ );
2775
+ if (cancel.isCancellationRequested)
2776
+ return;
2337
2777
  return result;
2338
2778
  },
2339
2779
  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));
2780
+ let result;
2781
+ await Promise.allSettled(
2782
+ plugins.map(async (plugin) => {
2783
+ var _a;
2784
+ const cur = await ((_a = plugin.doHover) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2344
2785
  if (cancel.isCancellationRequested)
2345
2786
  return;
2346
- if (result)
2347
- return result;
2348
- }
2349
- } catch (err) {
2350
- displayError(err);
2351
- }
2787
+ if (cur) {
2788
+ if (result) {
2789
+ result.range = maxRange(result.range, cur.range);
2790
+ result.contents = mergeHoverContents(result.contents, cur.contents);
2791
+ } else {
2792
+ result = cur;
2793
+ }
2794
+ }
2795
+ })
2796
+ );
2797
+ return result;
2352
2798
  },
2353
2799
  async doRename(doc, params, cancel) {
2354
2800
  let changes;
2355
2801
  let changeAnnotations;
2356
2802
  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;
2803
+ await Promise.allSettled(
2804
+ plugins.map(async (plugin) => {
2805
+ var _a;
2806
+ const cur = await ((_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2365
2807
  if (cancel.isCancellationRequested)
2366
2808
  return;
2367
2809
  if (cur) {
@@ -2385,10 +2827,10 @@ var service = {
2385
2827
  documentChanges = documentChanges ? documentChanges.concat(cur.documentChanges) : cur.documentChanges;
2386
2828
  }
2387
2829
  }
2388
- }
2389
- } catch (err) {
2390
- displayError(err);
2391
- }
2830
+ })
2831
+ );
2832
+ if (cancel.isCancellationRequested)
2833
+ return;
2392
2834
  if (changes || changeAnnotations || documentChanges) {
2393
2835
  return {
2394
2836
  changes,
@@ -2399,62 +2841,112 @@ var service = {
2399
2841
  },
2400
2842
  async doCodeActions(doc, params, cancel) {
2401
2843
  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;
2844
+ await Promise.allSettled(
2845
+ plugins.map(async (plugin) => {
2846
+ var _a;
2847
+ const cur = await ((_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel));
2410
2848
  if (cancel.isCancellationRequested)
2411
2849
  return;
2412
2850
  if (cur)
2413
- result = result ? result.concat(cur) : cur;
2414
- }
2415
- } catch (err) {
2416
- displayError(err);
2417
- }
2851
+ result = (result || []).concat(cur);
2852
+ })
2853
+ );
2854
+ if (cancel.isCancellationRequested)
2855
+ return;
2418
2856
  return result;
2419
2857
  },
2420
2858
  async doValidate(doc) {
2421
2859
  let result;
2422
- try {
2423
- for (const pending of plugins.map((plugin) => {
2860
+ await Promise.allSettled(
2861
+ plugins.map(async (plugin) => {
2424
2862
  var _a;
2425
- return (_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc);
2426
- })) {
2427
- const cur = await pending;
2863
+ const cur = await ((_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc));
2428
2864
  if (cur)
2429
- result = result ? result.concat(cur) : cur;
2430
- }
2431
- } catch (err) {
2432
- displayError(err);
2433
- }
2865
+ result = (result || []).concat(cur);
2866
+ })
2867
+ );
2434
2868
  return result;
2435
2869
  },
2436
2870
  format: marko_default.format
2437
2871
  };
2872
+ function maxRange(a, b) {
2873
+ if (!a)
2874
+ return b;
2875
+ if (!b)
2876
+ return a;
2877
+ return {
2878
+ start: {
2879
+ line: Math.min(a.start.line, b.start.line),
2880
+ character: Math.min(a.start.character, b.start.character)
2881
+ },
2882
+ end: {
2883
+ line: Math.max(a.end.line, b.end.line),
2884
+ character: Math.max(a.end.character, b.end.character)
2885
+ }
2886
+ };
2887
+ }
2888
+ function mergeHoverContents(a, b) {
2889
+ if (!a)
2890
+ return b;
2891
+ if (!b)
2892
+ return a;
2893
+ if (!import_vscode_languageserver12.MarkupContent.is(a)) {
2894
+ a = markedStringToMarkupContent(a);
2895
+ }
2896
+ if (!import_vscode_languageserver12.MarkupContent.is(b)) {
2897
+ b = markedStringToMarkupContent(b);
2898
+ }
2899
+ if (a.kind === b.kind) {
2900
+ return {
2901
+ kind: a.kind,
2902
+ value: `${a.value}
2903
+ ${b.value}`
2904
+ };
2905
+ }
2906
+ return {
2907
+ kind: import_vscode_languageserver12.MarkupKind.Markdown,
2908
+ value: `${markupContentToMarkdown(a)}
2909
+ ${markupContentToMarkdown(b)}`
2910
+ };
2911
+ }
2912
+ function markedStringToMarkupContent(markedString) {
2913
+ return {
2914
+ kind: import_vscode_languageserver12.MarkupKind.Markdown,
2915
+ value: Array.isArray(markedString) ? markedString.map((it) => markedStringToString(it)).join("\n") : markedStringToString(markedString)
2916
+ };
2917
+ }
2918
+ function markedStringToString(markedString) {
2919
+ if (typeof markedString === "string") {
2920
+ return markedString;
2921
+ }
2922
+ return `\`\`\`${markedString.language}
2923
+ ${markedString.value}
2924
+ \`\`\``;
2925
+ }
2926
+ function markupContentToMarkdown(content) {
2927
+ return content.kind === import_vscode_languageserver12.MarkupKind.Markdown ? content.value : escapeMarkdown(content.value);
2928
+ }
2929
+ function escapeMarkdown(str) {
2930
+ return str.replace(REG_MARKDOWN_CHARS, "$1");
2931
+ }
2438
2932
 
2439
2933
  // src/index.ts
2440
2934
  if (typeof require !== "undefined" && require.extensions && !(".ts" in require.extensions)) {
2441
2935
  require.extensions[".ts"] = void 0;
2442
2936
  }
2443
- var documents = new import_node.TextDocuments(import_vscode_languageserver_textdocument3.TextDocument);
2444
- var connection2 = (0, import_node.createConnection)(import_node.ProposedFeatures.all);
2937
+ var connection3 = (0, import_node.createConnection)(import_node.ProposedFeatures.all);
2445
2938
  var prevDiags = /* @__PURE__ */ new WeakMap();
2446
- var pendingDiags = /* @__PURE__ */ new WeakSet();
2447
2939
  var diagnosticTimeout;
2448
2940
  console.log = (...args) => {
2449
- connection2.console.log(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2941
+ connection3.console.log(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2450
2942
  };
2451
2943
  console.error = (...args) => {
2452
- connection2.console.error(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2944
+ connection3.console.error(args.map((v) => (0, import_util2.inspect)(v)).join(" "));
2453
2945
  };
2454
2946
  process.on("uncaughtException", console.error);
2455
2947
  process.on("unhandledRejection", console.error);
2456
- connection2.onInitialize(async (params) => {
2457
- setup(connection2);
2948
+ connection3.onInitialize(async (params) => {
2949
+ setup3(connection3);
2458
2950
  await service.initialize(params);
2459
2951
  return {
2460
2952
  capabilities: {
@@ -2470,6 +2962,7 @@ connection2.onInitialize(async (params) => {
2470
2962
  documentHighlightProvider: true,
2471
2963
  documentSymbolProvider: true,
2472
2964
  completionProvider: {
2965
+ resolveProvider: true,
2473
2966
  triggerCharacters: [
2474
2967
  ".",
2475
2968
  ":",
@@ -2495,111 +2988,123 @@ connection2.onInitialize(async (params) => {
2495
2988
  }
2496
2989
  };
2497
2990
  });
2498
- connection2.onDidChangeConfiguration(validateDocs);
2499
- connection2.onDidChangeWatchedFiles(validateDocs);
2500
- documents.onDidChangeContent(({ document }) => {
2501
- queueDiagnostic();
2502
- pendingDiags.add(document);
2503
- clearCompilerCache(document);
2991
+ setup2(connection3);
2992
+ onConfigChange(validateDocs);
2993
+ setup(connection3);
2994
+ onFileChange((changeDoc) => {
2995
+ if (changeDoc) {
2996
+ queueDiagnostic();
2997
+ getMarkoProject(getFSDir(changeDoc)).cache.delete(changeDoc);
2998
+ } else {
2999
+ validateDocs();
3000
+ }
2504
3001
  });
2505
- connection2.onCompletion(async (params, cancel) => {
3002
+ connection3.onCompletion(async (params, cancel) => {
2506
3003
  return await service.doComplete(
2507
- documents.get(params.textDocument.uri),
3004
+ get(params.textDocument.uri),
2508
3005
  params,
2509
3006
  cancel
2510
3007
  ) || null;
2511
3008
  });
2512
- connection2.onDefinition(async (params, cancel) => {
3009
+ connection3.onCompletionResolve(async (item, cancel) => {
3010
+ return await service.doCompletionResolve(item, cancel) || item;
3011
+ });
3012
+ connection3.onDefinition(async (params, cancel) => {
2513
3013
  return await service.findDefinition(
2514
- documents.get(params.textDocument.uri),
3014
+ get(params.textDocument.uri),
2515
3015
  params,
2516
3016
  cancel
2517
3017
  ) || null;
2518
3018
  });
2519
- connection2.onReferences(async (params, cancel) => {
3019
+ connection3.onReferences(async (params, cancel) => {
2520
3020
  return await service.findReferences(
2521
- documents.get(params.textDocument.uri),
3021
+ get(params.textDocument.uri),
2522
3022
  params,
2523
3023
  cancel
2524
3024
  ) || null;
2525
3025
  });
2526
- connection2.onDocumentLinks(async (params, cancel) => {
3026
+ connection3.onDocumentLinks(async (params, cancel) => {
2527
3027
  return await service.findDocumentLinks(
2528
- documents.get(params.textDocument.uri),
3028
+ get(params.textDocument.uri),
2529
3029
  params,
2530
3030
  cancel
2531
3031
  ) || null;
2532
3032
  });
2533
- connection2.onDocumentSymbol(async (params, cancel) => {
3033
+ connection3.onDocumentSymbol(async (params, cancel) => {
2534
3034
  return await service.findDocumentSymbols(
2535
- documents.get(params.textDocument.uri),
3035
+ get(params.textDocument.uri),
2536
3036
  params,
2537
3037
  cancel
2538
3038
  ) || null;
2539
3039
  });
2540
- connection2.onDocumentHighlight(async (params, cancel) => {
3040
+ connection3.onDocumentHighlight(async (params, cancel) => {
2541
3041
  return await service.findDocumentHighlights(
2542
- documents.get(params.textDocument.uri),
3042
+ get(params.textDocument.uri),
2543
3043
  params,
2544
3044
  cancel
2545
3045
  ) || null;
2546
3046
  });
2547
- connection2.onDocumentColor(async (params, cancel) => {
3047
+ connection3.onDocumentColor(async (params, cancel) => {
2548
3048
  return await service.findDocumentColors(
2549
- documents.get(params.textDocument.uri),
3049
+ get(params.textDocument.uri),
2550
3050
  params,
2551
3051
  cancel
2552
3052
  ) || null;
2553
3053
  });
2554
- connection2.onColorPresentation(async (params, cancel) => {
3054
+ connection3.onColorPresentation(async (params, cancel) => {
2555
3055
  return await service.getColorPresentations(
2556
- documents.get(params.textDocument.uri),
3056
+ get(params.textDocument.uri),
2557
3057
  params,
2558
3058
  cancel
2559
3059
  ) || null;
2560
3060
  });
2561
- connection2.onHover(async (params, cancel) => {
3061
+ connection3.onHover(async (params, cancel) => {
2562
3062
  return await service.doHover(
2563
- documents.get(params.textDocument.uri),
3063
+ get(params.textDocument.uri),
2564
3064
  params,
2565
3065
  cancel
2566
3066
  ) || null;
2567
3067
  });
2568
- connection2.onRenameRequest(async (params, cancel) => {
3068
+ connection3.onRenameRequest(async (params, cancel) => {
2569
3069
  return await service.doRename(
2570
- documents.get(params.textDocument.uri),
3070
+ get(params.textDocument.uri),
2571
3071
  params,
2572
3072
  cancel
2573
3073
  ) || null;
2574
3074
  });
2575
- connection2.onCodeAction(async (params, cancel) => {
3075
+ connection3.onCodeAction(async (params, cancel) => {
2576
3076
  return await service.doCodeActions(
2577
- documents.get(params.textDocument.uri),
3077
+ get(params.textDocument.uri),
2578
3078
  params,
2579
3079
  cancel
2580
3080
  ) || null;
2581
3081
  });
2582
- connection2.onDocumentFormatting(async (params, cancel) => {
3082
+ connection3.onDocumentFormatting(async (params, cancel) => {
2583
3083
  return await service.format(
2584
- documents.get(params.textDocument.uri),
3084
+ get(params.textDocument.uri),
2585
3085
  params,
2586
3086
  cancel
2587
3087
  ) || null;
2588
3088
  });
3089
+ for (const command in service.commands) {
3090
+ connection3.onRequest(command, service.commands[command]);
3091
+ }
2589
3092
  function validateDocs() {
2590
3093
  queueDiagnostic();
2591
- clearCompilerCache();
2592
- for (const doc of documents.all()) {
2593
- pendingDiags.add(doc);
3094
+ for (const project of getMarkoProjects()) {
3095
+ project.cache.clear();
3096
+ project.compiler.taglib.clearCaches();
2594
3097
  }
2595
3098
  }
2596
3099
  function queueDiagnostic() {
2597
3100
  clearTimeout(diagnosticTimeout);
2598
3101
  const id = diagnosticTimeout = setTimeout(async () => {
2599
3102
  const results = await Promise.all(
2600
- documents.all().map(async (doc) => {
2601
- if (!pendingDiags.delete(doc))
3103
+ Array.from(getAllOpen()).map(async (doc) => {
3104
+ if (!isOpen(doc)) {
3105
+ prevDiags.delete(doc);
2602
3106
  return;
3107
+ }
2603
3108
  const prevDiag = prevDiags.get(doc) || [];
2604
3109
  const nextDiag = await service.doValidate(doc) || [];
2605
3110
  if ((0, import_util2.isDeepStrictEqual)(prevDiag, nextDiag))
@@ -2612,7 +3117,7 @@ function queueDiagnostic() {
2612
3117
  if (result) {
2613
3118
  const [doc, diag] = result;
2614
3119
  prevDiags.set(doc, diag);
2615
- connection2.sendDiagnostics({
3120
+ connection3.sendDiagnostics({
2616
3121
  uri: doc.uri,
2617
3122
  diagnostics: diag
2618
3123
  });
@@ -2621,6 +3126,5 @@ function queueDiagnostic() {
2621
3126
  }
2622
3127
  }, 400);
2623
3128
  }
2624
- documents.listen(connection2);
2625
- connection2.listen();
3129
+ connection3.listen();
2626
3130
  //# sourceMappingURL=index.js.map