@marko/language-server 0.12.4 → 0.12.5

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
@@ -18,6 +18,7 @@ import { TextDocument as TextDocument3 } from "vscode-languageserver-textdocumen
18
18
  import { inspect as inspect2, isDeepStrictEqual } from "util";
19
19
 
20
20
  // src/utils/compiler.ts
21
+ import { URI as URI2 } from "vscode-uri";
21
22
  import resolveFrom from "resolve-from";
22
23
  import lassoPackageRoot from "lasso-package-root";
23
24
  import * as builtinCompiler from "@marko/compiler";
@@ -27,7 +28,8 @@ import * as builtinTranslator from "@marko/translator-default";
27
28
  import path from "path";
28
29
  import { URI } from "vscode-uri";
29
30
  function getDocDir(doc) {
30
- return path.dirname(getDocFile(doc));
31
+ const filename = getDocFile(doc);
32
+ return filename ? path.dirname(filename) : void 0;
31
33
  }
32
34
  function getDocFile(doc) {
33
35
  return URI.parse(doc.uri).fsPath;
@@ -530,6 +532,12 @@ function isTransparentTag(node) {
530
532
  // src/utils/compiler.ts
531
533
  var lookupKey = Symbol("lookup");
532
534
  var compilerInfoByDir = /* @__PURE__ */ new Map();
535
+ var builtinInfo = {
536
+ cache: /* @__PURE__ */ new Map(),
537
+ lookup: builtinCompiler.taglib.buildLookup(__dirname, builtinTranslator),
538
+ compiler: builtinCompiler,
539
+ translator: builtinTranslator
540
+ };
533
541
  builtinCompiler.configure({ translator: builtinTranslator });
534
542
  function parse2(doc) {
535
543
  const compilerInfo = getCompilerInfo(doc);
@@ -542,6 +550,8 @@ function parse2(doc) {
542
550
  }
543
551
  function getCompilerInfo(doc) {
544
552
  const dir = getDocDir(doc);
553
+ if (!dir)
554
+ return builtinInfo;
545
555
  let info = compilerInfoByDir.get(dir);
546
556
  if (!info) {
547
557
  info = loadCompilerInfo(dir);
@@ -554,15 +564,19 @@ function setup(connection3, documents2) {
554
564
  clearAllCaches();
555
565
  });
556
566
  documents2.onDidChangeContent(({ document }) => {
557
- var _a;
558
567
  if (document.version > 1) {
559
- if (document.uri.endsWith(".marko")) {
560
- (_a = getCompilerInfo(document)) == null ? void 0 : _a.cache.delete(document);
568
+ if (document.languageId === "marko") {
569
+ getCompilerInfo(document).cache.delete(document);
561
570
  } else if (/[./\\]marko(?:-tag)?\.json$/.test(document.uri)) {
562
571
  clearAllCaches();
563
572
  }
564
573
  }
565
574
  });
575
+ documents2.onDidClose(({ document }) => {
576
+ if (document.languageId === "marko" && URI2.parse(document.uri).scheme !== "file") {
577
+ getCompilerInfo(document).cache.delete(document);
578
+ }
579
+ });
566
580
  }
567
581
  function clearAllCaches() {
568
582
  for (const [, info] of compilerInfoByDir) {
@@ -598,7 +612,7 @@ function loadCompilerInfo(dir) {
598
612
  try {
599
613
  lookup = compiler.taglib.buildLookup(dir, translator);
600
614
  } catch {
601
- lookup = null;
615
+ lookup = builtinInfo.lookup;
602
616
  }
603
617
  cache2.set(lookupKey, lookup);
604
618
  }
@@ -679,7 +693,7 @@ ${closingTagStr}`
679
693
 
680
694
  // src/service/marko/complete/OpenTagName.ts
681
695
  import path2 from "path";
682
- import { URI as URI2 } from "vscode-uri";
696
+ import { URI as URI3 } from "vscode-uri";
683
697
  import {
684
698
  CompletionItemKind as CompletionItemKind2,
685
699
  InsertTextFormat as InsertTextFormat2,
@@ -692,8 +706,6 @@ function OpenTagName({
692
706
  parsed,
693
707
  node
694
708
  }) {
695
- if (!lookup)
696
- return;
697
709
  const currentTemplateFilePath = getDocFile(document);
698
710
  const tag = node.parent;
699
711
  const tagNameLocation = parsed.locationAt(node);
@@ -710,7 +722,7 @@ function OpenTagName({
710
722
  return tags.filter((it) => !it.deprecated).filter((it) => it.name !== "*").filter((it) => /^[^_]/.test(it.name) || !/\/node_modules\//.test(it.filePath)).map((it) => {
711
723
  let label = it.isNestedTag ? `@${it.name}` : it.name;
712
724
  const fileForTag = it.template || it.renderer || it.filePath;
713
- const fileURIForTag = URI2.file(fileForTag).toString();
725
+ const fileURIForTag = URI3.file(fileForTag).toString();
714
726
  const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
715
727
  const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
716
728
  const isCoreTag = nodeModuleName === "marko";
@@ -718,7 +730,7 @@ function OpenTagName({
718
730
  kind: MarkupKind.Markdown,
719
731
  value: it.html ? `Built in [<${it.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${it.name}) HTML tag.` : nodeModuleName ? isCoreTag ? `Core Marko [<${it.name}>](${fileURIForTag}) tag.` : `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
720
732
 
721
- [${path2.relative(currentTemplateFilePath, fileForTag)}](${fileURIForTag})`
733
+ [${currentTemplateFilePath ? path2.relative(currentTemplateFilePath, fileForTag) : currentTemplateFilePath}](${fileURIForTag})`
722
734
  };
723
735
  if (it.description) {
724
736
  documentation.value += `
@@ -787,8 +799,6 @@ function AttrName({
787
799
  name = name.slice(0, modifierIndex);
788
800
  }
789
801
  }
790
- if (!lookup)
791
- return;
792
802
  const completions = [];
793
803
  const attrNameLoc = parsed.locationAt(hasModifier ? {
794
804
  start: node.start,
@@ -886,31 +896,26 @@ var doComplete = async (doc, params) => {
886
896
  };
887
897
 
888
898
  // src/service/marko/validate.ts
889
- import { URI as URI3 } from "vscode-uri";
890
899
  import { Diagnostic, DiagnosticSeverity, Range as Range2 } from "vscode-languageserver";
891
900
  var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
892
901
  var doValidate = (doc) => {
893
- const { fsPath, scheme } = URI3.parse(doc.uri);
902
+ const fsPath = getDocFile(doc);
894
903
  const diagnostics = [];
895
- if (scheme === "file") {
896
- const { compiler, translator, cache: cache2, lookup } = getCompilerInfo(doc);
897
- if (lookup) {
898
- try {
899
- compiler.compileSync(doc.getText(), fsPath, {
900
- cache: cache2,
901
- output: "source",
902
- code: false,
903
- translator
904
- });
905
- } catch (e) {
906
- let match;
907
- while (match = markoErrorRegExp.exec(e.message)) {
908
- const [, fileName, rawLine, rawCol, msg] = match;
909
- const line = (parseInt(rawLine, 10) || 1) - 1;
910
- const col = (parseInt(rawCol, 10) || 1) - 1;
911
- diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
912
- }
913
- }
904
+ const { compiler, translator, cache: cache2 } = getCompilerInfo(doc);
905
+ try {
906
+ compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
907
+ cache: cache2,
908
+ output: "source",
909
+ code: false,
910
+ translator
911
+ });
912
+ } catch (e) {
913
+ let match;
914
+ while (match = markoErrorRegExp.exec(e.message)) {
915
+ const [, fileName, rawLine, rawCol, msg] = match;
916
+ const line = (parseInt(rawLine, 10) || 1) - 1;
917
+ const col = (parseInt(rawCol, 10) || 1) - 1;
918
+ diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
914
919
  }
915
920
  }
916
921
  return diagnostics;
@@ -963,8 +968,6 @@ function OpenTagName2({
963
968
  parsed,
964
969
  node
965
970
  }) {
966
- if (!lookup)
967
- return;
968
971
  const tag = node.parent;
969
972
  let tagDef;
970
973
  let range = START_OF_FILE;
@@ -1003,8 +1006,6 @@ function AttrName2({
1003
1006
  parsed,
1004
1007
  node
1005
1008
  }) {
1006
- if (!lookup)
1007
- return;
1008
1009
  const tagName = node.parent.parent.nameText;
1009
1010
  const attrName = parsed.read(node);
1010
1011
  if (attrName[0] === "{")
@@ -1276,7 +1277,7 @@ var stylesheet_default = {
1276
1277
  if (generatedOffset === void 0)
1277
1278
  continue;
1278
1279
  const { service: service2, virtualDoc } = info;
1279
- const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset), service2.parseStylesheet(virtualDoc));
1280
+ const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1280
1281
  for (const item of result.items) {
1281
1282
  if (item.additionalTextEdits) {
1282
1283
  for (const edit of item.additionalTextEdits) {
@@ -1315,13 +1316,28 @@ var stylesheet_default = {
1315
1316
  if (generatedOffset === void 0)
1316
1317
  continue;
1317
1318
  const { service: service2, virtualDoc } = info;
1318
- const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), service2.parseStylesheet(virtualDoc));
1319
+ const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1319
1320
  if (result && updateRange(doc, info, result.range)) {
1320
1321
  return result;
1321
1322
  }
1322
1323
  break;
1323
1324
  }
1324
1325
  },
1326
+ async doHover(doc, params) {
1327
+ const infoByExt = getStyleSheetInfo(doc);
1328
+ const sourceOffset = doc.offsetAt(params.position);
1329
+ for (const ext in infoByExt) {
1330
+ const info = infoByExt[ext];
1331
+ const generatedOffset = info.generatedOffsetAt(sourceOffset);
1332
+ if (generatedOffset === void 0)
1333
+ continue;
1334
+ const { service: service2, virtualDoc } = info;
1335
+ const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), service2.parseStylesheet(virtualDoc));
1336
+ if (result && (!result.range || updateRange(doc, info, result.range))) {
1337
+ return result;
1338
+ }
1339
+ }
1340
+ },
1325
1341
  async doValidate(doc) {
1326
1342
  const infoByExt = getStyleSheetInfo(doc);
1327
1343
  const result = [];
@@ -1427,6 +1443,20 @@ var service = {
1427
1443
  }
1428
1444
  return result;
1429
1445
  },
1446
+ async doHover(doc, params, cancel) {
1447
+ var _a;
1448
+ try {
1449
+ for (const plugin of plugins) {
1450
+ const result = await ((_a = plugin.doHover) == null ? void 0 : _a.call(plugin, doc, params, cancel));
1451
+ if (cancel.isCancellationRequested)
1452
+ return;
1453
+ if (result)
1454
+ return result;
1455
+ }
1456
+ } catch (err) {
1457
+ displayError(err);
1458
+ }
1459
+ },
1430
1460
  async doValidate(doc) {
1431
1461
  const result = [];
1432
1462
  try {
@@ -1471,6 +1501,7 @@ connection2.onInitialize(() => {
1471
1501
  textDocumentSync: TextDocumentSyncKind.Incremental,
1472
1502
  documentFormattingProvider: true,
1473
1503
  definitionProvider: true,
1504
+ hoverProvider: true,
1474
1505
  completionProvider: {
1475
1506
  triggerCharacters: [
1476
1507
  ".",
@@ -1509,6 +1540,9 @@ connection2.onCompletion(async (params, cancel) => {
1509
1540
  connection2.onDefinition(async (params, cancel) => {
1510
1541
  return await service.findDefinition(documents.get(params.textDocument.uri), params, cancel) || null;
1511
1542
  });
1543
+ connection2.onHover(async (params, cancel) => {
1544
+ return await service.doHover(documents.get(params.textDocument.uri), params, cancel) || null;
1545
+ });
1512
1546
  connection2.onDocumentFormatting(async (params, cancel) => {
1513
1547
  return await service.format(documents.get(params.textDocument.uri), params, cancel) || null;
1514
1548
  });