@marko/language-server 0.12.12 → 0.12.15

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.
package/dist/index.mjs CHANGED
@@ -276,12 +276,14 @@ function parse(source) {
276
276
  }
277
277
  }
278
278
  program.body.length = i + 1;
279
- program.static.push(curParent = {
280
- type: 20 /* Statement */,
281
- parent: program,
282
- start: range.start,
283
- end: UNFINISHED
284
- });
279
+ program.static.push(
280
+ curParent = {
281
+ type: 20 /* Statement */,
282
+ parent: program,
283
+ start: range.start,
284
+ end: UNFINISHED
285
+ }
286
+ );
285
287
  return curBodyType = TagType.statement;
286
288
  }
287
289
  default:
@@ -408,15 +410,18 @@ function parse(source) {
408
410
  start: range.start,
409
411
  end: range.end
410
412
  };
411
- pushAttr(parent, curAttr = name.parent = {
412
- type: 8 /* AttrNamed */,
413
+ pushAttr(
413
414
  parent,
414
- name,
415
- value: void 0,
416
- args: void 0,
417
- start: range.start,
418
- end: range.end
419
- });
415
+ curAttr = name.parent = {
416
+ type: 8 /* AttrNamed */,
417
+ parent,
418
+ name,
419
+ value: void 0,
420
+ args: void 0,
421
+ start: range.start,
422
+ end: range.end
423
+ }
424
+ );
420
425
  },
421
426
  onAttrArgs(range) {
422
427
  curAttr.args = {
@@ -571,12 +576,16 @@ function loadCompilerInfo(dir) {
571
576
  const rootDir = lassoPackageRoot.getRootDir(dir);
572
577
  const pkgPath = rootDir && resolveFrom.silent(rootDir, "@marko/compiler/package.json");
573
578
  const pkg = pkgPath && __require(pkgPath);
574
- const cache3 = /* @__PURE__ */ new Map();
579
+ const cache4 = /* @__PURE__ */ new Map();
575
580
  let translator = builtinTranslator;
576
581
  let compiler = builtinCompiler;
577
582
  if (pkg && /^5\./.test(pkg.version)) {
578
583
  try {
579
- let checkTranslator = [].concat(Object.keys(pkg.dependencies), Object.keys(pkg.peerDependencies), Object.keys(pkg.devDependencies)).find((name) => /^marko$|^(@\/marko\/|marko-)translator-/.test(name));
584
+ let checkTranslator = [].concat(
585
+ Object.keys(pkg.dependencies),
586
+ Object.keys(pkg.peerDependencies),
587
+ Object.keys(pkg.devDependencies)
588
+ ).find((name) => /^marko$|^(@\/marko\/|marko-)translator-/.test(name));
580
589
  if (checkTranslator === "marko" || !checkTranslator) {
581
590
  checkTranslator = __require(resolveFrom(dir, "@marko/compiler/config")).translator;
582
591
  }
@@ -588,16 +597,16 @@ function loadCompilerInfo(dir) {
588
597
  }
589
598
  }
590
599
  return {
591
- cache: cache3,
600
+ cache: cache4,
592
601
  get lookup() {
593
- let lookup = cache3.get(lookupKey);
602
+ let lookup = cache4.get(lookupKey);
594
603
  if (lookup === void 0) {
595
604
  try {
596
605
  lookup = compiler.taglib.buildLookup(dir, translator);
597
606
  } catch {
598
607
  lookup = builtinInfo.lookup;
599
608
  }
600
- cache3.set(lookupKey, lookup);
609
+ cache4.set(lookupKey, lookup);
601
610
  }
602
611
  return lookup;
603
612
  },
@@ -665,10 +674,13 @@ ${closingTagStr}`
665
674
  label: closingTagStr,
666
675
  kind: CompletionItemKind.Class,
667
676
  insertTextFormat: InsertTextFormat.Snippet,
668
- textEdit: TextEdit.replace(parsed.locationAt({
669
- start,
670
- end
671
- }), closingTagStr)
677
+ textEdit: TextEdit.replace(
678
+ parsed.locationAt({
679
+ start,
680
+ end
681
+ }),
682
+ closingTagStr
683
+ )
672
684
  }
673
685
  ];
674
686
  }
@@ -695,12 +707,14 @@ function getTagNameCompletion({
695
707
  let label = tag.isNestedTag ? `@${tag.name}` : tag.name;
696
708
  const fileForTag = tag.template || tag.renderer || tag.filePath;
697
709
  const fileURIForTag = URI2.file(fileForTag).toString();
698
- const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
710
+ const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(
711
+ fileForTag
712
+ );
699
713
  const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
700
- const isCoreTag = nodeModuleName === "marko";
714
+ const isCoreTag = /^@?marko[/-]/.test(tag.taglibId) || nodeModuleName === "marko";
701
715
  const documentation = {
702
716
  kind: MarkupKind.Markdown,
703
- value: tag.html ? `Built in [<${tag.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : nodeModuleName ? isCoreTag ? `Core Marko [<${tag.name}>](${fileURIForTag}) tag.` : `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
717
+ 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:
704
718
 
705
719
  [${importer ? path2.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
706
720
  };
@@ -758,12 +772,14 @@ function OpenTagName({
758
772
  for (const key in nestedTags) {
759
773
  if (key !== "*") {
760
774
  const tag2 = nestedTags[key];
761
- result.push(getTagNameCompletion({
762
- tag: tag2,
763
- range,
764
- importer,
765
- showAutoComplete: true
766
- }));
775
+ result.push(
776
+ getTagNameCompletion({
777
+ tag: tag2,
778
+ range,
779
+ importer,
780
+ showAutoComplete: true
781
+ })
782
+ );
767
783
  }
768
784
  }
769
785
  }
@@ -771,12 +787,14 @@ function OpenTagName({
771
787
  const skipStatements = !(tag.concise && tag.parent.type === 0 /* Program */);
772
788
  for (const tag2 of lookup.getTagsSorted()) {
773
789
  if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
774
- result.push(getTagNameCompletion({
775
- tag: tag2,
776
- range,
777
- importer,
778
- showAutoComplete: true
779
- }));
790
+ result.push(
791
+ getTagNameCompletion({
792
+ tag: tag2,
793
+ range,
794
+ importer,
795
+ showAutoComplete: true
796
+ })
797
+ );
780
798
  }
781
799
  }
782
800
  }
@@ -820,10 +838,12 @@ function AttrName({
820
838
  }
821
839
  }
822
840
  const completions = [];
823
- const attrNameLoc = parsed.locationAt(hasModifier ? {
824
- start: node.start,
825
- end: node.start + name.length
826
- } : node);
841
+ const attrNameLoc = parsed.locationAt(
842
+ hasModifier ? {
843
+ start: node.start,
844
+ end: node.start + name.length
845
+ } : node
846
+ );
827
847
  const tagName = node.parent.parent.nameText || "";
828
848
  const tagDef = tagName && lookup.getTag(tagName);
829
849
  const nestedTagAttrs = {};
@@ -961,7 +981,11 @@ async function readDirectory(uri) {
961
981
  try {
962
982
  const entries = await fs.readdir(fileURLToPath(uri));
963
983
  const base = uri.at(-1) === "/" ? uri : `${uri}/`;
964
- return (await Promise.all(entries.map(async (entry) => [entry, (await stat(new URL(entry, base).toString())).type]))).filter(([, type]) => type !== FileType.Unknown);
984
+ return (await Promise.all(
985
+ entries.map(
986
+ async (entry) => [entry, (await stat(new URL(entry, base).toString())).type]
987
+ )
988
+ )).filter(([, type]) => type !== FileType.Unknown);
965
989
  } catch {
966
990
  return [];
967
991
  }
@@ -1005,22 +1029,27 @@ async function AttrValue({
1005
1029
  if (uri) {
1006
1030
  const result = [];
1007
1031
  const curFile = req === "." ? path3.basename(document.uri) : void 0;
1008
- const replaceRange = Range2.create(document.positionAt(start + segmentStart + 1), document.positionAt(start + rawValue.length));
1032
+ const replaceRange = Range2.create(
1033
+ document.positionAt(start + segmentStart + 1),
1034
+ document.positionAt(start + rawValue.length)
1035
+ );
1009
1036
  for (const [entry, type] of await file_system_default.readDirectory(uri)) {
1010
1037
  if (entry[0] !== "." && entry !== curFile) {
1011
- result.push(type === FileType.Directory ? {
1012
- label: `${entry}/`,
1013
- kind: CompletionItemKind4.Folder,
1014
- textEdit: TextEdit4.replace(replaceRange, `${entry}/`),
1015
- command: {
1016
- title: "Suggest",
1017
- command: "editor.action.triggerSuggest"
1038
+ result.push(
1039
+ type === FileType.Directory ? {
1040
+ label: `${entry}/`,
1041
+ kind: CompletionItemKind4.Folder,
1042
+ textEdit: TextEdit4.replace(replaceRange, `${entry}/`),
1043
+ command: {
1044
+ title: "Suggest",
1045
+ command: "editor.action.triggerSuggest"
1046
+ }
1047
+ } : {
1048
+ label: entry,
1049
+ kind: CompletionItemKind4.File,
1050
+ textEdit: TextEdit4.replace(replaceRange, entry)
1018
1051
  }
1019
- } : {
1020
- label: entry,
1021
- kind: CompletionItemKind4.File,
1022
- textEdit: TextEdit4.replace(replaceRange, entry)
1023
- });
1052
+ );
1024
1053
  }
1025
1054
  }
1026
1055
  return result;
@@ -1080,48 +1109,128 @@ var doComplete = async (doc, params) => {
1080
1109
  const parsed = parse2(doc);
1081
1110
  const offset = doc.offsetAt(params.position);
1082
1111
  const node = parsed.nodeAt(offset);
1083
- return CompletionList.create(await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
1084
- document: doc,
1085
- params,
1086
- parsed,
1087
- offset,
1088
- node,
1089
- code: doc.getText(),
1090
- ...getCompilerInfo(doc)
1091
- })) || [], true);
1112
+ return CompletionList.create(
1113
+ await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
1114
+ document: doc,
1115
+ params,
1116
+ parsed,
1117
+ offset,
1118
+ node,
1119
+ code: doc.getText(),
1120
+ ...getCompilerInfo(doc)
1121
+ })) || [],
1122
+ true
1123
+ );
1092
1124
  };
1093
1125
 
1094
1126
  // src/service/marko/validate.ts
1095
- import { Diagnostic, DiagnosticSeverity, Range as Range3 } from "vscode-languageserver";
1096
- var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
1127
+ import { DiagnosticSeverity } from "vscode-languageserver";
1128
+ var markoErrorRegExp = /^(.+?)\.marko(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
1097
1129
  var doValidate = (doc) => {
1098
1130
  const fsPath = getDocFile(doc);
1099
1131
  const diagnostics = [];
1100
- const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
1132
+ const { compiler, translator, cache: cache4 } = getCompilerInfo(doc);
1101
1133
  try {
1102
1134
  compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
1103
- cache: cache3,
1135
+ cache: cache4,
1104
1136
  translator,
1105
1137
  code: false,
1106
1138
  output: "source",
1107
- sourceMaps: false
1139
+ sourceMaps: false,
1140
+ babelConfig: {
1141
+ caller: {
1142
+ name: "@marko/language-server",
1143
+ supportsStaticESM: true,
1144
+ supportsDynamicImport: true,
1145
+ supportsTopLevelAwait: true,
1146
+ supportsExportNamespaceFrom: true
1147
+ }
1148
+ }
1108
1149
  });
1109
1150
  } catch (e) {
1110
1151
  let match;
1111
1152
  while (match = markoErrorRegExp.exec(e.message)) {
1112
- const [, fileName, rawLine, rawCol, msg] = match;
1113
- const line = (parseInt(rawLine, 10) || 1) - 1;
1114
- const col = (parseInt(rawCol, 10) || 1) - 1;
1115
- diagnostics.push(Diagnostic.create(Range3.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
1153
+ const [, , rawLine, rawCol, message] = match;
1154
+ const pos = {
1155
+ line: (parseInt(rawLine, 10) || 1) - 1,
1156
+ character: (parseInt(rawCol, 10) || 1) - 1
1157
+ };
1158
+ diagnostics.push({
1159
+ range: { start: pos, end: pos },
1160
+ source: "marko",
1161
+ code: void 0,
1162
+ tags: void 0,
1163
+ severity: DiagnosticSeverity.Error,
1164
+ message
1165
+ });
1116
1166
  }
1117
1167
  }
1118
1168
  return diagnostics;
1119
1169
  };
1120
1170
 
1171
+ // src/utils/utils.ts
1172
+ import fs2 from "fs";
1173
+ import { URI as URI3 } from "vscode-uri";
1174
+ import { Position, Range as Range3 } from "vscode-languageserver";
1175
+ import { TextDocument } from "vscode-languageserver-textdocument";
1176
+ var START_OF_FILE = Range3.create(
1177
+ Position.create(0, 0),
1178
+ Position.create(0, 0)
1179
+ );
1180
+ function createTextDocument(filename) {
1181
+ const uri = URI3.file(filename).toString();
1182
+ const content = fs2.readFileSync(filename, "utf-8");
1183
+ return TextDocument.create(uri, "plaintext", 0, content);
1184
+ }
1185
+
1186
+ // src/service/marko/hover/OpenTagName.ts
1187
+ function OpenTagName2({
1188
+ document,
1189
+ lookup,
1190
+ parsed,
1191
+ node
1192
+ }) {
1193
+ const importer = getDocFile(document);
1194
+ const tag = node.parent;
1195
+ const range = parsed.locationAt(node);
1196
+ const tagDef = tag.nameText && lookup.getTag(tag.nameText);
1197
+ if (tagDef) {
1198
+ const completion = getTagNameCompletion({
1199
+ tag: tagDef,
1200
+ range: START_OF_FILE,
1201
+ importer
1202
+ });
1203
+ return {
1204
+ range,
1205
+ contents: completion.documentation
1206
+ };
1207
+ }
1208
+ }
1209
+
1210
+ // src/service/marko/hover/index.ts
1211
+ var handlers2 = {
1212
+ OpenTagName: OpenTagName2
1213
+ };
1214
+ var doHover = async (doc, params) => {
1215
+ var _a;
1216
+ const parsed = parse2(doc);
1217
+ const offset = doc.offsetAt(params.position);
1218
+ const node = parsed.nodeAt(offset);
1219
+ return await ((_a = handlers2[NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1220
+ document: doc,
1221
+ params,
1222
+ parsed,
1223
+ offset,
1224
+ node,
1225
+ code: doc.getText(),
1226
+ ...getCompilerInfo(doc)
1227
+ }));
1228
+ };
1229
+
1121
1230
  // src/service/marko/definition/OpenTagName.ts
1122
1231
  import path4 from "path";
1123
1232
  import { URI as URI4 } from "vscode-uri";
1124
- import { Range as Range5, LocationLink } from "vscode-languageserver";
1233
+ import { Range as Range4, LocationLink } from "vscode-languageserver";
1125
1234
 
1126
1235
  // src/utils/regexp-builder.ts
1127
1236
  function RegExpBuilder(strings, ...expressions) {
@@ -1147,20 +1256,8 @@ function escape(val) {
1147
1256
  return String(val).replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
1148
1257
  }
1149
1258
 
1150
- // src/utils/utils.ts
1151
- import fs2 from "fs";
1152
- import { URI as URI3 } from "vscode-uri";
1153
- import { Position, Range as Range4 } from "vscode-languageserver";
1154
- import { TextDocument } from "vscode-languageserver-textdocument";
1155
- var START_OF_FILE = Range4.create(Position.create(0, 0), Position.create(0, 0));
1156
- function createTextDocument(filename) {
1157
- const uri = URI3.file(filename).toString();
1158
- const content = fs2.readFileSync(filename, "utf-8");
1159
- return TextDocument.create(uri, "plaintext", 0, content);
1160
- }
1161
-
1162
1259
  // src/service/marko/definition/OpenTagName.ts
1163
- function OpenTagName2({
1260
+ function OpenTagName3({
1164
1261
  lookup,
1165
1262
  parsed,
1166
1263
  node
@@ -1185,19 +1282,29 @@ function OpenTagName2({
1185
1282
  }
1186
1283
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
1187
1284
  const tagDefDoc = createTextDocument(tagEntryFile);
1188
- const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1285
+ const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(
1286
+ tagDefDoc.getText()
1287
+ );
1189
1288
  if (match && match.index) {
1190
- range = Range5.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1289
+ range = Range4.create(
1290
+ tagDefDoc.positionAt(match.index),
1291
+ tagDefDoc.positionAt(match.index + match[0].length)
1292
+ );
1191
1293
  }
1192
1294
  }
1193
1295
  return [
1194
- LocationLink.create(URI4.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
1296
+ LocationLink.create(
1297
+ URI4.file(tagEntryFile).toString(),
1298
+ range,
1299
+ range,
1300
+ parsed.locationAt(node)
1301
+ )
1195
1302
  ];
1196
1303
  }
1197
1304
 
1198
1305
  // src/service/marko/definition/AttrName.ts
1199
1306
  import { URI as URI5 } from "vscode-uri";
1200
- import { Range as Range6, LocationLink as LocationLink2 } from "vscode-languageserver";
1307
+ import { Range as Range5, LocationLink as LocationLink2 } from "vscode-languageserver";
1201
1308
  function AttrName2({
1202
1309
  lookup,
1203
1310
  parsed,
@@ -1219,19 +1326,29 @@ function AttrName2({
1219
1326
  }
1220
1327
  if (/\/marko(?:-tag)?\.json$/.test(attrEntryFile)) {
1221
1328
  const tagDefDoc = createTextDocument(attrEntryFile);
1222
- const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1329
+ const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(
1330
+ tagDefDoc.getText()
1331
+ );
1223
1332
  if (match && match.index) {
1224
- range = Range6.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1333
+ range = Range5.create(
1334
+ tagDefDoc.positionAt(match.index),
1335
+ tagDefDoc.positionAt(match.index + match[0].length)
1336
+ );
1225
1337
  }
1226
1338
  }
1227
1339
  return [
1228
- LocationLink2.create(URI5.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
1340
+ LocationLink2.create(
1341
+ URI5.file(attrEntryFile).toString(),
1342
+ range,
1343
+ range,
1344
+ parsed.locationAt(node)
1345
+ )
1229
1346
  ];
1230
1347
  }
1231
1348
 
1232
1349
  // src/service/marko/definition/index.ts
1233
- var handlers2 = {
1234
- OpenTagName: OpenTagName2,
1350
+ var handlers3 = {
1351
+ OpenTagName: OpenTagName3,
1235
1352
  AttrName: AttrName2
1236
1353
  };
1237
1354
  var findDefinition = async (doc, params) => {
@@ -1239,7 +1356,7 @@ var findDefinition = async (doc, params) => {
1239
1356
  const parsed = parse2(doc);
1240
1357
  const offset = doc.offsetAt(params.position);
1241
1358
  const node = parsed.nodeAt(offset);
1242
- return await ((_a = handlers2[NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1359
+ return await ((_a = handlers3[NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1243
1360
  document: doc,
1244
1361
  params,
1245
1362
  parsed,
@@ -1250,10 +1367,20 @@ var findDefinition = async (doc, params) => {
1250
1367
  })) || [];
1251
1368
  };
1252
1369
 
1253
- // src/service/marko/document-links/extract.ts
1370
+ // src/service/marko/document-links.ts
1254
1371
  import { DocumentLink } from "vscode-languageserver";
1255
1372
  import { URI as URI6 } from "vscode-uri";
1256
1373
  var importTagReg2 = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1374
+ var cache = /* @__PURE__ */ new WeakMap();
1375
+ var findDocumentLinks = async (doc) => {
1376
+ const parsed = parse2(doc);
1377
+ let result = cache.get(parsed);
1378
+ if (!result) {
1379
+ result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1380
+ cache.set(parsed, result);
1381
+ }
1382
+ return result;
1383
+ };
1257
1384
  function extractDocumentLinks(doc, parsed, lookup) {
1258
1385
  if (URI6.parse(doc.uri).scheme === "untitled") {
1259
1386
  return [];
@@ -1264,14 +1391,29 @@ function extractDocumentLinks(doc, parsed, lookup) {
1264
1391
  const read = (range) => code.slice(range.start, range.end);
1265
1392
  const visit = (node) => {
1266
1393
  switch (node.type) {
1394
+ case 14 /* AttrTag */:
1395
+ if (node.body) {
1396
+ for (const child of node.body) {
1397
+ visit(child);
1398
+ }
1399
+ }
1400
+ break;
1267
1401
  case 1 /* Tag */:
1268
1402
  if (node.attrs && node.nameText) {
1269
1403
  for (const attr of node.attrs) {
1270
1404
  if (isDocumentLinkAttr(doc, node, attr)) {
1271
- links.push(DocumentLink.create({
1272
- start: parsed.positionAt(attr.value.value.start),
1273
- end: parsed.positionAt(attr.value.value.end)
1274
- }, resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1405
+ const resolved = resolveUrl(
1406
+ read(attr.value.value).slice(1, -1),
1407
+ doc.uri
1408
+ );
1409
+ if (resolved) {
1410
+ links.push(
1411
+ DocumentLink.create(
1412
+ parsed.locationAt(attr.value.value),
1413
+ resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)
1414
+ )
1415
+ );
1416
+ }
1275
1417
  }
1276
1418
  }
1277
1419
  }
@@ -1293,10 +1435,15 @@ function extractDocumentLinks(doc, parsed, lookup) {
1293
1435
  const tagDef = lookup.getTag(tagName);
1294
1436
  const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1295
1437
  if (fileForTag) {
1296
- links.push(DocumentLink.create({
1297
- start: parsed.positionAt(item.start + match.index),
1298
- end: parsed.positionAt(item.start + match.index + length)
1299
- }, fileForTag));
1438
+ links.push(
1439
+ DocumentLink.create(
1440
+ parsed.locationAt({
1441
+ start: item.start + match.index,
1442
+ end: item.start + match.index + length
1443
+ }),
1444
+ fileForTag
1445
+ )
1446
+ );
1300
1447
  }
1301
1448
  }
1302
1449
  }
@@ -1307,26 +1454,60 @@ function extractDocumentLinks(doc, parsed, lookup) {
1307
1454
  return links;
1308
1455
  }
1309
1456
 
1310
- // src/service/marko/document-links/index.ts
1311
- var cache = /* @__PURE__ */ new WeakMap();
1312
- var findDocumentLinks = async (doc) => {
1457
+ // src/service/marko/document-symbols.ts
1458
+ import { URI as URI7 } from "vscode-uri";
1459
+ import { SymbolInformation, SymbolKind } from "vscode-languageserver";
1460
+ var cache2 = /* @__PURE__ */ new WeakMap();
1461
+ var findDocumentSymbols = async (doc) => {
1313
1462
  const parsed = parse2(doc);
1314
- let result = cache.get(parsed);
1463
+ let result = cache2.get(parsed);
1315
1464
  if (!result) {
1316
- result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1317
- cache.set(parsed, result);
1465
+ result = extractDocumentSymbols(doc, parsed, getCompilerInfo(doc).lookup);
1466
+ cache2.set(parsed, result);
1318
1467
  }
1319
1468
  return result;
1320
1469
  };
1470
+ function extractDocumentSymbols(doc, parsed, lookup) {
1471
+ if (URI7.parse(doc.uri).scheme === "untitled") {
1472
+ return [];
1473
+ }
1474
+ const symbols = [];
1475
+ const { program } = parsed;
1476
+ const visit = (node) => {
1477
+ var _a, _b;
1478
+ switch (node.type) {
1479
+ case 1 /* Tag */:
1480
+ case 14 /* AttrTag */:
1481
+ symbols.push(
1482
+ SymbolInformation.create(
1483
+ (node.type === 14 /* AttrTag */ ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>",
1484
+ node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html) && SymbolKind.Property || SymbolKind.Class,
1485
+ parsed.locationAt(node),
1486
+ doc.uri
1487
+ )
1488
+ );
1489
+ if (node.body) {
1490
+ for (const child of node.body) {
1491
+ visit(child);
1492
+ }
1493
+ }
1494
+ break;
1495
+ }
1496
+ };
1497
+ for (const item of program.body) {
1498
+ visit(item);
1499
+ }
1500
+ return symbols;
1501
+ }
1321
1502
 
1322
1503
  // src/service/marko/format.ts
1323
- import { Range as Range7, TextEdit as TextEdit6 } from "vscode-languageserver";
1324
- import { URI as URI7 } from "vscode-uri";
1504
+ import { Range as Range6, TextEdit as TextEdit6 } from "vscode-languageserver";
1505
+ import { URI as URI8 } from "vscode-uri";
1325
1506
  import * as prettier from "prettier";
1326
1507
  import * as markoPrettier from "prettier-plugin-marko";
1327
1508
  var format2 = async (doc, params, cancel) => {
1328
1509
  try {
1329
- const { fsPath, scheme } = URI7.parse(doc.uri);
1510
+ const { fsPath, scheme } = URI8.parse(doc.uri);
1330
1511
  const text = doc.getText();
1331
1512
  const options = {
1332
1513
  parser: "marko",
@@ -1341,7 +1522,10 @@ var format2 = async (doc, params, cancel) => {
1341
1522
  if (cancel.isCancellationRequested)
1342
1523
  return;
1343
1524
  return [
1344
- TextEdit6.replace(Range7.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1525
+ TextEdit6.replace(
1526
+ Range6.create(doc.positionAt(0), doc.positionAt(text.length)),
1527
+ prettier.format(text, options)
1528
+ )
1345
1529
  ];
1346
1530
  } catch (e) {
1347
1531
  displayError(e);
@@ -1352,15 +1536,17 @@ var format2 = async (doc, params, cancel) => {
1352
1536
  var marko_default = {
1353
1537
  doComplete,
1354
1538
  doValidate,
1539
+ doHover,
1355
1540
  findDefinition,
1356
1541
  findDocumentLinks,
1542
+ findDocumentSymbols,
1357
1543
  format: format2
1358
1544
  };
1359
1545
 
1360
1546
  // src/service/stylesheet/index.ts
1361
1547
  import {
1362
1548
  CompletionList as CompletionList2,
1363
- Range as Range9,
1549
+ Range as Range8,
1364
1550
  TextDocumentEdit
1365
1551
  } from "vscode-languageserver";
1366
1552
  import {
@@ -1472,6 +1658,13 @@ function extractStyleSheets(code, program, lookup) {
1472
1658
  const visit = (node) => {
1473
1659
  var _a, _b;
1474
1660
  switch (node.type) {
1661
+ case 14 /* AttrTag */:
1662
+ if (node.body) {
1663
+ for (const child of node.body) {
1664
+ visit(child);
1665
+ }
1666
+ }
1667
+ break;
1475
1668
  case 1 /* Tag */:
1476
1669
  if (node.nameText === "style" && node.concise && node.attrs) {
1477
1670
  const block = node.attrs.at(-1);
@@ -1528,7 +1721,7 @@ function extractStyleSheets(code, program, lookup) {
1528
1721
  }
1529
1722
 
1530
1723
  // src/service/stylesheet/index.ts
1531
- var cache2 = /* @__PURE__ */ new WeakMap();
1724
+ var cache3 = /* @__PURE__ */ new WeakMap();
1532
1725
  var services = {
1533
1726
  css: getCSSLanguageService,
1534
1727
  less: getLESSLanguageService,
@@ -1548,12 +1741,21 @@ var StyleSheetService = {
1548
1741
  if (generatedOffset === void 0)
1549
1742
  continue;
1550
1743
  const { service: service2, virtualDoc } = info;
1551
- const result = await service2.doComplete2(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed, { resolveReference: resolveUrl });
1744
+ const result = await service2.doComplete2(
1745
+ virtualDoc,
1746
+ virtualDoc.positionAt(generatedOffset),
1747
+ info.parsed,
1748
+ { resolveReference: resolveUrl }
1749
+ );
1552
1750
  if (result.itemDefaults) {
1553
1751
  const { editRange } = result.itemDefaults;
1554
1752
  if (editRange) {
1555
1753
  if ("start" in editRange) {
1556
- result.itemDefaults.editRange = getSourceRange(doc, info, editRange);
1754
+ result.itemDefaults.editRange = getSourceRange(
1755
+ doc,
1756
+ info,
1757
+ editRange
1758
+ );
1557
1759
  } else {
1558
1760
  editRange.insert = getSourceRange(doc, info, editRange.insert);
1559
1761
  editRange.replace = getSourceRange(doc, info, editRange.replace);
@@ -1565,7 +1767,11 @@ var StyleSheetService = {
1565
1767
  item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
1566
1768
  }
1567
1769
  if (item.additionalTextEdits) {
1568
- item.additionalTextEdits = getSourceEdits(doc, info, item.additionalTextEdits);
1770
+ item.additionalTextEdits = getSourceEdits(
1771
+ doc,
1772
+ info,
1773
+ item.additionalTextEdits
1774
+ );
1569
1775
  }
1570
1776
  }
1571
1777
  return result;
@@ -1581,7 +1787,11 @@ var StyleSheetService = {
1581
1787
  if (generatedOffset === void 0)
1582
1788
  continue;
1583
1789
  const { service: service2, virtualDoc } = info;
1584
- const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1790
+ const result = service2.findDefinition(
1791
+ virtualDoc,
1792
+ virtualDoc.positionAt(generatedOffset),
1793
+ info.parsed
1794
+ );
1585
1795
  if (result) {
1586
1796
  const range = getSourceRange(doc, info, result.range);
1587
1797
  if (range) {
@@ -1604,7 +1814,11 @@ var StyleSheetService = {
1604
1814
  continue;
1605
1815
  const { service: service2, virtualDoc } = info;
1606
1816
  const result = [];
1607
- for (const location of service2.findReferences(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1817
+ for (const location of service2.findReferences(
1818
+ virtualDoc,
1819
+ virtualDoc.positionAt(generatedOffset),
1820
+ info.parsed
1821
+ )) {
1608
1822
  const range = getSourceRange(doc, info, location.range);
1609
1823
  if (range) {
1610
1824
  result.push({
@@ -1616,13 +1830,46 @@ var StyleSheetService = {
1616
1830
  return result.length ? result : void 0;
1617
1831
  }
1618
1832
  },
1833
+ findDocumentSymbols(doc) {
1834
+ const infoByExt = getStyleSheetInfo(doc);
1835
+ const result = [];
1836
+ for (const ext in infoByExt) {
1837
+ const info = infoByExt[ext];
1838
+ const { service: service2, virtualDoc } = info;
1839
+ for (const symbol of service2.findDocumentSymbols(
1840
+ virtualDoc,
1841
+ info.parsed
1842
+ )) {
1843
+ if (symbol.location.uri === doc.uri) {
1844
+ const range = getSourceRange(doc, info, symbol.location.range);
1845
+ if (range) {
1846
+ result.push({
1847
+ kind: symbol.kind,
1848
+ name: symbol.name,
1849
+ tags: symbol.tags,
1850
+ deprecated: symbol.deprecated,
1851
+ containerName: symbol.containerName,
1852
+ location: { uri: doc.uri, range }
1853
+ });
1854
+ }
1855
+ } else {
1856
+ result.push(symbol);
1857
+ }
1858
+ }
1859
+ }
1860
+ return result.length ? result : void 0;
1861
+ },
1619
1862
  async findDocumentLinks(doc) {
1620
1863
  const infoByExt = getStyleSheetInfo(doc);
1621
1864
  const result = [];
1622
1865
  for (const ext in infoByExt) {
1623
1866
  const info = infoByExt[ext];
1624
1867
  const { service: service2, virtualDoc } = info;
1625
- for (const link of await service2.findDocumentLinks2(virtualDoc, info.parsed, { resolveReference: resolveUrl })) {
1868
+ for (const link of await service2.findDocumentLinks2(
1869
+ virtualDoc,
1870
+ info.parsed,
1871
+ { resolveReference: resolveUrl }
1872
+ )) {
1626
1873
  const range = getSourceRange(doc, info, link.range);
1627
1874
  if (range) {
1628
1875
  result.push({
@@ -1646,7 +1893,11 @@ var StyleSheetService = {
1646
1893
  continue;
1647
1894
  const { service: service2, virtualDoc } = info;
1648
1895
  const result = [];
1649
- for (const highlight of service2.findDocumentHighlights(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1896
+ for (const highlight of service2.findDocumentHighlights(
1897
+ virtualDoc,
1898
+ virtualDoc.positionAt(generatedOffset),
1899
+ info.parsed
1900
+ )) {
1650
1901
  const range = getSourceRange(doc, info, highlight.range);
1651
1902
  if (range) {
1652
1903
  result.push({
@@ -1664,7 +1915,10 @@ var StyleSheetService = {
1664
1915
  for (const ext in infoByExt) {
1665
1916
  const info = infoByExt[ext];
1666
1917
  const { service: service2, virtualDoc } = info;
1667
- for (const colorInfo of service2.findDocumentColors(virtualDoc, info.parsed)) {
1918
+ for (const colorInfo of service2.findDocumentColors(
1919
+ virtualDoc,
1920
+ info.parsed
1921
+ )) {
1668
1922
  const range = getSourceRange(doc, info, colorInfo.range);
1669
1923
  if (range) {
1670
1924
  result.push({
@@ -1684,12 +1938,22 @@ var StyleSheetService = {
1684
1938
  const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
1685
1939
  if (generatedOffsetStart === void 0)
1686
1940
  continue;
1687
- const generatedOffsetEnd = info.generatedOffsetAt(doc.offsetAt(params.range.end));
1941
+ const generatedOffsetEnd = info.generatedOffsetAt(
1942
+ doc.offsetAt(params.range.end)
1943
+ );
1688
1944
  if (generatedOffsetEnd === void 0)
1689
1945
  continue;
1690
1946
  const { service: service2, virtualDoc } = info;
1691
1947
  const result = [];
1692
- for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1948
+ for (const colorPresentation of service2.getColorPresentations(
1949
+ virtualDoc,
1950
+ info.parsed,
1951
+ params.color,
1952
+ Range8.create(
1953
+ virtualDoc.positionAt(generatedOffsetStart),
1954
+ virtualDoc.positionAt(generatedOffsetEnd)
1955
+ )
1956
+ )) {
1693
1957
  const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1694
1958
  const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
1695
1959
  if (textEdit || additionalTextEdits) {
@@ -1712,7 +1976,11 @@ var StyleSheetService = {
1712
1976
  if (generatedOffset === void 0)
1713
1977
  continue;
1714
1978
  const { service: service2, virtualDoc } = info;
1715
- const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1979
+ const result = service2.doHover(
1980
+ virtualDoc,
1981
+ virtualDoc.positionAt(generatedOffset),
1982
+ info.parsed
1983
+ );
1716
1984
  if (result) {
1717
1985
  if (result.range) {
1718
1986
  const range = getSourceRange(doc, info, result.range);
@@ -1737,7 +2005,12 @@ var StyleSheetService = {
1737
2005
  if (generatedOffset === void 0)
1738
2006
  continue;
1739
2007
  const { service: service2, virtualDoc } = info;
1740
- const result = service2.doRename(virtualDoc, virtualDoc.positionAt(generatedOffset), params.newName, info.parsed);
2008
+ const result = service2.doRename(
2009
+ virtualDoc,
2010
+ virtualDoc.positionAt(generatedOffset),
2011
+ params.newName,
2012
+ info.parsed
2013
+ );
1741
2014
  if (result.changes) {
1742
2015
  for (const uri in result.changes) {
1743
2016
  if (uri === doc.uri) {
@@ -1766,11 +2039,21 @@ var StyleSheetService = {
1766
2039
  const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
1767
2040
  if (generatedOffsetStart === void 0)
1768
2041
  continue;
1769
- const generatedOffsetEnd = info.generatedOffsetAt(doc.offsetAt(params.range.end));
2042
+ const generatedOffsetEnd = info.generatedOffsetAt(
2043
+ doc.offsetAt(params.range.end)
2044
+ );
1770
2045
  if (generatedOffsetEnd === void 0)
1771
2046
  continue;
1772
2047
  const { service: service2, virtualDoc } = info;
1773
- const result = service2.doCodeActions(virtualDoc, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
2048
+ const result = service2.doCodeActions(
2049
+ virtualDoc,
2050
+ Range8.create(
2051
+ virtualDoc.positionAt(generatedOffsetStart),
2052
+ virtualDoc.positionAt(generatedOffsetEnd)
2053
+ ),
2054
+ params.context,
2055
+ info.parsed
2056
+ );
1774
2057
  for (const command of result) {
1775
2058
  const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1776
2059
  if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
@@ -1785,7 +2068,10 @@ var StyleSheetService = {
1785
2068
  const result = [];
1786
2069
  for (const ext in infoByExt) {
1787
2070
  const info = infoByExt[ext];
1788
- for (const diag of info.service.doValidation(info.virtualDoc, info.parsed)) {
2071
+ for (const diag of info.service.doValidation(
2072
+ info.virtualDoc,
2073
+ info.parsed
2074
+ )) {
1789
2075
  const range = getSourceRange(doc, info, diag.range);
1790
2076
  if (range) {
1791
2077
  diag.range = range;
@@ -1855,9 +2141,13 @@ function getSourceRange(doc, info, range) {
1855
2141
  function getStyleSheetInfo(doc) {
1856
2142
  var _a;
1857
2143
  const parsed = parse2(doc);
1858
- let cached = cache2.get(parsed);
2144
+ let cached = cache3.get(parsed);
1859
2145
  if (!cached) {
1860
- const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
2146
+ const results = extractStyleSheets(
2147
+ doc.getText(),
2148
+ parsed.program,
2149
+ getCompilerInfo(doc).lookup
2150
+ );
1861
2151
  cached = {};
1862
2152
  for (const ext in results) {
1863
2153
  const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
@@ -1867,7 +2157,12 @@ function getStyleSheetInfo(doc) {
1867
2157
  if (!service2)
1868
2158
  continue;
1869
2159
  const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
1870
- const virtualDoc = TextDocument2.create(doc.uri, "css", doc.version, generated);
2160
+ const virtualDoc = TextDocument2.create(
2161
+ doc.uri,
2162
+ "css",
2163
+ doc.version,
2164
+ generated
2165
+ );
1871
2166
  cached[ext] = {
1872
2167
  service: service2,
1873
2168
  virtualDoc,
@@ -1876,7 +2171,7 @@ function getStyleSheetInfo(doc) {
1876
2171
  parsed: service2.parseStylesheet(virtualDoc)
1877
2172
  };
1878
2173
  }
1879
- cache2.set(parsed, cached);
2174
+ cache3.set(parsed, cached);
1880
2175
  }
1881
2176
  return cached;
1882
2177
  }
@@ -1897,10 +2192,12 @@ var service = {
1897
2192
  let items;
1898
2193
  let isIncomplete = false;
1899
2194
  try {
1900
- for (const pending of plugins.map((plugin) => {
1901
- var _a;
1902
- return (_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1903
- })) {
2195
+ for (const pending of plugins.map(
2196
+ (plugin) => {
2197
+ var _a;
2198
+ return (_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2199
+ }
2200
+ )) {
1904
2201
  const cur = await pending;
1905
2202
  if (cancel.isCancellationRequested)
1906
2203
  return;
@@ -1926,10 +2223,12 @@ var service = {
1926
2223
  async findDefinition(doc, params, cancel) {
1927
2224
  let result;
1928
2225
  try {
1929
- for (const pending of plugins.map((plugin) => {
1930
- var _a;
1931
- return (_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1932
- })) {
2226
+ for (const pending of plugins.map(
2227
+ (plugin) => {
2228
+ var _a;
2229
+ return (_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2230
+ }
2231
+ )) {
1933
2232
  const cur = await pending;
1934
2233
  if (cancel.isCancellationRequested)
1935
2234
  return;
@@ -1944,10 +2243,32 @@ var service = {
1944
2243
  async findReferences(doc, params, cancel) {
1945
2244
  let result;
1946
2245
  try {
1947
- for (const pending of plugins.map((plugin) => {
1948
- var _a;
1949
- return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1950
- })) {
2246
+ for (const pending of plugins.map(
2247
+ (plugin) => {
2248
+ var _a;
2249
+ return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2250
+ }
2251
+ )) {
2252
+ const cur = await pending;
2253
+ if (cancel.isCancellationRequested)
2254
+ return;
2255
+ if (cur)
2256
+ result = result ? result.concat(cur) : cur;
2257
+ }
2258
+ } catch (err) {
2259
+ displayError(err);
2260
+ }
2261
+ return result;
2262
+ },
2263
+ async findDocumentSymbols(doc, params, cancel) {
2264
+ let result;
2265
+ try {
2266
+ for (const pending of plugins.map(
2267
+ (plugin) => {
2268
+ var _a;
2269
+ return (_a = plugin.findDocumentSymbols) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2270
+ }
2271
+ )) {
1951
2272
  const cur = await pending;
1952
2273
  if (cancel.isCancellationRequested)
1953
2274
  return;
@@ -1962,10 +2283,12 @@ var service = {
1962
2283
  async findDocumentLinks(doc, params, cancel) {
1963
2284
  let result;
1964
2285
  try {
1965
- for (const pending of plugins.map((plugin) => {
1966
- var _a;
1967
- return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1968
- })) {
2286
+ for (const pending of plugins.map(
2287
+ (plugin) => {
2288
+ var _a;
2289
+ return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2290
+ }
2291
+ )) {
1969
2292
  const cur = await pending;
1970
2293
  if (cancel.isCancellationRequested)
1971
2294
  return;
@@ -1980,10 +2303,12 @@ var service = {
1980
2303
  async findDocumentHighlights(doc, params, cancel) {
1981
2304
  let result;
1982
2305
  try {
1983
- for (const pending of plugins.map((plugin) => {
1984
- var _a;
1985
- return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1986
- })) {
2306
+ for (const pending of plugins.map(
2307
+ (plugin) => {
2308
+ var _a;
2309
+ return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2310
+ }
2311
+ )) {
1987
2312
  const cur = await pending;
1988
2313
  if (cancel.isCancellationRequested)
1989
2314
  return;
@@ -1998,10 +2323,12 @@ var service = {
1998
2323
  async findDocumentColors(doc, params, cancel) {
1999
2324
  let result;
2000
2325
  try {
2001
- for (const pending of plugins.map((plugin) => {
2002
- var _a;
2003
- return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2004
- })) {
2326
+ for (const pending of plugins.map(
2327
+ (plugin) => {
2328
+ var _a;
2329
+ return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2330
+ }
2331
+ )) {
2005
2332
  const cur = await pending;
2006
2333
  if (cancel.isCancellationRequested)
2007
2334
  return;
@@ -2016,10 +2343,12 @@ var service = {
2016
2343
  async getColorPresentations(doc, params, cancel) {
2017
2344
  let result;
2018
2345
  try {
2019
- for (const pending of plugins.map((plugin) => {
2020
- var _a;
2021
- return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2022
- })) {
2346
+ for (const pending of plugins.map(
2347
+ (plugin) => {
2348
+ var _a;
2349
+ return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2350
+ }
2351
+ )) {
2023
2352
  const cur = await pending;
2024
2353
  if (cancel.isCancellationRequested)
2025
2354
  return;
@@ -2050,10 +2379,12 @@ var service = {
2050
2379
  let changeAnnotations;
2051
2380
  let documentChanges;
2052
2381
  try {
2053
- for (const pending of plugins.map((plugin) => {
2054
- var _a;
2055
- return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2056
- })) {
2382
+ for (const pending of plugins.map(
2383
+ (plugin) => {
2384
+ var _a;
2385
+ return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2386
+ }
2387
+ )) {
2057
2388
  const cur = await pending;
2058
2389
  if (cancel.isCancellationRequested)
2059
2390
  return;
@@ -2093,10 +2424,12 @@ var service = {
2093
2424
  async doCodeActions(doc, params, cancel) {
2094
2425
  let result;
2095
2426
  try {
2096
- for (const pending of plugins.map((plugin) => {
2097
- var _a;
2098
- return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2099
- })) {
2427
+ for (const pending of plugins.map(
2428
+ (plugin) => {
2429
+ var _a;
2430
+ return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2431
+ }
2432
+ )) {
2100
2433
  const cur = await pending;
2101
2434
  if (cancel.isCancellationRequested)
2102
2435
  return;
@@ -2159,6 +2492,7 @@ connection2.onInitialize(async (params) => {
2159
2492
  documentLinkProvider: { resolveProvider: false },
2160
2493
  colorProvider: true,
2161
2494
  documentHighlightProvider: true,
2495
+ documentSymbolProvider: true,
2162
2496
  completionProvider: {
2163
2497
  triggerCharacters: [
2164
2498
  ".",
@@ -2193,37 +2527,88 @@ documents.onDidChangeContent(({ document }) => {
2193
2527
  clearCompilerCache(document);
2194
2528
  });
2195
2529
  connection2.onCompletion(async (params, cancel) => {
2196
- return await service.doComplete(documents.get(params.textDocument.uri), params, cancel) || null;
2530
+ return await service.doComplete(
2531
+ documents.get(params.textDocument.uri),
2532
+ params,
2533
+ cancel
2534
+ ) || null;
2197
2535
  });
2198
2536
  connection2.onDefinition(async (params, cancel) => {
2199
- return await service.findDefinition(documents.get(params.textDocument.uri), params, cancel) || null;
2537
+ return await service.findDefinition(
2538
+ documents.get(params.textDocument.uri),
2539
+ params,
2540
+ cancel
2541
+ ) || null;
2200
2542
  });
2201
2543
  connection2.onReferences(async (params, cancel) => {
2202
- return await service.findReferences(documents.get(params.textDocument.uri), params, cancel) || null;
2544
+ return await service.findReferences(
2545
+ documents.get(params.textDocument.uri),
2546
+ params,
2547
+ cancel
2548
+ ) || null;
2203
2549
  });
2204
2550
  connection2.onDocumentLinks(async (params, cancel) => {
2205
- return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
2551
+ return await service.findDocumentLinks(
2552
+ documents.get(params.textDocument.uri),
2553
+ params,
2554
+ cancel
2555
+ ) || null;
2556
+ });
2557
+ connection2.onDocumentSymbol(async (params, cancel) => {
2558
+ return await service.findDocumentSymbols(
2559
+ documents.get(params.textDocument.uri),
2560
+ params,
2561
+ cancel
2562
+ ) || null;
2206
2563
  });
2207
2564
  connection2.onDocumentHighlight(async (params, cancel) => {
2208
- return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
2565
+ return await service.findDocumentHighlights(
2566
+ documents.get(params.textDocument.uri),
2567
+ params,
2568
+ cancel
2569
+ ) || null;
2209
2570
  });
2210
2571
  connection2.onDocumentColor(async (params, cancel) => {
2211
- return await service.findDocumentColors(documents.get(params.textDocument.uri), params, cancel) || null;
2572
+ return await service.findDocumentColors(
2573
+ documents.get(params.textDocument.uri),
2574
+ params,
2575
+ cancel
2576
+ ) || null;
2212
2577
  });
2213
2578
  connection2.onColorPresentation(async (params, cancel) => {
2214
- return await service.getColorPresentations(documents.get(params.textDocument.uri), params, cancel) || null;
2579
+ return await service.getColorPresentations(
2580
+ documents.get(params.textDocument.uri),
2581
+ params,
2582
+ cancel
2583
+ ) || null;
2215
2584
  });
2216
2585
  connection2.onHover(async (params, cancel) => {
2217
- return await service.doHover(documents.get(params.textDocument.uri), params, cancel) || null;
2586
+ return await service.doHover(
2587
+ documents.get(params.textDocument.uri),
2588
+ params,
2589
+ cancel
2590
+ ) || null;
2218
2591
  });
2219
2592
  connection2.onRenameRequest(async (params, cancel) => {
2220
- return await service.doRename(documents.get(params.textDocument.uri), params, cancel) || null;
2593
+ return await service.doRename(
2594
+ documents.get(params.textDocument.uri),
2595
+ params,
2596
+ cancel
2597
+ ) || null;
2221
2598
  });
2222
2599
  connection2.onCodeAction(async (params, cancel) => {
2223
- return await service.doCodeActions(documents.get(params.textDocument.uri), params, cancel) || null;
2600
+ return await service.doCodeActions(
2601
+ documents.get(params.textDocument.uri),
2602
+ params,
2603
+ cancel
2604
+ ) || null;
2224
2605
  });
2225
2606
  connection2.onDocumentFormatting(async (params, cancel) => {
2226
- return await service.format(documents.get(params.textDocument.uri), params, cancel) || null;
2607
+ return await service.format(
2608
+ documents.get(params.textDocument.uri),
2609
+ params,
2610
+ cancel
2611
+ ) || null;
2227
2612
  });
2228
2613
  function validateDocs() {
2229
2614
  queueDiagnostic();
@@ -2235,15 +2620,17 @@ function validateDocs() {
2235
2620
  function queueDiagnostic() {
2236
2621
  clearTimeout(diagnosticTimeout);
2237
2622
  const id = diagnosticTimeout = setTimeout(async () => {
2238
- const results = await Promise.all(documents.all().map(async (doc) => {
2239
- if (!pendingDiags.delete(doc))
2240
- return;
2241
- const prevDiag = prevDiags.get(doc) || [];
2242
- const nextDiag = await service.doValidate(doc) || [];
2243
- if (isDeepStrictEqual(prevDiag, nextDiag))
2244
- return;
2245
- return [doc, nextDiag];
2246
- }));
2623
+ const results = await Promise.all(
2624
+ documents.all().map(async (doc) => {
2625
+ if (!pendingDiags.delete(doc))
2626
+ return;
2627
+ const prevDiag = prevDiags.get(doc) || [];
2628
+ const nextDiag = await service.doValidate(doc) || [];
2629
+ if (isDeepStrictEqual(prevDiag, nextDiag))
2630
+ return;
2631
+ return [doc, nextDiag];
2632
+ })
2633
+ );
2247
2634
  if (id === diagnosticTimeout) {
2248
2635
  for (const result of results) {
2249
2636
  if (result) {