luaut-language-server 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-SXRYJV32.js → chunk-X2GHHRWT.js} +78 -14
- package/dist/chunk-X2GHHRWT.js.map +1 -0
- package/dist/cli.cjs +73 -10
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +73 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-SXRYJV32.js.map +0 -1
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -819,11 +819,28 @@ var import_luaut_parser4 = require("luaut-parser");
|
|
|
819
819
|
function hover(analysis, position) {
|
|
820
820
|
const path = pathAt(analysis.program, position, true);
|
|
821
821
|
for (let i = path.length - 1; i >= 0; i--) {
|
|
822
|
+
if (UNNAMED.has(path[i].type)) return null;
|
|
822
823
|
const text = describe(analysis, path, i);
|
|
823
824
|
if (text) return { contents: { kind: "markdown", value: code(text) }, range: toRange(path[i]) };
|
|
824
825
|
}
|
|
825
826
|
return null;
|
|
826
827
|
}
|
|
828
|
+
var UNNAMED = /* @__PURE__ */ new Set([
|
|
829
|
+
"BinaryExpression",
|
|
830
|
+
"UnaryExpression",
|
|
831
|
+
"CallExpression",
|
|
832
|
+
"MethodCallExpression",
|
|
833
|
+
"MemberExpression",
|
|
834
|
+
"IndexExpression",
|
|
835
|
+
"ParenthesizedExpression",
|
|
836
|
+
"IfElseExpression",
|
|
837
|
+
"TableExpression",
|
|
838
|
+
"ArrayExpression",
|
|
839
|
+
"TypeAssertionExpression",
|
|
840
|
+
"SatisfiesExpression",
|
|
841
|
+
"AsConstExpression",
|
|
842
|
+
"InterpolatedStringExpression"
|
|
843
|
+
]);
|
|
827
844
|
var PRIMITIVES = /* @__PURE__ */ new Set(["any", "unknown", "never", "nil", "boolean", "number", "string", "thread", "buffer"]);
|
|
828
845
|
function describe(analysis, path, index) {
|
|
829
846
|
const { types } = analysis;
|
|
@@ -865,6 +882,9 @@ function describe(analysis, path, index) {
|
|
|
865
882
|
case "DeclareStatement":
|
|
866
883
|
if (parent.id === node) return declareText(analysis, parent);
|
|
867
884
|
break;
|
|
885
|
+
case "DeclareClassStatement":
|
|
886
|
+
if (parent.name === node) return classText(analysis, name);
|
|
887
|
+
break;
|
|
868
888
|
case "TableTypeProperty":
|
|
869
889
|
if (parent.key === node) {
|
|
870
890
|
const type2 = typeOfNode(parent.valueType);
|
|
@@ -896,7 +916,7 @@ function describe(analysis, path, index) {
|
|
|
896
916
|
const binding = bindingOfNode(analysis, identifier2);
|
|
897
917
|
if (binding) {
|
|
898
918
|
const type2 = types.bindingType.get(binding.id);
|
|
899
|
-
if (type2) return
|
|
919
|
+
if (type2) return bindingText(binding, type2);
|
|
900
920
|
}
|
|
901
921
|
if (parent?.type === "MemberExpression" || parent?.type === "MethodCallExpression") {
|
|
902
922
|
const type2 = types.typeOf.get(parent);
|
|
@@ -904,13 +924,13 @@ function describe(analysis, path, index) {
|
|
|
904
924
|
}
|
|
905
925
|
return void 0;
|
|
906
926
|
}
|
|
907
|
-
// Declarations: `const x`, a parameter
|
|
927
|
+
// Declarations: `const x`, a parameter.
|
|
908
928
|
case "IdentifierPattern":
|
|
909
929
|
case "FunctionParameter":
|
|
910
930
|
case "TypedIdentifier": {
|
|
911
931
|
const binding = bindingOfNode(analysis, node);
|
|
912
932
|
const type2 = binding && types.bindingType.get(binding.id);
|
|
913
|
-
return type2 ?
|
|
933
|
+
return type2 ? bindingText(binding, type2) : void 0;
|
|
914
934
|
}
|
|
915
935
|
// A type written by name: `number`, `Shape`, `Partial<User>`, or a type
|
|
916
936
|
// parameter in scope.
|
|
@@ -921,9 +941,11 @@ function describe(analysis, path, index) {
|
|
|
921
941
|
if (parameter) return typeParameterText(analysis, parameter);
|
|
922
942
|
if (PRIMITIVES.has(base)) return `type ${base}`;
|
|
923
943
|
}
|
|
924
|
-
if (!node.
|
|
925
|
-
const
|
|
926
|
-
|
|
944
|
+
if (!node.typeArguments.length) {
|
|
945
|
+
const qualified = node.namespace ? `${node.namespace}.${base}` : base;
|
|
946
|
+
const alias = types.aliases.get(qualified);
|
|
947
|
+
if (alias && (0, import_luaut_parser4.isClassType)(alias)) return classText(analysis, qualified);
|
|
948
|
+
if (alias) return `type ${qualified} = ${pretty(alias)}`;
|
|
927
949
|
}
|
|
928
950
|
const type2 = typeOfNode(node);
|
|
929
951
|
return type2 && `type ${referenceText(analysis, node)} = ${pretty(type2)}`;
|
|
@@ -952,6 +974,19 @@ function declareText(analysis, statement) {
|
|
|
952
974
|
const overloads = others > 0 ? ` (+${others} overload${others > 1 ? "s" : ""})` : "";
|
|
953
975
|
return `declare function ${name}${(0, import_luaut_parser4.formatType)(own)}${overloads}`;
|
|
954
976
|
}
|
|
977
|
+
function classText(analysis, name) {
|
|
978
|
+
const type = analysis.types.aliases.get(name);
|
|
979
|
+
if (!type || !(0, import_luaut_parser4.isClassType)(type)) return void 0;
|
|
980
|
+
const superclass = type.class.superclass;
|
|
981
|
+
const inherited = superclass ? analysis.types.aliases.get(superclass) : void 0;
|
|
982
|
+
const own = [...type.properties].filter(([key, property]) => inherited?.kind !== "object" || inherited.properties.get(key) !== property);
|
|
983
|
+
const head = `declare class ${name}${superclass ? ` extends ${superclass}` : ""}`;
|
|
984
|
+
if (!own.length) return `${head} {}`;
|
|
985
|
+
const lines = own.map(([key, property]) => ` ${property.readonly ? "readonly " : ""}${key}${property.optional ? "?" : ""}: ${(0, import_luaut_parser4.formatType)(property.type)},`);
|
|
986
|
+
return `${head} {
|
|
987
|
+
${lines.join("\n")}
|
|
988
|
+
}`;
|
|
989
|
+
}
|
|
955
990
|
function typeParameterText(analysis, parameter) {
|
|
956
991
|
return `(type parameter) ${typeParameterSignature(analysis, parameter)}`;
|
|
957
992
|
}
|
|
@@ -1011,10 +1046,19 @@ ${lines.join("\n")}
|
|
|
1011
1046
|
}
|
|
1012
1047
|
return flat;
|
|
1013
1048
|
}
|
|
1049
|
+
function bindingText(binding, type) {
|
|
1050
|
+
if (binding.declaredBy === "function" && type.kind === "function") {
|
|
1051
|
+
return `function ${binding.name}${(0, import_luaut_parser4.formatType)(type)}`;
|
|
1052
|
+
}
|
|
1053
|
+
return `${keyword(binding)} ${binding.name}: ${pretty(type)}`;
|
|
1054
|
+
}
|
|
1014
1055
|
function keyword(binding) {
|
|
1015
1056
|
if (binding.kind === "param" || binding.kind === "self") return "(parameter)";
|
|
1016
1057
|
if (binding.kind === "global") return "(global)";
|
|
1017
1058
|
if (binding.kind.startsWith("for-")) return "(loop variable)";
|
|
1059
|
+
if (binding.declaredBy === "import" || binding.declaredBy === "namespace") return "(import)";
|
|
1060
|
+
if (binding.declaredBy === "type") return "(type import)";
|
|
1061
|
+
if (binding.declaredBy === "function") return "function";
|
|
1018
1062
|
return binding.isConst ? "const" : "let";
|
|
1019
1063
|
}
|
|
1020
1064
|
function code(text) {
|
|
@@ -1116,10 +1160,10 @@ function completion(analyzer, document, position) {
|
|
|
1116
1160
|
}
|
|
1117
1161
|
if (operator || !first) return [];
|
|
1118
1162
|
if (inTypePosition(first.path)) {
|
|
1119
|
-
const named = [...first.analysis.types.aliases
|
|
1163
|
+
const named = [...first.analysis.types.aliases].map(([name, type]) => ({
|
|
1120
1164
|
label: name,
|
|
1121
|
-
kind: import_vscode_languageserver4.CompletionItemKind.Interface,
|
|
1122
|
-
detail: "type"
|
|
1165
|
+
kind: (0, import_luaut_parser5.isClassType)(type) ? import_vscode_languageserver4.CompletionItemKind.Class : import_vscode_languageserver4.CompletionItemKind.Interface,
|
|
1166
|
+
detail: (0, import_luaut_parser5.isClassType)(type) ? "class" : "type"
|
|
1123
1167
|
}));
|
|
1124
1168
|
const primitives = PRIMITIVES2.map((name) => ({
|
|
1125
1169
|
label: name,
|
|
@@ -1210,6 +1254,7 @@ function valueItems(analysis, at) {
|
|
|
1210
1254
|
const seen = /* @__PURE__ */ new Set();
|
|
1211
1255
|
for (const binding of analysis.scopes.bindings.values()) {
|
|
1212
1256
|
if (binding.name === PLACEHOLDER || seen.has(binding.name)) continue;
|
|
1257
|
+
if (binding.declaredBy === "type") continue;
|
|
1213
1258
|
const declaration = binding.declarationNode;
|
|
1214
1259
|
if (declaration && declaration.line.start - 1 > at.line) continue;
|
|
1215
1260
|
seen.add(binding.name);
|
|
@@ -1251,7 +1296,7 @@ function kindOf(type, bindingKind) {
|
|
|
1251
1296
|
}
|
|
1252
1297
|
function inTypePosition(path) {
|
|
1253
1298
|
return path.some(
|
|
1254
|
-
(n) => !!n.type && (n.type.endsWith("TypeNode") || n.type === "TypeReference" || n.type === "TypeAliasStatement" || n.type === "ExportTypeAliasStatement")
|
|
1299
|
+
(n) => !!n.type && (n.type.endsWith("TypeNode") || n.type === "TypeReference" || n.type === "TypeAliasStatement" || n.type === "ExportTypeAliasStatement" || n.type === "DeclareClassStatement")
|
|
1255
1300
|
);
|
|
1256
1301
|
}
|
|
1257
1302
|
var PRIMITIVES2 = [
|
|
@@ -1392,6 +1437,12 @@ function documentSymbols(analysis) {
|
|
|
1392
1437
|
}
|
|
1393
1438
|
break;
|
|
1394
1439
|
}
|
|
1440
|
+
case "DeclareClassStatement": {
|
|
1441
|
+
const name = node.name.name;
|
|
1442
|
+
const superclass = node.superclass?.base;
|
|
1443
|
+
out.push(symbol(name, import_vscode_languageserver5.SymbolKind.Class, node, superclass && `extends ${superclass}`));
|
|
1444
|
+
break;
|
|
1445
|
+
}
|
|
1395
1446
|
case "VariableDeclaration": {
|
|
1396
1447
|
for (const target of node.names ?? []) {
|
|
1397
1448
|
const name = target.name;
|
|
@@ -1433,6 +1484,7 @@ var import_luaut_parser7 = require("luaut-parser");
|
|
|
1433
1484
|
var TOKEN_TYPES = [
|
|
1434
1485
|
"namespace",
|
|
1435
1486
|
"type",
|
|
1487
|
+
"class",
|
|
1436
1488
|
"typeParameter",
|
|
1437
1489
|
"parameter",
|
|
1438
1490
|
"variable",
|
|
@@ -1449,6 +1501,7 @@ var semanticTokensLegend = {
|
|
|
1449
1501
|
var SOFT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
1450
1502
|
"type",
|
|
1451
1503
|
"declare",
|
|
1504
|
+
"class",
|
|
1452
1505
|
"extends",
|
|
1453
1506
|
"keyof",
|
|
1454
1507
|
"infer",
|
|
@@ -1515,6 +1568,8 @@ function classify(analysis, spanned, ancestors, identifiers, add) {
|
|
|
1515
1568
|
if (!baseToken) return;
|
|
1516
1569
|
if (!namespace && typeParameterInScope2(ancestors, base)) {
|
|
1517
1570
|
add(baseToken, base.length, "typeParameter");
|
|
1571
|
+
} else if ((0, import_luaut_parser7.isClassType)(analysis.types.aliases.get(namespace ? `${namespace}.${base}` : base) ?? import_luaut_parser7.unknownType)) {
|
|
1572
|
+
add(baseToken, base.length, "class");
|
|
1518
1573
|
} else {
|
|
1519
1574
|
add(baseToken, base.length, "type", PRIMITIVES3.has(base) ? ["defaultLibrary"] : []);
|
|
1520
1575
|
}
|
|
@@ -1542,6 +1597,9 @@ function identifier(analysis, node, parent, add) {
|
|
|
1542
1597
|
case "ExportTypeAliasStatement":
|
|
1543
1598
|
if (parent.name === node) return as("type", ["declaration"]);
|
|
1544
1599
|
break;
|
|
1600
|
+
case "DeclareClassStatement":
|
|
1601
|
+
if (parent.name === node) return as("class", ["declaration"]);
|
|
1602
|
+
break;
|
|
1545
1603
|
case "DeclareStatement":
|
|
1546
1604
|
if (parent.id === node) return as(isFunction(typeOfNode(parent.valueType)) ? "function" : "variable", ["declaration"]);
|
|
1547
1605
|
break;
|
|
@@ -1565,10 +1623,14 @@ function identifier(analysis, node, parent, add) {
|
|
|
1565
1623
|
break;
|
|
1566
1624
|
case "ImportSpecifier": {
|
|
1567
1625
|
const binding2 = bindingOfNode(analysis, node);
|
|
1626
|
+
if (binding2?.declaredBy === "type") return as("type", ["declaration"]);
|
|
1568
1627
|
const value = binding2 && analysis.types.bindingType.get(binding2.id);
|
|
1569
1628
|
if (analysis.types.aliases.has(name) && (!value || value.kind === "any")) return as("type", ["declaration"]);
|
|
1570
1629
|
break;
|
|
1571
1630
|
}
|
|
1631
|
+
case "ImportStatement":
|
|
1632
|
+
if (parent.namespaceImport === node) return as("namespace", ["declaration"]);
|
|
1633
|
+
break;
|
|
1572
1634
|
case "ExportSpecifier":
|
|
1573
1635
|
if (!bindingOfNode(analysis, node) && analysis.types.aliases.has(name)) return as("type");
|
|
1574
1636
|
break;
|
|
@@ -1584,6 +1646,7 @@ function identifier(analysis, node, parent, add) {
|
|
|
1584
1646
|
function valueKind(analysis, binding) {
|
|
1585
1647
|
if (!binding) return "variable";
|
|
1586
1648
|
if (binding.kind === "param" || binding.kind === "self") return "parameter";
|
|
1649
|
+
if (binding.declaredBy === "namespace") return "namespace";
|
|
1587
1650
|
return isFunction(analysis.types.bindingType.get(binding.id)) ? "function" : "variable";
|
|
1588
1651
|
}
|
|
1589
1652
|
function modifiersOf(binding, isDeclaration) {
|