@marko/language-server 0.12.4 → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +120 -83
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +120 -84
- package/dist/index.mjs.map +2 -2
- package/dist/service/types.d.ts +2 -1
- package/dist/utils/compiler.d.ts +2 -3
- package/dist/utils/doc-file.d.ts +2 -2
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
2
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
3
|
}) : x)(function(x) {
|
|
@@ -27,7 +26,8 @@ import * as builtinTranslator from "@marko/translator-default";
|
|
|
27
26
|
import path from "path";
|
|
28
27
|
import { URI } from "vscode-uri";
|
|
29
28
|
function getDocDir(doc) {
|
|
30
|
-
|
|
29
|
+
const filename = getDocFile(doc);
|
|
30
|
+
return filename ? path.dirname(filename) : void 0;
|
|
31
31
|
}
|
|
32
32
|
function getDocFile(doc) {
|
|
33
33
|
return URI.parse(doc.uri).fsPath;
|
|
@@ -530,6 +530,12 @@ function isTransparentTag(node) {
|
|
|
530
530
|
// src/utils/compiler.ts
|
|
531
531
|
var lookupKey = Symbol("lookup");
|
|
532
532
|
var compilerInfoByDir = /* @__PURE__ */ new Map();
|
|
533
|
+
var builtinInfo = {
|
|
534
|
+
cache: /* @__PURE__ */ new Map(),
|
|
535
|
+
lookup: builtinCompiler.taglib.buildLookup(__dirname, builtinTranslator),
|
|
536
|
+
compiler: builtinCompiler,
|
|
537
|
+
translator: builtinTranslator
|
|
538
|
+
};
|
|
533
539
|
builtinCompiler.configure({ translator: builtinTranslator });
|
|
534
540
|
function parse2(doc) {
|
|
535
541
|
const compilerInfo = getCompilerInfo(doc);
|
|
@@ -542,6 +548,8 @@ function parse2(doc) {
|
|
|
542
548
|
}
|
|
543
549
|
function getCompilerInfo(doc) {
|
|
544
550
|
const dir = getDocDir(doc);
|
|
551
|
+
if (!dir)
|
|
552
|
+
return builtinInfo;
|
|
545
553
|
let info = compilerInfoByDir.get(dir);
|
|
546
554
|
if (!info) {
|
|
547
555
|
info = loadCompilerInfo(dir);
|
|
@@ -549,25 +557,14 @@ function getCompilerInfo(doc) {
|
|
|
549
557
|
}
|
|
550
558
|
return info;
|
|
551
559
|
}
|
|
552
|
-
function
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
if (document.uri.endsWith(".marko")) {
|
|
560
|
-
(_a = getCompilerInfo(document)) == null ? void 0 : _a.cache.delete(document);
|
|
561
|
-
} else if (/[./\\]marko(?:-tag)?\.json$/.test(document.uri)) {
|
|
562
|
-
clearAllCaches();
|
|
563
|
-
}
|
|
560
|
+
function clearCompilerCache(doc) {
|
|
561
|
+
if (doc) {
|
|
562
|
+
getCompilerInfo(doc).cache.delete(doc);
|
|
563
|
+
} else {
|
|
564
|
+
for (const [, info] of compilerInfoByDir) {
|
|
565
|
+
info.cache.clear();
|
|
566
|
+
info.compiler.taglib.clearCaches();
|
|
564
567
|
}
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
function clearAllCaches() {
|
|
568
|
-
for (const [, info] of compilerInfoByDir) {
|
|
569
|
-
info.cache.clear();
|
|
570
|
-
info.compiler.taglib.clearCaches();
|
|
571
568
|
}
|
|
572
569
|
}
|
|
573
570
|
function loadCompilerInfo(dir) {
|
|
@@ -598,7 +595,7 @@ function loadCompilerInfo(dir) {
|
|
|
598
595
|
try {
|
|
599
596
|
lookup = compiler.taglib.buildLookup(dir, translator);
|
|
600
597
|
} catch {
|
|
601
|
-
lookup =
|
|
598
|
+
lookup = builtinInfo.lookup;
|
|
602
599
|
}
|
|
603
600
|
cache2.set(lookupKey, lookup);
|
|
604
601
|
}
|
|
@@ -612,7 +609,7 @@ function loadCompilerInfo(dir) {
|
|
|
612
609
|
// src/utils/messages.ts
|
|
613
610
|
import { inspect } from "util";
|
|
614
611
|
var connection;
|
|
615
|
-
function
|
|
612
|
+
function setup(_) {
|
|
616
613
|
connection = _;
|
|
617
614
|
}
|
|
618
615
|
function displayError(data) {
|
|
@@ -692,8 +689,6 @@ function OpenTagName({
|
|
|
692
689
|
parsed,
|
|
693
690
|
node
|
|
694
691
|
}) {
|
|
695
|
-
if (!lookup)
|
|
696
|
-
return;
|
|
697
692
|
const currentTemplateFilePath = getDocFile(document);
|
|
698
693
|
const tag = node.parent;
|
|
699
694
|
const tagNameLocation = parsed.locationAt(node);
|
|
@@ -718,7 +713,7 @@ function OpenTagName({
|
|
|
718
713
|
kind: MarkupKind.Markdown,
|
|
719
714
|
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
715
|
|
|
721
|
-
[${path2.relative(currentTemplateFilePath, fileForTag)}](${fileURIForTag})`
|
|
716
|
+
[${currentTemplateFilePath ? path2.relative(currentTemplateFilePath, fileForTag) : currentTemplateFilePath}](${fileURIForTag})`
|
|
722
717
|
};
|
|
723
718
|
if (it.description) {
|
|
724
719
|
documentation.value += `
|
|
@@ -787,8 +782,6 @@ function AttrName({
|
|
|
787
782
|
name = name.slice(0, modifierIndex);
|
|
788
783
|
}
|
|
789
784
|
}
|
|
790
|
-
if (!lookup)
|
|
791
|
-
return;
|
|
792
785
|
const completions = [];
|
|
793
786
|
const attrNameLoc = parsed.locationAt(hasModifier ? {
|
|
794
787
|
start: node.start,
|
|
@@ -886,31 +879,27 @@ var doComplete = async (doc, params) => {
|
|
|
886
879
|
};
|
|
887
880
|
|
|
888
881
|
// src/service/marko/validate.ts
|
|
889
|
-
import { URI as URI3 } from "vscode-uri";
|
|
890
882
|
import { Diagnostic, DiagnosticSeverity, Range as Range2 } from "vscode-languageserver";
|
|
891
883
|
var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
|
|
892
884
|
var doValidate = (doc) => {
|
|
893
|
-
const
|
|
885
|
+
const fsPath = getDocFile(doc);
|
|
894
886
|
const diagnostics = [];
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
|
|
912
|
-
}
|
|
913
|
-
}
|
|
887
|
+
const { compiler, translator, cache: cache2 } = getCompilerInfo(doc);
|
|
888
|
+
try {
|
|
889
|
+
compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
|
|
890
|
+
cache: cache2,
|
|
891
|
+
translator,
|
|
892
|
+
code: false,
|
|
893
|
+
output: "source",
|
|
894
|
+
sourceMaps: false
|
|
895
|
+
});
|
|
896
|
+
} catch (e) {
|
|
897
|
+
let match;
|
|
898
|
+
while (match = markoErrorRegExp.exec(e.message)) {
|
|
899
|
+
const [, fileName, rawLine, rawCol, msg] = match;
|
|
900
|
+
const line = (parseInt(rawLine, 10) || 1) - 1;
|
|
901
|
+
const col = (parseInt(rawCol, 10) || 1) - 1;
|
|
902
|
+
diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
|
|
914
903
|
}
|
|
915
904
|
}
|
|
916
905
|
return diagnostics;
|
|
@@ -918,7 +907,7 @@ var doValidate = (doc) => {
|
|
|
918
907
|
|
|
919
908
|
// src/service/marko/definition/OpenTagName.ts
|
|
920
909
|
import path3 from "path";
|
|
921
|
-
import { URI as
|
|
910
|
+
import { URI as URI4 } from "vscode-uri";
|
|
922
911
|
import { Range as Range4, LocationLink } from "vscode-languageserver";
|
|
923
912
|
|
|
924
913
|
// src/utils/regexp-builder.ts
|
|
@@ -947,12 +936,12 @@ function escape(val) {
|
|
|
947
936
|
|
|
948
937
|
// src/utils/utils.ts
|
|
949
938
|
import fs from "fs";
|
|
950
|
-
import { URI as
|
|
939
|
+
import { URI as URI3 } from "vscode-uri";
|
|
951
940
|
import { Position, Range as Range3 } from "vscode-languageserver";
|
|
952
941
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
953
942
|
var START_OF_FILE = Range3.create(Position.create(0, 0), Position.create(0, 0));
|
|
954
943
|
function createTextDocument(filename) {
|
|
955
|
-
const uri =
|
|
944
|
+
const uri = URI3.file(filename).toString();
|
|
956
945
|
const content = fs.readFileSync(filename, "utf-8");
|
|
957
946
|
return TextDocument.create(uri, "plaintext", 0, content);
|
|
958
947
|
}
|
|
@@ -963,8 +952,6 @@ function OpenTagName2({
|
|
|
963
952
|
parsed,
|
|
964
953
|
node
|
|
965
954
|
}) {
|
|
966
|
-
if (!lookup)
|
|
967
|
-
return;
|
|
968
955
|
const tag = node.parent;
|
|
969
956
|
let tagDef;
|
|
970
957
|
let range = START_OF_FILE;
|
|
@@ -991,20 +978,18 @@ function OpenTagName2({
|
|
|
991
978
|
}
|
|
992
979
|
}
|
|
993
980
|
return [
|
|
994
|
-
LocationLink.create(
|
|
981
|
+
LocationLink.create(URI4.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
|
|
995
982
|
];
|
|
996
983
|
}
|
|
997
984
|
|
|
998
985
|
// src/service/marko/definition/AttrName.ts
|
|
999
|
-
import { URI as
|
|
986
|
+
import { URI as URI5 } from "vscode-uri";
|
|
1000
987
|
import { Range as Range5, LocationLink as LocationLink2 } from "vscode-languageserver";
|
|
1001
988
|
function AttrName2({
|
|
1002
989
|
lookup,
|
|
1003
990
|
parsed,
|
|
1004
991
|
node
|
|
1005
992
|
}) {
|
|
1006
|
-
if (!lookup)
|
|
1007
|
-
return;
|
|
1008
993
|
const tagName = node.parent.parent.nameText;
|
|
1009
994
|
const attrName = parsed.read(node);
|
|
1010
995
|
if (attrName[0] === "{")
|
|
@@ -1027,7 +1012,7 @@ function AttrName2({
|
|
|
1027
1012
|
}
|
|
1028
1013
|
}
|
|
1029
1014
|
return [
|
|
1030
|
-
LocationLink2.create(
|
|
1015
|
+
LocationLink2.create(URI5.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
|
|
1031
1016
|
];
|
|
1032
1017
|
}
|
|
1033
1018
|
|
|
@@ -1054,7 +1039,7 @@ var findDefinition = async (doc, params) => {
|
|
|
1054
1039
|
|
|
1055
1040
|
// src/service/marko/format.ts
|
|
1056
1041
|
import { Position as Position2, Range as Range6, TextEdit as TextEdit4 } from "vscode-languageserver";
|
|
1057
|
-
import { URI as
|
|
1042
|
+
import { URI as URI6 } from "vscode-uri";
|
|
1058
1043
|
import * as prettier from "prettier";
|
|
1059
1044
|
import * as markoPrettier from "prettier-plugin-marko";
|
|
1060
1045
|
var NO_EDIT = [
|
|
@@ -1062,7 +1047,7 @@ var NO_EDIT = [
|
|
|
1062
1047
|
];
|
|
1063
1048
|
var format2 = async (doc, params, token) => {
|
|
1064
1049
|
try {
|
|
1065
|
-
const { fsPath, scheme } =
|
|
1050
|
+
const { fsPath, scheme } = URI6.parse(doc.uri);
|
|
1066
1051
|
const text = doc.getText();
|
|
1067
1052
|
const options = {
|
|
1068
1053
|
parser: "marko",
|
|
@@ -1276,7 +1261,7 @@ var stylesheet_default = {
|
|
|
1276
1261
|
if (generatedOffset === void 0)
|
|
1277
1262
|
continue;
|
|
1278
1263
|
const { service: service2, virtualDoc } = info;
|
|
1279
|
-
const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset),
|
|
1264
|
+
const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
|
|
1280
1265
|
for (const item of result.items) {
|
|
1281
1266
|
if (item.additionalTextEdits) {
|
|
1282
1267
|
for (const edit of item.additionalTextEdits) {
|
|
@@ -1315,13 +1300,28 @@ var stylesheet_default = {
|
|
|
1315
1300
|
if (generatedOffset === void 0)
|
|
1316
1301
|
continue;
|
|
1317
1302
|
const { service: service2, virtualDoc } = info;
|
|
1318
|
-
const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset),
|
|
1303
|
+
const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
|
|
1319
1304
|
if (result && updateRange(doc, info, result.range)) {
|
|
1320
1305
|
return result;
|
|
1321
1306
|
}
|
|
1322
1307
|
break;
|
|
1323
1308
|
}
|
|
1324
1309
|
},
|
|
1310
|
+
async doHover(doc, params) {
|
|
1311
|
+
const infoByExt = getStyleSheetInfo(doc);
|
|
1312
|
+
const sourceOffset = doc.offsetAt(params.position);
|
|
1313
|
+
for (const ext in infoByExt) {
|
|
1314
|
+
const info = infoByExt[ext];
|
|
1315
|
+
const generatedOffset = info.generatedOffsetAt(sourceOffset);
|
|
1316
|
+
if (generatedOffset === void 0)
|
|
1317
|
+
continue;
|
|
1318
|
+
const { service: service2, virtualDoc } = info;
|
|
1319
|
+
const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), service2.parseStylesheet(virtualDoc));
|
|
1320
|
+
if (result && (!result.range || updateRange(doc, info, result.range))) {
|
|
1321
|
+
return result;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
1325
|
async doValidate(doc) {
|
|
1326
1326
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1327
1327
|
const result = [];
|
|
@@ -1427,6 +1427,20 @@ var service = {
|
|
|
1427
1427
|
}
|
|
1428
1428
|
return result;
|
|
1429
1429
|
},
|
|
1430
|
+
async doHover(doc, params, cancel) {
|
|
1431
|
+
var _a;
|
|
1432
|
+
try {
|
|
1433
|
+
for (const plugin of plugins) {
|
|
1434
|
+
const result = await ((_a = plugin.doHover) == null ? void 0 : _a.call(plugin, doc, params, cancel));
|
|
1435
|
+
if (cancel.isCancellationRequested)
|
|
1436
|
+
return;
|
|
1437
|
+
if (result)
|
|
1438
|
+
return result;
|
|
1439
|
+
}
|
|
1440
|
+
} catch (err) {
|
|
1441
|
+
displayError(err);
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1430
1444
|
async doValidate(doc) {
|
|
1431
1445
|
const result = [];
|
|
1432
1446
|
try {
|
|
@@ -1453,8 +1467,9 @@ if (typeof __require !== "undefined" && __require.extensions && !(".ts" in __req
|
|
|
1453
1467
|
}
|
|
1454
1468
|
var documents = new TextDocuments(TextDocument3);
|
|
1455
1469
|
var connection2 = createConnection(ProposedFeatures.all);
|
|
1456
|
-
var
|
|
1457
|
-
var
|
|
1470
|
+
var prevDiags = /* @__PURE__ */ new WeakMap();
|
|
1471
|
+
var pendingDiags = /* @__PURE__ */ new WeakSet();
|
|
1472
|
+
var diagnosticTimeout;
|
|
1458
1473
|
console.log = (...args) => {
|
|
1459
1474
|
connection2.console.log(args.map((v) => inspect2(v)).join(" "));
|
|
1460
1475
|
};
|
|
@@ -1464,13 +1479,13 @@ console.error = (...args) => {
|
|
|
1464
1479
|
process.on("uncaughtException", console.error);
|
|
1465
1480
|
process.on("unhandledRejection", console.error);
|
|
1466
1481
|
connection2.onInitialize(() => {
|
|
1467
|
-
|
|
1468
|
-
setup(connection2, documents);
|
|
1482
|
+
setup(connection2);
|
|
1469
1483
|
return {
|
|
1470
1484
|
capabilities: {
|
|
1471
1485
|
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
1472
1486
|
documentFormattingProvider: true,
|
|
1473
1487
|
definitionProvider: true,
|
|
1488
|
+
hoverProvider: true,
|
|
1474
1489
|
completionProvider: {
|
|
1475
1490
|
triggerCharacters: [
|
|
1476
1491
|
".",
|
|
@@ -1497,11 +1512,12 @@ connection2.onInitialize(() => {
|
|
|
1497
1512
|
}
|
|
1498
1513
|
};
|
|
1499
1514
|
});
|
|
1500
|
-
connection2.
|
|
1501
|
-
|
|
1502
|
-
})
|
|
1503
|
-
|
|
1504
|
-
|
|
1515
|
+
connection2.onDidChangeConfiguration(validateDocs);
|
|
1516
|
+
connection2.onDidChangeWatchedFiles(validateDocs);
|
|
1517
|
+
documents.onDidChangeContent(({ document }) => {
|
|
1518
|
+
queueDiagnostic();
|
|
1519
|
+
pendingDiags.add(document);
|
|
1520
|
+
clearCompilerCache(document);
|
|
1505
1521
|
});
|
|
1506
1522
|
connection2.onCompletion(async (params, cancel) => {
|
|
1507
1523
|
return await service.doComplete(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
@@ -1509,24 +1525,44 @@ connection2.onCompletion(async (params, cancel) => {
|
|
|
1509
1525
|
connection2.onDefinition(async (params, cancel) => {
|
|
1510
1526
|
return await service.findDefinition(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
1511
1527
|
});
|
|
1528
|
+
connection2.onHover(async (params, cancel) => {
|
|
1529
|
+
return await service.doHover(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
1530
|
+
});
|
|
1512
1531
|
connection2.onDocumentFormatting(async (params, cancel) => {
|
|
1513
1532
|
return await service.format(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
1514
1533
|
});
|
|
1515
|
-
function
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1534
|
+
function validateDocs() {
|
|
1535
|
+
queueDiagnostic();
|
|
1536
|
+
clearCompilerCache();
|
|
1537
|
+
for (const doc of documents.all()) {
|
|
1538
|
+
pendingDiags.add(doc);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
function queueDiagnostic() {
|
|
1542
|
+
clearTimeout(diagnosticTimeout);
|
|
1543
|
+
const id = diagnosticTimeout = setTimeout(async () => {
|
|
1544
|
+
const results = await Promise.all(documents.all().map(async (doc) => {
|
|
1545
|
+
if (!pendingDiags.delete(doc))
|
|
1546
|
+
return;
|
|
1547
|
+
const prevDiag = prevDiags.get(doc) || [];
|
|
1548
|
+
const nextDiag = await service.doValidate(doc) || [];
|
|
1549
|
+
if (isDeepStrictEqual(prevDiag, nextDiag))
|
|
1550
|
+
return;
|
|
1551
|
+
return [doc, nextDiag];
|
|
1552
|
+
}));
|
|
1553
|
+
if (id === diagnosticTimeout) {
|
|
1554
|
+
for (const result of results) {
|
|
1555
|
+
if (result) {
|
|
1556
|
+
const [doc, diag] = result;
|
|
1557
|
+
prevDiags.set(doc, diag);
|
|
1558
|
+
connection2.sendDiagnostics({
|
|
1559
|
+
uri: doc.uri,
|
|
1560
|
+
diagnostics: diag
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1522
1564
|
}
|
|
1523
|
-
prevDiagnostics.set(doc, nextDiag);
|
|
1524
|
-
connection2.sendDiagnostics({
|
|
1525
|
-
uri: doc.uri,
|
|
1526
|
-
diagnostics: nextDiag
|
|
1527
|
-
});
|
|
1528
1565
|
}, 400);
|
|
1529
|
-
diagnosticTimeouts.set(doc, id);
|
|
1530
1566
|
}
|
|
1531
1567
|
documents.listen(connection2);
|
|
1532
1568
|
connection2.listen();
|