@tilua/parser 1.0.1 → 1.1.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 +20 -0
- package/dist/index.cjs +72 -7
- package/dist/index.d.cts +105 -9
- package/dist/index.d.ts +105 -9
- package/dist/index.js +72 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -298,6 +298,18 @@ call needed it — and the receiver is passed as the call's first argument. An
|
|
|
298
298
|
answer of `undefined` leaves an ordinary Luau method call, which is what
|
|
299
299
|
`text:upper()` wants, since a string already answers to it.
|
|
300
300
|
|
|
301
|
+
A call can also carry more than was written. Every hook is told `at`, where
|
|
302
|
+
the call was written (`{ file, line, column }`), and `arguments`: each one's
|
|
303
|
+
type, that type as text, the code it was written as, and, for a name, the
|
|
304
|
+
code of what it names. An answer's `prepend` lists Luau expressions to pass
|
|
305
|
+
ahead of the written arguments. `globalCall` answers for a call to a global,
|
|
306
|
+
such as `print(x)`, and `globalValue` for a global read as a value, such as
|
|
307
|
+
`local p = print`. A local with the same name belongs to the author, and no
|
|
308
|
+
hook is asked about it. A runtime can read `__LINES__`, the bundle's line map
|
|
309
|
+
(`nil` outside a bundle), to turn a line Luau reports back into a place in the
|
|
310
|
+
project. `console:log`, `print` and `error` in `@tilua-types/lua` are built on
|
|
311
|
+
these hooks.
|
|
312
|
+
|
|
301
313
|
The compiler lowers the language and nothing else: `filter` appears nowhere in
|
|
302
314
|
it.
|
|
303
315
|
|
|
@@ -406,6 +418,14 @@ method's type is `(this: Dog, ...) => R`, so `rex:speak()` supplies it the way
|
|
|
406
418
|
`function T:m()` supplies `self`. `new Dog(x)` *is* `Dog.new(x)` — the same
|
|
407
419
|
function, callable by hand and passable as a value.
|
|
408
420
|
|
|
421
|
+
**`public` and `private`** go before a member — `private balance = 0`,
|
|
422
|
+
`private static function check()`, `public get size()`. Leaving it out means
|
|
423
|
+
public. A private member can be reached only inside the body of the class that
|
|
424
|
+
declared it, including functions nested in its methods; a subclass is outside,
|
|
425
|
+
as in TypeScript. It is a type check and nothing more: the member is an
|
|
426
|
+
ordinary key at runtime. `public` and `private` stay ordinary names elsewhere,
|
|
427
|
+
so `private: boolean` is still a field.
|
|
428
|
+
|
|
409
429
|
A declaration names two things. As a **type**, `Dog` is the type of its
|
|
410
430
|
instances, nominal the same way a `declare class` is: a table with the same
|
|
411
431
|
members is not one, and only `Dog` and what extends it are assignable to it.
|
package/dist/index.cjs
CHANGED
|
@@ -1830,6 +1830,19 @@ var Parser = class {
|
|
|
1830
1830
|
}
|
|
1831
1831
|
parseClassMember() {
|
|
1832
1832
|
const start = this.current();
|
|
1833
|
+
let accessibility;
|
|
1834
|
+
if ((this.checkIdentifierValue("public") || this.checkIdentifierValue("private")) && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=") && !this.punctuatorAt(1, "(")) {
|
|
1835
|
+
accessibility = this.advance().value;
|
|
1836
|
+
}
|
|
1837
|
+
const member = this.parseClassMemberAfterAccessibility(start);
|
|
1838
|
+
if (!accessibility || !member) return member;
|
|
1839
|
+
if (member.type === "ClassConstructor") {
|
|
1840
|
+
this.problem(`A constructor cannot be '${accessibility}'`);
|
|
1841
|
+
return member;
|
|
1842
|
+
}
|
|
1843
|
+
return { ...member, accessibility };
|
|
1844
|
+
}
|
|
1845
|
+
parseClassMemberAfterAccessibility(start) {
|
|
1833
1846
|
const isStatic = this.checkIdentifierValue("static") && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=");
|
|
1834
1847
|
if (isStatic) this.advance();
|
|
1835
1848
|
if (this.checkKeyword("function")) {
|
|
@@ -4498,7 +4511,12 @@ function substitute(t, subst) {
|
|
|
4498
4511
|
return t.name && r.kind === "intersection" && !r.name ? { ...r, name: t.name } : r;
|
|
4499
4512
|
}
|
|
4500
4513
|
case "genericRef":
|
|
4501
|
-
return {
|
|
4514
|
+
return {
|
|
4515
|
+
kind: "genericRef",
|
|
4516
|
+
name: t.name,
|
|
4517
|
+
typeArguments: t.typeArguments.map((a) => substitute(a, subst)),
|
|
4518
|
+
...t.origin ? { origin: t.origin } : {}
|
|
4519
|
+
};
|
|
4502
4520
|
case "keyof":
|
|
4503
4521
|
return { kind: "keyof", target: substitute(t.target, subst) };
|
|
4504
4522
|
case "templateLiteral":
|
|
@@ -4658,6 +4676,7 @@ function optional(t) {
|
|
|
4658
4676
|
return union([t, nilType]);
|
|
4659
4677
|
}
|
|
4660
4678
|
function widen(t) {
|
|
4679
|
+
if (isAliasNamed(t)) return t;
|
|
4661
4680
|
switch (t.kind) {
|
|
4662
4681
|
case "literal":
|
|
4663
4682
|
return primitive(t.base);
|
|
@@ -4697,7 +4716,7 @@ function isAssignable(rawA, rawB) {
|
|
|
4697
4716
|
if (expandAlias) {
|
|
4698
4717
|
if (a.kind === "genericRef" && b.kind !== "genericRef") a = expandAlias(a);
|
|
4699
4718
|
else if (b.kind === "genericRef" && a.kind !== "genericRef") b = expandAlias(b);
|
|
4700
|
-
else if (a.kind === "genericRef" && b.kind === "genericRef" && a
|
|
4719
|
+
else if (a.kind === "genericRef" && b.kind === "genericRef" && !sameRefTarget(a, b)) {
|
|
4701
4720
|
a = expandAlias(a);
|
|
4702
4721
|
b = expandAlias(b);
|
|
4703
4722
|
}
|
|
@@ -4807,10 +4826,17 @@ function isAssignableInner(a, b) {
|
|
|
4807
4826
|
}
|
|
4808
4827
|
if (b.kind === "typeParam") return false;
|
|
4809
4828
|
if (a.kind === "genericRef" || b.kind === "genericRef") {
|
|
4810
|
-
return a.kind === "genericRef" && b.kind === "genericRef" && a
|
|
4829
|
+
return a.kind === "genericRef" && b.kind === "genericRef" && sameRefTarget(a, b) && a.typeArguments.length === b.typeArguments.length && a.typeArguments.every((x, i) => equalTypes(x, b.typeArguments[i]));
|
|
4811
4830
|
}
|
|
4812
4831
|
return false;
|
|
4813
4832
|
}
|
|
4833
|
+
function isAliasNamed(t) {
|
|
4834
|
+
if (t.kind === "object" || t.kind === "intersection") return t.name !== void 0;
|
|
4835
|
+
return t.alias !== void 0;
|
|
4836
|
+
}
|
|
4837
|
+
function sameRefTarget(a, b) {
|
|
4838
|
+
return a.name === b.name && (!a.origin || !b.origin || a.origin === b.origin);
|
|
4839
|
+
}
|
|
4814
4840
|
function isNoValue(t) {
|
|
4815
4841
|
return t.kind === "tuple" && t.elements.length === 0;
|
|
4816
4842
|
}
|
|
@@ -5596,6 +5622,9 @@ var TypeAnalyzer = class {
|
|
|
5596
5622
|
aliases = new AliasMap();
|
|
5597
5623
|
/** Uninstantiated alias definitions, for `Name<Args>` instantiation. */
|
|
5598
5624
|
aliasDefs = /* @__PURE__ */ new Map();
|
|
5625
|
+
/** Put on every ref to one of `aliasDefs`, so a module that imports the
|
|
5626
|
+
* type expands the ref here rather than by its name there. */
|
|
5627
|
+
origin = { expand: (t) => this.expand(t) };
|
|
5599
5628
|
/** See `resolveClass`. */
|
|
5600
5629
|
classTypes = /* @__PURE__ */ new WeakMap();
|
|
5601
5630
|
/** See `instanceType` — one instance type per `class ... end`. */
|
|
@@ -5880,13 +5909,18 @@ var TypeAnalyzer = class {
|
|
|
5880
5909
|
classIdentityCount = 0;
|
|
5881
5910
|
/** The class whose members are being read, so `super` knows its base. */
|
|
5882
5911
|
currentClass;
|
|
5912
|
+
/** Every class whose body the checker is inside, innermost last — what
|
|
5913
|
+
* decides whether a `private` member may be reached. */
|
|
5914
|
+
enclosingClasses = [];
|
|
5883
5915
|
withClass(stmt, fn2) {
|
|
5884
5916
|
const previous = this.currentClass;
|
|
5885
5917
|
this.currentClass = stmt;
|
|
5918
|
+
this.enclosingClasses.push(stmt);
|
|
5886
5919
|
try {
|
|
5887
5920
|
return fn2();
|
|
5888
5921
|
} finally {
|
|
5889
5922
|
this.currentClass = previous;
|
|
5923
|
+
this.enclosingClasses.pop();
|
|
5890
5924
|
}
|
|
5891
5925
|
}
|
|
5892
5926
|
/** What the class is known by. A declaration is known by its name, the way
|
|
@@ -6004,7 +6038,8 @@ var TypeAnalyzer = class {
|
|
|
6004
6038
|
return {
|
|
6005
6039
|
kind: "genericRef",
|
|
6006
6040
|
name: stmt.name.name,
|
|
6007
|
-
typeArguments: params.map((p) => typeParam(p.name, p.constraint ? this.resolveType(p.constraint) : void 0))
|
|
6041
|
+
typeArguments: params.map((p) => typeParam(p.name, p.constraint ? this.resolveType(p.constraint) : void 0)),
|
|
6042
|
+
origin: this.origin
|
|
6008
6043
|
};
|
|
6009
6044
|
}
|
|
6010
6045
|
/** The class table: the statics, what it inherits from the class it
|
|
@@ -6103,8 +6138,11 @@ var TypeAnalyzer = class {
|
|
|
6103
6138
|
return shape;
|
|
6104
6139
|
}
|
|
6105
6140
|
fillShape(stmt, shape) {
|
|
6141
|
+
const className = this.className(stmt);
|
|
6106
6142
|
const put = (isStatic, name, property) => {
|
|
6107
|
-
(
|
|
6143
|
+
const member = stmt.members.find((m) => m.type !== "ClassConstructor" && m.isStatic === isStatic && m.name.name === name && m.accessibility === "private");
|
|
6144
|
+
const marked = member ? { ...property, private: { owner: stmt, className } } : property;
|
|
6145
|
+
(isStatic ? shape.statics : shape.instance).set(name, marked);
|
|
6108
6146
|
};
|
|
6109
6147
|
for (const member of stmt.members) {
|
|
6110
6148
|
if (member.type !== "ClassField") continue;
|
|
@@ -6569,7 +6607,8 @@ var TypeAnalyzer = class {
|
|
|
6569
6607
|
return this.expand({
|
|
6570
6608
|
kind: "genericRef",
|
|
6571
6609
|
name: node.base,
|
|
6572
|
-
typeArguments: node.typeArguments.map((a) => this.resolveType(a))
|
|
6610
|
+
typeArguments: node.typeArguments.map((a) => this.resolveType(a)),
|
|
6611
|
+
origin: this.origin
|
|
6573
6612
|
});
|
|
6574
6613
|
}
|
|
6575
6614
|
const imported = this.importedTypes.get(node.base);
|
|
@@ -6582,7 +6621,8 @@ var TypeAnalyzer = class {
|
|
|
6582
6621
|
return this.expand({
|
|
6583
6622
|
kind: "genericRef",
|
|
6584
6623
|
name,
|
|
6585
|
-
typeArguments: node.typeArguments.map((a) => this.resolveType(a))
|
|
6624
|
+
typeArguments: node.typeArguments.map((a) => this.resolveType(a)),
|
|
6625
|
+
origin: this.origin
|
|
6586
6626
|
});
|
|
6587
6627
|
}
|
|
6588
6628
|
return {
|
|
@@ -8408,6 +8448,7 @@ var TypeAnalyzer = class {
|
|
|
8408
8448
|
* resolving, which is what breaks re-entry on a recursive alias. */
|
|
8409
8449
|
expand(t) {
|
|
8410
8450
|
if (t.kind !== "genericRef") return t;
|
|
8451
|
+
if (t.origin && t.origin !== this.origin) return t.origin.expand(t);
|
|
8411
8452
|
const def = this.aliasDefs.get(t.name);
|
|
8412
8453
|
if (!def) {
|
|
8413
8454
|
const imported = this.importedTypes.get(t.name);
|
|
@@ -8558,6 +8599,28 @@ var TypeAnalyzer = class {
|
|
|
8558
8599
|
message: names.length === 1 ? `'${names[0]}' does not exist on a string` : `'${briefType(key)}' does not name a member of a string`
|
|
8559
8600
|
});
|
|
8560
8601
|
}
|
|
8602
|
+
/** A `private` member read from outside the class that declared it —
|
|
8603
|
+
* a subclass counts as outside, as in TypeScript. */
|
|
8604
|
+
checkPrivateMember(node, object, name) {
|
|
8605
|
+
if (!this.emitDiagnostics) return;
|
|
8606
|
+
const raw = this.expand(object);
|
|
8607
|
+
for (const part of raw.kind === "union" ? raw.types : [raw]) {
|
|
8608
|
+
const t = this.deferredAccess(this.expand(part));
|
|
8609
|
+
if (t.kind !== "object") continue;
|
|
8610
|
+
const access = t.properties.get(name)?.private;
|
|
8611
|
+
if (!access || this.insideClass(access.owner)) continue;
|
|
8612
|
+
this.diagnostics.push({
|
|
8613
|
+
node,
|
|
8614
|
+
message: `Property '${name}' is private and only accessible within class '${access.className}'`
|
|
8615
|
+
});
|
|
8616
|
+
return;
|
|
8617
|
+
}
|
|
8618
|
+
}
|
|
8619
|
+
/** Is the code being checked written inside `owner`'s body — its own
|
|
8620
|
+
* methods, or a class or function nested in them? */
|
|
8621
|
+
insideClass(owner) {
|
|
8622
|
+
return this.enclosingClasses.includes(owner);
|
|
8623
|
+
}
|
|
8561
8624
|
propertyType(raw, name) {
|
|
8562
8625
|
const t = this.deferredAccess(this.expand(raw));
|
|
8563
8626
|
if (t.kind === "object") {
|
|
@@ -8775,6 +8838,7 @@ var TypeAnalyzer = class {
|
|
|
8775
8838
|
}
|
|
8776
8839
|
case "MemberExpression": {
|
|
8777
8840
|
const { type: obj, shortCircuits } = this.chainObject(expr, expr.object, env);
|
|
8841
|
+
this.checkPrivateMember(expr.property, obj, expr.property.name);
|
|
8778
8842
|
const key = this.refKeyOf(expr);
|
|
8779
8843
|
const narrowed = key === void 0 ? void 0 : env.get(key);
|
|
8780
8844
|
this.checkStringMember(expr, obj, literal(expr.property.name));
|
|
@@ -8910,6 +8974,7 @@ var TypeAnalyzer = class {
|
|
|
8910
8974
|
});
|
|
8911
8975
|
}
|
|
8912
8976
|
inferMethodCall(expr, objType, env) {
|
|
8977
|
+
this.checkPrivateMember(expr.method, objType, expr.method.name);
|
|
8913
8978
|
const method = this.propertyType(objType, expr.method.name);
|
|
8914
8979
|
const united = this.unionSignatures(method);
|
|
8915
8980
|
const fns = united ?? this.overloadsOf(method);
|
package/dist/index.d.cts
CHANGED
|
@@ -377,11 +377,16 @@ type ClassMember = ClassField | ClassMethod | ClassAccessor | ClassConstructor;
|
|
|
377
377
|
/** The two ways a class is written. Everything after parsing treats them
|
|
378
378
|
* alike: only the name and the type parameters differ. */
|
|
379
379
|
type ClassLike = ClassDeclaration | ClassExpression;
|
|
380
|
+
/** `public` / `private` written before a member. Only the type checker reads
|
|
381
|
+
* it: a private member is still an ordinary key at runtime. */
|
|
382
|
+
type ClassAccessibility = "public" | "private";
|
|
380
383
|
/** `x: number` / `x = 1` / `static count = 0`. An instance field is assigned
|
|
381
384
|
* when the instance is built, before the constructor body runs; a `static`
|
|
382
385
|
* one is assigned on the class table, once. */
|
|
383
386
|
interface ClassField extends BaseNode {
|
|
384
387
|
type: "ClassField";
|
|
388
|
+
/** Left out, the member is public. */
|
|
389
|
+
accessibility?: ClassAccessibility;
|
|
385
390
|
name: Identifier;
|
|
386
391
|
isStatic: boolean;
|
|
387
392
|
typeAnnotation?: TypeNode;
|
|
@@ -391,6 +396,8 @@ interface ClassField extends BaseNode {
|
|
|
391
396
|
* A `static` one is a plain function on the class table, with no `this`. */
|
|
392
397
|
interface ClassMethod extends BaseNode {
|
|
393
398
|
type: "ClassMethod";
|
|
399
|
+
/** Left out, the member is public. */
|
|
400
|
+
accessibility?: ClassAccessibility;
|
|
394
401
|
name: Identifier;
|
|
395
402
|
isStatic: boolean;
|
|
396
403
|
func: FunctionBody;
|
|
@@ -401,6 +408,8 @@ interface ClassMethod extends BaseNode {
|
|
|
401
408
|
* property, run as a function. */
|
|
402
409
|
interface ClassAccessor extends BaseNode {
|
|
403
410
|
type: "ClassAccessor";
|
|
411
|
+
/** Left out, the member is public. */
|
|
412
|
+
accessibility?: ClassAccessibility;
|
|
404
413
|
kind: "get" | "set";
|
|
405
414
|
name: Identifier;
|
|
406
415
|
isStatic: boolean;
|
|
@@ -1117,6 +1126,13 @@ interface ObjectProperty {
|
|
|
1117
1126
|
type: Type;
|
|
1118
1127
|
optional: boolean;
|
|
1119
1128
|
readonly?: boolean;
|
|
1129
|
+
/** A class member written `private`: reachable only from inside the class
|
|
1130
|
+
* that declared it. `owner` is that class's node, compared by identity;
|
|
1131
|
+
* `className` is how a diagnostic names it. Checked, never lowered. */
|
|
1132
|
+
private?: {
|
|
1133
|
+
owner: object;
|
|
1134
|
+
className: string;
|
|
1135
|
+
};
|
|
1120
1136
|
}
|
|
1121
1137
|
interface ObjectType {
|
|
1122
1138
|
kind: "object";
|
|
@@ -1223,6 +1239,15 @@ interface GenericRefType {
|
|
|
1223
1239
|
kind: "genericRef";
|
|
1224
1240
|
name: string;
|
|
1225
1241
|
typeArguments: Type[];
|
|
1242
|
+
/** The module whose alias this names. A recursive alias is left as a ref
|
|
1243
|
+
* inside its own structure, and that ref travels with the type into every
|
|
1244
|
+
* module that imports it — where `name` may mean nothing, or a different
|
|
1245
|
+
* type. Expanding through `origin` reads the name where it was written. */
|
|
1246
|
+
origin?: TypeOrigin;
|
|
1247
|
+
}
|
|
1248
|
+
/** A module's own alias resolution, handed out on the refs it creates. */
|
|
1249
|
+
interface TypeOrigin {
|
|
1250
|
+
expand(t: GenericRefType): Type;
|
|
1226
1251
|
}
|
|
1227
1252
|
/** `keyof T`. */
|
|
1228
1253
|
interface KeyofType {
|
|
@@ -1600,9 +1625,20 @@ declare function resolveTypeLibraries(config: TiluaConfig, host?: ProjectHost):
|
|
|
1600
1625
|
|
|
1601
1626
|
interface LoweringPlugin {
|
|
1602
1627
|
/** Luau the plugin needs in the output, by a key it chooses. Each is a
|
|
1603
|
-
* file's worth of source
|
|
1604
|
-
*
|
|
1605
|
-
*
|
|
1628
|
+
* file's worth of source, emitted once, at the top of the output, only if
|
|
1629
|
+
* `use` asked for it. Two names in it are filled in by the compiler:
|
|
1630
|
+
*
|
|
1631
|
+
* - `__NAME__`, the local the compiler gives this runtime;
|
|
1632
|
+
* - `__LINES__`, an expression holding the bundle's line map —
|
|
1633
|
+
* `{ [bundleLine] = { "src/a.tilua", sourceLine } }` — or `nil` when
|
|
1634
|
+
* the output is not a bundle. It is what turns a line Luau reports at
|
|
1635
|
+
* runtime back into a place in the project;
|
|
1636
|
+
* - `__FAIL__`, the bundle's error reporter, or `nil` outside a bundle:
|
|
1637
|
+
* a function that takes an error and returns it with the bundle's
|
|
1638
|
+
* positions replaced by the project's, followed by a traceback of
|
|
1639
|
+
* those. It is an `xpcall` handler — the one the entry runs under —
|
|
1640
|
+
* so a runtime that runs a callback on a thread of its own can report
|
|
1641
|
+
* that callback's errors the same way.
|
|
1606
1642
|
*
|
|
1607
1643
|
* local __NAME__ = {}
|
|
1608
1644
|
* function __NAME__.filter(t, test) ... end
|
|
@@ -1612,24 +1648,84 @@ interface LoweringPlugin {
|
|
|
1612
1648
|
* method call, which is what a value that answers to the method itself
|
|
1613
1649
|
* wants — `text:upper()` reaches Lua's own. */
|
|
1614
1650
|
methodCall?(call: MethodCall): MethodLowering | undefined;
|
|
1651
|
+
/** What a call to a global — `print(...)`, `error(...)` — becomes. Asked
|
|
1652
|
+
* only when the name really is the global: a local the author called
|
|
1653
|
+
* `print` is theirs. `undefined` leaves the call as it was written. */
|
|
1654
|
+
globalCall?(call: GlobalCall): CallLowering | undefined;
|
|
1655
|
+
/** What a global read as a value — `task.spawn(print, x)`, `local p =
|
|
1656
|
+
* print` — becomes: a Luau expression, usually built from `use(...)`.
|
|
1657
|
+
* There is no call site to describe here, so this is where a plugin
|
|
1658
|
+
* that rewrites calls keeps the rest of the program consistent with it. */
|
|
1659
|
+
globalValue?(value: GlobalValue): string | undefined;
|
|
1660
|
+
}
|
|
1661
|
+
/** Where a call was written. */
|
|
1662
|
+
interface CallSite {
|
|
1663
|
+
/** The file, relative to the project root with `/` separators, or
|
|
1664
|
+
* `undefined` when a single source was compiled with no name. */
|
|
1665
|
+
readonly file: string | undefined;
|
|
1666
|
+
/** 1-based. */
|
|
1667
|
+
readonly line: number;
|
|
1668
|
+
/** 1-based. */
|
|
1669
|
+
readonly column: number;
|
|
1670
|
+
}
|
|
1671
|
+
/** What the compiler knows about one argument that the runtime will not. */
|
|
1672
|
+
interface ArgumentInfo {
|
|
1673
|
+
/** Its type, as the analyzer worked it out. */
|
|
1674
|
+
readonly type: Type | undefined;
|
|
1675
|
+
/** That type as the editor would show it — `(x: number) => number` —
|
|
1676
|
+
* so a library can print it without depending on this package. */
|
|
1677
|
+
readonly typeText: string | undefined;
|
|
1678
|
+
/** The code it was written as, at the call. */
|
|
1679
|
+
readonly source: string;
|
|
1680
|
+
/** For a name, the code of what it names — the value of `const f = ...`,
|
|
1681
|
+
* or the whole `function f() { ... }` — when this file declares it. */
|
|
1682
|
+
readonly declaration?: string;
|
|
1683
|
+
/** Written `...xs`. */
|
|
1684
|
+
readonly spread: boolean;
|
|
1685
|
+
}
|
|
1686
|
+
interface CallContext {
|
|
1687
|
+
/** Where the call was written. */
|
|
1688
|
+
readonly at: CallSite;
|
|
1689
|
+
/** Each written argument, in order. */
|
|
1690
|
+
readonly arguments: readonly ArgumentInfo[];
|
|
1691
|
+
/** The local name the output gives one of `runtime`'s entries, emitting
|
|
1692
|
+
* it if this is the first call that needed it. */
|
|
1693
|
+
use(runtime: string): string;
|
|
1615
1694
|
}
|
|
1616
|
-
interface MethodCall {
|
|
1695
|
+
interface MethodCall extends CallContext {
|
|
1617
1696
|
/** The name written after `:`. */
|
|
1618
1697
|
readonly method: string;
|
|
1619
1698
|
/** The receiver's type, as the analyzer worked it out. `undefined` when
|
|
1620
1699
|
* nothing typed it, where a plugin should decline rather than guess. */
|
|
1621
1700
|
readonly receiver: Type | undefined;
|
|
1701
|
+
/** The receiver's name when it is a global — `console` in
|
|
1702
|
+
* `console:log(x)` — and `undefined` for anything else, a local of the
|
|
1703
|
+
* same name included. */
|
|
1704
|
+
readonly receiverGlobal: string | undefined;
|
|
1622
1705
|
/** How many arguments were written. */
|
|
1623
1706
|
readonly argumentCount: number;
|
|
1624
|
-
|
|
1625
|
-
|
|
1707
|
+
}
|
|
1708
|
+
interface GlobalCall extends CallContext {
|
|
1709
|
+
/** The global called. */
|
|
1710
|
+
readonly name: string;
|
|
1711
|
+
}
|
|
1712
|
+
interface GlobalValue {
|
|
1713
|
+
/** The global read. */
|
|
1714
|
+
readonly name: string;
|
|
1715
|
+
readonly at: CallSite;
|
|
1626
1716
|
use(runtime: string): string;
|
|
1627
1717
|
}
|
|
1628
|
-
interface
|
|
1718
|
+
interface CallLowering {
|
|
1629
1719
|
/** What to call instead: a name, or a `table.member` path — usually built
|
|
1630
1720
|
* from `use(...)`. */
|
|
1631
1721
|
readonly callee: string;
|
|
1632
|
-
/**
|
|
1722
|
+
/** Luau expressions passed ahead of the written arguments — the call
|
|
1723
|
+
* site, say, or a table of what the compiler knew about them. */
|
|
1724
|
+
readonly prepend?: readonly string[];
|
|
1725
|
+
}
|
|
1726
|
+
interface MethodLowering extends CallLowering {
|
|
1727
|
+
/** Pass the receiver as the first argument, after `prepend`. Default:
|
|
1728
|
+
* yes. */
|
|
1633
1729
|
readonly passReceiver?: boolean;
|
|
1634
1730
|
}
|
|
1635
1731
|
|
|
@@ -1679,4 +1775,4 @@ declare const tilua: {
|
|
|
1679
1775
|
readonly analyzeTypes: typeof analyzeTypes;
|
|
1680
1776
|
};
|
|
1681
1777
|
|
|
1682
|
-
export { type AnalyzeTypesOptions, type AnyType, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallStatement, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
|
|
1778
|
+
export { type AnalyzeTypesOptions, type AnyType, type ArgumentInfo, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallLowering, type CallSite, type CallStatement, type ClassAccessibility, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type GlobalCall, type GlobalValue, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
|
package/dist/index.d.ts
CHANGED
|
@@ -377,11 +377,16 @@ type ClassMember = ClassField | ClassMethod | ClassAccessor | ClassConstructor;
|
|
|
377
377
|
/** The two ways a class is written. Everything after parsing treats them
|
|
378
378
|
* alike: only the name and the type parameters differ. */
|
|
379
379
|
type ClassLike = ClassDeclaration | ClassExpression;
|
|
380
|
+
/** `public` / `private` written before a member. Only the type checker reads
|
|
381
|
+
* it: a private member is still an ordinary key at runtime. */
|
|
382
|
+
type ClassAccessibility = "public" | "private";
|
|
380
383
|
/** `x: number` / `x = 1` / `static count = 0`. An instance field is assigned
|
|
381
384
|
* when the instance is built, before the constructor body runs; a `static`
|
|
382
385
|
* one is assigned on the class table, once. */
|
|
383
386
|
interface ClassField extends BaseNode {
|
|
384
387
|
type: "ClassField";
|
|
388
|
+
/** Left out, the member is public. */
|
|
389
|
+
accessibility?: ClassAccessibility;
|
|
385
390
|
name: Identifier;
|
|
386
391
|
isStatic: boolean;
|
|
387
392
|
typeAnnotation?: TypeNode;
|
|
@@ -391,6 +396,8 @@ interface ClassField extends BaseNode {
|
|
|
391
396
|
* A `static` one is a plain function on the class table, with no `this`. */
|
|
392
397
|
interface ClassMethod extends BaseNode {
|
|
393
398
|
type: "ClassMethod";
|
|
399
|
+
/** Left out, the member is public. */
|
|
400
|
+
accessibility?: ClassAccessibility;
|
|
394
401
|
name: Identifier;
|
|
395
402
|
isStatic: boolean;
|
|
396
403
|
func: FunctionBody;
|
|
@@ -401,6 +408,8 @@ interface ClassMethod extends BaseNode {
|
|
|
401
408
|
* property, run as a function. */
|
|
402
409
|
interface ClassAccessor extends BaseNode {
|
|
403
410
|
type: "ClassAccessor";
|
|
411
|
+
/** Left out, the member is public. */
|
|
412
|
+
accessibility?: ClassAccessibility;
|
|
404
413
|
kind: "get" | "set";
|
|
405
414
|
name: Identifier;
|
|
406
415
|
isStatic: boolean;
|
|
@@ -1117,6 +1126,13 @@ interface ObjectProperty {
|
|
|
1117
1126
|
type: Type;
|
|
1118
1127
|
optional: boolean;
|
|
1119
1128
|
readonly?: boolean;
|
|
1129
|
+
/** A class member written `private`: reachable only from inside the class
|
|
1130
|
+
* that declared it. `owner` is that class's node, compared by identity;
|
|
1131
|
+
* `className` is how a diagnostic names it. Checked, never lowered. */
|
|
1132
|
+
private?: {
|
|
1133
|
+
owner: object;
|
|
1134
|
+
className: string;
|
|
1135
|
+
};
|
|
1120
1136
|
}
|
|
1121
1137
|
interface ObjectType {
|
|
1122
1138
|
kind: "object";
|
|
@@ -1223,6 +1239,15 @@ interface GenericRefType {
|
|
|
1223
1239
|
kind: "genericRef";
|
|
1224
1240
|
name: string;
|
|
1225
1241
|
typeArguments: Type[];
|
|
1242
|
+
/** The module whose alias this names. A recursive alias is left as a ref
|
|
1243
|
+
* inside its own structure, and that ref travels with the type into every
|
|
1244
|
+
* module that imports it — where `name` may mean nothing, or a different
|
|
1245
|
+
* type. Expanding through `origin` reads the name where it was written. */
|
|
1246
|
+
origin?: TypeOrigin;
|
|
1247
|
+
}
|
|
1248
|
+
/** A module's own alias resolution, handed out on the refs it creates. */
|
|
1249
|
+
interface TypeOrigin {
|
|
1250
|
+
expand(t: GenericRefType): Type;
|
|
1226
1251
|
}
|
|
1227
1252
|
/** `keyof T`. */
|
|
1228
1253
|
interface KeyofType {
|
|
@@ -1600,9 +1625,20 @@ declare function resolveTypeLibraries(config: TiluaConfig, host?: ProjectHost):
|
|
|
1600
1625
|
|
|
1601
1626
|
interface LoweringPlugin {
|
|
1602
1627
|
/** Luau the plugin needs in the output, by a key it chooses. Each is a
|
|
1603
|
-
* file's worth of source
|
|
1604
|
-
*
|
|
1605
|
-
*
|
|
1628
|
+
* file's worth of source, emitted once, at the top of the output, only if
|
|
1629
|
+
* `use` asked for it. Two names in it are filled in by the compiler:
|
|
1630
|
+
*
|
|
1631
|
+
* - `__NAME__`, the local the compiler gives this runtime;
|
|
1632
|
+
* - `__LINES__`, an expression holding the bundle's line map —
|
|
1633
|
+
* `{ [bundleLine] = { "src/a.tilua", sourceLine } }` — or `nil` when
|
|
1634
|
+
* the output is not a bundle. It is what turns a line Luau reports at
|
|
1635
|
+
* runtime back into a place in the project;
|
|
1636
|
+
* - `__FAIL__`, the bundle's error reporter, or `nil` outside a bundle:
|
|
1637
|
+
* a function that takes an error and returns it with the bundle's
|
|
1638
|
+
* positions replaced by the project's, followed by a traceback of
|
|
1639
|
+
* those. It is an `xpcall` handler — the one the entry runs under —
|
|
1640
|
+
* so a runtime that runs a callback on a thread of its own can report
|
|
1641
|
+
* that callback's errors the same way.
|
|
1606
1642
|
*
|
|
1607
1643
|
* local __NAME__ = {}
|
|
1608
1644
|
* function __NAME__.filter(t, test) ... end
|
|
@@ -1612,24 +1648,84 @@ interface LoweringPlugin {
|
|
|
1612
1648
|
* method call, which is what a value that answers to the method itself
|
|
1613
1649
|
* wants — `text:upper()` reaches Lua's own. */
|
|
1614
1650
|
methodCall?(call: MethodCall): MethodLowering | undefined;
|
|
1651
|
+
/** What a call to a global — `print(...)`, `error(...)` — becomes. Asked
|
|
1652
|
+
* only when the name really is the global: a local the author called
|
|
1653
|
+
* `print` is theirs. `undefined` leaves the call as it was written. */
|
|
1654
|
+
globalCall?(call: GlobalCall): CallLowering | undefined;
|
|
1655
|
+
/** What a global read as a value — `task.spawn(print, x)`, `local p =
|
|
1656
|
+
* print` — becomes: a Luau expression, usually built from `use(...)`.
|
|
1657
|
+
* There is no call site to describe here, so this is where a plugin
|
|
1658
|
+
* that rewrites calls keeps the rest of the program consistent with it. */
|
|
1659
|
+
globalValue?(value: GlobalValue): string | undefined;
|
|
1660
|
+
}
|
|
1661
|
+
/** Where a call was written. */
|
|
1662
|
+
interface CallSite {
|
|
1663
|
+
/** The file, relative to the project root with `/` separators, or
|
|
1664
|
+
* `undefined` when a single source was compiled with no name. */
|
|
1665
|
+
readonly file: string | undefined;
|
|
1666
|
+
/** 1-based. */
|
|
1667
|
+
readonly line: number;
|
|
1668
|
+
/** 1-based. */
|
|
1669
|
+
readonly column: number;
|
|
1670
|
+
}
|
|
1671
|
+
/** What the compiler knows about one argument that the runtime will not. */
|
|
1672
|
+
interface ArgumentInfo {
|
|
1673
|
+
/** Its type, as the analyzer worked it out. */
|
|
1674
|
+
readonly type: Type | undefined;
|
|
1675
|
+
/** That type as the editor would show it — `(x: number) => number` —
|
|
1676
|
+
* so a library can print it without depending on this package. */
|
|
1677
|
+
readonly typeText: string | undefined;
|
|
1678
|
+
/** The code it was written as, at the call. */
|
|
1679
|
+
readonly source: string;
|
|
1680
|
+
/** For a name, the code of what it names — the value of `const f = ...`,
|
|
1681
|
+
* or the whole `function f() { ... }` — when this file declares it. */
|
|
1682
|
+
readonly declaration?: string;
|
|
1683
|
+
/** Written `...xs`. */
|
|
1684
|
+
readonly spread: boolean;
|
|
1685
|
+
}
|
|
1686
|
+
interface CallContext {
|
|
1687
|
+
/** Where the call was written. */
|
|
1688
|
+
readonly at: CallSite;
|
|
1689
|
+
/** Each written argument, in order. */
|
|
1690
|
+
readonly arguments: readonly ArgumentInfo[];
|
|
1691
|
+
/** The local name the output gives one of `runtime`'s entries, emitting
|
|
1692
|
+
* it if this is the first call that needed it. */
|
|
1693
|
+
use(runtime: string): string;
|
|
1615
1694
|
}
|
|
1616
|
-
interface MethodCall {
|
|
1695
|
+
interface MethodCall extends CallContext {
|
|
1617
1696
|
/** The name written after `:`. */
|
|
1618
1697
|
readonly method: string;
|
|
1619
1698
|
/** The receiver's type, as the analyzer worked it out. `undefined` when
|
|
1620
1699
|
* nothing typed it, where a plugin should decline rather than guess. */
|
|
1621
1700
|
readonly receiver: Type | undefined;
|
|
1701
|
+
/** The receiver's name when it is a global — `console` in
|
|
1702
|
+
* `console:log(x)` — and `undefined` for anything else, a local of the
|
|
1703
|
+
* same name included. */
|
|
1704
|
+
readonly receiverGlobal: string | undefined;
|
|
1622
1705
|
/** How many arguments were written. */
|
|
1623
1706
|
readonly argumentCount: number;
|
|
1624
|
-
|
|
1625
|
-
|
|
1707
|
+
}
|
|
1708
|
+
interface GlobalCall extends CallContext {
|
|
1709
|
+
/** The global called. */
|
|
1710
|
+
readonly name: string;
|
|
1711
|
+
}
|
|
1712
|
+
interface GlobalValue {
|
|
1713
|
+
/** The global read. */
|
|
1714
|
+
readonly name: string;
|
|
1715
|
+
readonly at: CallSite;
|
|
1626
1716
|
use(runtime: string): string;
|
|
1627
1717
|
}
|
|
1628
|
-
interface
|
|
1718
|
+
interface CallLowering {
|
|
1629
1719
|
/** What to call instead: a name, or a `table.member` path — usually built
|
|
1630
1720
|
* from `use(...)`. */
|
|
1631
1721
|
readonly callee: string;
|
|
1632
|
-
/**
|
|
1722
|
+
/** Luau expressions passed ahead of the written arguments — the call
|
|
1723
|
+
* site, say, or a table of what the compiler knew about them. */
|
|
1724
|
+
readonly prepend?: readonly string[];
|
|
1725
|
+
}
|
|
1726
|
+
interface MethodLowering extends CallLowering {
|
|
1727
|
+
/** Pass the receiver as the first argument, after `prepend`. Default:
|
|
1728
|
+
* yes. */
|
|
1633
1729
|
readonly passReceiver?: boolean;
|
|
1634
1730
|
}
|
|
1635
1731
|
|
|
@@ -1679,4 +1775,4 @@ declare const tilua: {
|
|
|
1679
1775
|
readonly analyzeTypes: typeof analyzeTypes;
|
|
1680
1776
|
};
|
|
1681
1777
|
|
|
1682
|
-
export { type AnalyzeTypesOptions, type AnyType, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallStatement, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
|
|
1778
|
+
export { type AnalyzeTypesOptions, type AnyType, type ArgumentInfo, type ArrayExpression, type ArrayPattern, type ArrayPatternElement, type ArrayType, type ArrayTypeNode, type AsConstExpression, type AssignmentStatement, type BaseNode, type BaseToken, type BinaryExpression, BinaryOperators, type Binding, type BindingId, type BindingKind, type BindingTarget, type Block, type BooleanLiteral, type BreakStatement, type BuildTarget, CONFIG_FILE_NAMES, type CallExpression, type CallLowering, type CallSite, type CallStatement, type ClassAccessibility, type ClassAccessor, type ClassConstructor, type ClassDeclaration, type ClassExpression, type ClassField, type ClassInfo, type ClassLike, type ClassMember, type ClassMethod, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ConfigLookup, type ConfigProblem, type ContinueStatement, type DeclareClassStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type Directive, type DirectiveKind, type DirectiveOutcome, type Directives, type DoStatement, type EOFToken, type ErrorExpression, type ErrorStatement, type ExportAllStatement, type ExportDefaultStatement, type ExportNamedStatement, type ExportSpecifier, type ExportStatement, type ExportTypeAliasStatement, type ExportedType, type Expression, type ExpressionStatement, type FunctionBody, type FunctionDeclaration, type FunctionDeclarationStatement, type FunctionExpression, type FunctionName, type FunctionParam, type FunctionParameter, type FunctionSignature, type FunctionType, type FunctionTypeNode, type FunctionTypeParameter, type GenericForStatement, type GenericRefType, type GenericTypeParameter, type GlobalCall, type GlobalValue, type Identifier, type IdentifierPattern, type IdentifierToken, type IfClause, type IfElseExpression, type IfStatement, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LexError, type LiteralToken, type LiteralType, type LoweringModule, type LoweringPlugin, type MappedType, type MappedTypeNode, type MemberExpression, type MethodCall, type MethodCallExpression, type MethodLowering, type ModuleExports, type NeverType, type NewExpression, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, PRELUDE_SOURCE, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type ProjectHost, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type Statement, type StringLiteral, type SuperExpression, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type TiluaConfig, type Token, type TokenizeOptions, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLibraries, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypeOrigin, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, falsyType, findConfig, fn, formatType, getBinding, intersection, isAssignable, isClassType, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName };
|
package/dist/index.js
CHANGED
|
@@ -1727,6 +1727,19 @@ var Parser = class {
|
|
|
1727
1727
|
}
|
|
1728
1728
|
parseClassMember() {
|
|
1729
1729
|
const start = this.current();
|
|
1730
|
+
let accessibility;
|
|
1731
|
+
if ((this.checkIdentifierValue("public") || this.checkIdentifierValue("private")) && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=") && !this.punctuatorAt(1, "(")) {
|
|
1732
|
+
accessibility = this.advance().value;
|
|
1733
|
+
}
|
|
1734
|
+
const member = this.parseClassMemberAfterAccessibility(start);
|
|
1735
|
+
if (!accessibility || !member) return member;
|
|
1736
|
+
if (member.type === "ClassConstructor") {
|
|
1737
|
+
this.problem(`A constructor cannot be '${accessibility}'`);
|
|
1738
|
+
return member;
|
|
1739
|
+
}
|
|
1740
|
+
return { ...member, accessibility };
|
|
1741
|
+
}
|
|
1742
|
+
parseClassMemberAfterAccessibility(start) {
|
|
1730
1743
|
const isStatic = this.checkIdentifierValue("static") && !this.punctuatorAt(1, ":") && !this.operatorAt(1, "=");
|
|
1731
1744
|
if (isStatic) this.advance();
|
|
1732
1745
|
if (this.checkKeyword("function")) {
|
|
@@ -4395,7 +4408,12 @@ function substitute(t, subst) {
|
|
|
4395
4408
|
return t.name && r.kind === "intersection" && !r.name ? { ...r, name: t.name } : r;
|
|
4396
4409
|
}
|
|
4397
4410
|
case "genericRef":
|
|
4398
|
-
return {
|
|
4411
|
+
return {
|
|
4412
|
+
kind: "genericRef",
|
|
4413
|
+
name: t.name,
|
|
4414
|
+
typeArguments: t.typeArguments.map((a) => substitute(a, subst)),
|
|
4415
|
+
...t.origin ? { origin: t.origin } : {}
|
|
4416
|
+
};
|
|
4399
4417
|
case "keyof":
|
|
4400
4418
|
return { kind: "keyof", target: substitute(t.target, subst) };
|
|
4401
4419
|
case "templateLiteral":
|
|
@@ -4555,6 +4573,7 @@ function optional(t) {
|
|
|
4555
4573
|
return union([t, nilType]);
|
|
4556
4574
|
}
|
|
4557
4575
|
function widen(t) {
|
|
4576
|
+
if (isAliasNamed(t)) return t;
|
|
4558
4577
|
switch (t.kind) {
|
|
4559
4578
|
case "literal":
|
|
4560
4579
|
return primitive(t.base);
|
|
@@ -4594,7 +4613,7 @@ function isAssignable(rawA, rawB) {
|
|
|
4594
4613
|
if (expandAlias) {
|
|
4595
4614
|
if (a.kind === "genericRef" && b.kind !== "genericRef") a = expandAlias(a);
|
|
4596
4615
|
else if (b.kind === "genericRef" && a.kind !== "genericRef") b = expandAlias(b);
|
|
4597
|
-
else if (a.kind === "genericRef" && b.kind === "genericRef" && a
|
|
4616
|
+
else if (a.kind === "genericRef" && b.kind === "genericRef" && !sameRefTarget(a, b)) {
|
|
4598
4617
|
a = expandAlias(a);
|
|
4599
4618
|
b = expandAlias(b);
|
|
4600
4619
|
}
|
|
@@ -4704,10 +4723,17 @@ function isAssignableInner(a, b) {
|
|
|
4704
4723
|
}
|
|
4705
4724
|
if (b.kind === "typeParam") return false;
|
|
4706
4725
|
if (a.kind === "genericRef" || b.kind === "genericRef") {
|
|
4707
|
-
return a.kind === "genericRef" && b.kind === "genericRef" && a
|
|
4726
|
+
return a.kind === "genericRef" && b.kind === "genericRef" && sameRefTarget(a, b) && a.typeArguments.length === b.typeArguments.length && a.typeArguments.every((x, i) => equalTypes(x, b.typeArguments[i]));
|
|
4708
4727
|
}
|
|
4709
4728
|
return false;
|
|
4710
4729
|
}
|
|
4730
|
+
function isAliasNamed(t) {
|
|
4731
|
+
if (t.kind === "object" || t.kind === "intersection") return t.name !== void 0;
|
|
4732
|
+
return t.alias !== void 0;
|
|
4733
|
+
}
|
|
4734
|
+
function sameRefTarget(a, b) {
|
|
4735
|
+
return a.name === b.name && (!a.origin || !b.origin || a.origin === b.origin);
|
|
4736
|
+
}
|
|
4711
4737
|
function isNoValue(t) {
|
|
4712
4738
|
return t.kind === "tuple" && t.elements.length === 0;
|
|
4713
4739
|
}
|
|
@@ -5493,6 +5519,9 @@ var TypeAnalyzer = class {
|
|
|
5493
5519
|
aliases = new AliasMap();
|
|
5494
5520
|
/** Uninstantiated alias definitions, for `Name<Args>` instantiation. */
|
|
5495
5521
|
aliasDefs = /* @__PURE__ */ new Map();
|
|
5522
|
+
/** Put on every ref to one of `aliasDefs`, so a module that imports the
|
|
5523
|
+
* type expands the ref here rather than by its name there. */
|
|
5524
|
+
origin = { expand: (t) => this.expand(t) };
|
|
5496
5525
|
/** See `resolveClass`. */
|
|
5497
5526
|
classTypes = /* @__PURE__ */ new WeakMap();
|
|
5498
5527
|
/** See `instanceType` — one instance type per `class ... end`. */
|
|
@@ -5777,13 +5806,18 @@ var TypeAnalyzer = class {
|
|
|
5777
5806
|
classIdentityCount = 0;
|
|
5778
5807
|
/** The class whose members are being read, so `super` knows its base. */
|
|
5779
5808
|
currentClass;
|
|
5809
|
+
/** Every class whose body the checker is inside, innermost last — what
|
|
5810
|
+
* decides whether a `private` member may be reached. */
|
|
5811
|
+
enclosingClasses = [];
|
|
5780
5812
|
withClass(stmt, fn2) {
|
|
5781
5813
|
const previous = this.currentClass;
|
|
5782
5814
|
this.currentClass = stmt;
|
|
5815
|
+
this.enclosingClasses.push(stmt);
|
|
5783
5816
|
try {
|
|
5784
5817
|
return fn2();
|
|
5785
5818
|
} finally {
|
|
5786
5819
|
this.currentClass = previous;
|
|
5820
|
+
this.enclosingClasses.pop();
|
|
5787
5821
|
}
|
|
5788
5822
|
}
|
|
5789
5823
|
/** What the class is known by. A declaration is known by its name, the way
|
|
@@ -5901,7 +5935,8 @@ var TypeAnalyzer = class {
|
|
|
5901
5935
|
return {
|
|
5902
5936
|
kind: "genericRef",
|
|
5903
5937
|
name: stmt.name.name,
|
|
5904
|
-
typeArguments: params.map((p) => typeParam(p.name, p.constraint ? this.resolveType(p.constraint) : void 0))
|
|
5938
|
+
typeArguments: params.map((p) => typeParam(p.name, p.constraint ? this.resolveType(p.constraint) : void 0)),
|
|
5939
|
+
origin: this.origin
|
|
5905
5940
|
};
|
|
5906
5941
|
}
|
|
5907
5942
|
/** The class table: the statics, what it inherits from the class it
|
|
@@ -6000,8 +6035,11 @@ var TypeAnalyzer = class {
|
|
|
6000
6035
|
return shape;
|
|
6001
6036
|
}
|
|
6002
6037
|
fillShape(stmt, shape) {
|
|
6038
|
+
const className = this.className(stmt);
|
|
6003
6039
|
const put = (isStatic, name, property) => {
|
|
6004
|
-
(
|
|
6040
|
+
const member = stmt.members.find((m) => m.type !== "ClassConstructor" && m.isStatic === isStatic && m.name.name === name && m.accessibility === "private");
|
|
6041
|
+
const marked = member ? { ...property, private: { owner: stmt, className } } : property;
|
|
6042
|
+
(isStatic ? shape.statics : shape.instance).set(name, marked);
|
|
6005
6043
|
};
|
|
6006
6044
|
for (const member of stmt.members) {
|
|
6007
6045
|
if (member.type !== "ClassField") continue;
|
|
@@ -6466,7 +6504,8 @@ var TypeAnalyzer = class {
|
|
|
6466
6504
|
return this.expand({
|
|
6467
6505
|
kind: "genericRef",
|
|
6468
6506
|
name: node.base,
|
|
6469
|
-
typeArguments: node.typeArguments.map((a) => this.resolveType(a))
|
|
6507
|
+
typeArguments: node.typeArguments.map((a) => this.resolveType(a)),
|
|
6508
|
+
origin: this.origin
|
|
6470
6509
|
});
|
|
6471
6510
|
}
|
|
6472
6511
|
const imported = this.importedTypes.get(node.base);
|
|
@@ -6479,7 +6518,8 @@ var TypeAnalyzer = class {
|
|
|
6479
6518
|
return this.expand({
|
|
6480
6519
|
kind: "genericRef",
|
|
6481
6520
|
name,
|
|
6482
|
-
typeArguments: node.typeArguments.map((a) => this.resolveType(a))
|
|
6521
|
+
typeArguments: node.typeArguments.map((a) => this.resolveType(a)),
|
|
6522
|
+
origin: this.origin
|
|
6483
6523
|
});
|
|
6484
6524
|
}
|
|
6485
6525
|
return {
|
|
@@ -8305,6 +8345,7 @@ var TypeAnalyzer = class {
|
|
|
8305
8345
|
* resolving, which is what breaks re-entry on a recursive alias. */
|
|
8306
8346
|
expand(t) {
|
|
8307
8347
|
if (t.kind !== "genericRef") return t;
|
|
8348
|
+
if (t.origin && t.origin !== this.origin) return t.origin.expand(t);
|
|
8308
8349
|
const def = this.aliasDefs.get(t.name);
|
|
8309
8350
|
if (!def) {
|
|
8310
8351
|
const imported = this.importedTypes.get(t.name);
|
|
@@ -8455,6 +8496,28 @@ var TypeAnalyzer = class {
|
|
|
8455
8496
|
message: names.length === 1 ? `'${names[0]}' does not exist on a string` : `'${briefType(key)}' does not name a member of a string`
|
|
8456
8497
|
});
|
|
8457
8498
|
}
|
|
8499
|
+
/** A `private` member read from outside the class that declared it —
|
|
8500
|
+
* a subclass counts as outside, as in TypeScript. */
|
|
8501
|
+
checkPrivateMember(node, object, name) {
|
|
8502
|
+
if (!this.emitDiagnostics) return;
|
|
8503
|
+
const raw = this.expand(object);
|
|
8504
|
+
for (const part of raw.kind === "union" ? raw.types : [raw]) {
|
|
8505
|
+
const t = this.deferredAccess(this.expand(part));
|
|
8506
|
+
if (t.kind !== "object") continue;
|
|
8507
|
+
const access = t.properties.get(name)?.private;
|
|
8508
|
+
if (!access || this.insideClass(access.owner)) continue;
|
|
8509
|
+
this.diagnostics.push({
|
|
8510
|
+
node,
|
|
8511
|
+
message: `Property '${name}' is private and only accessible within class '${access.className}'`
|
|
8512
|
+
});
|
|
8513
|
+
return;
|
|
8514
|
+
}
|
|
8515
|
+
}
|
|
8516
|
+
/** Is the code being checked written inside `owner`'s body — its own
|
|
8517
|
+
* methods, or a class or function nested in them? */
|
|
8518
|
+
insideClass(owner) {
|
|
8519
|
+
return this.enclosingClasses.includes(owner);
|
|
8520
|
+
}
|
|
8458
8521
|
propertyType(raw, name) {
|
|
8459
8522
|
const t = this.deferredAccess(this.expand(raw));
|
|
8460
8523
|
if (t.kind === "object") {
|
|
@@ -8672,6 +8735,7 @@ var TypeAnalyzer = class {
|
|
|
8672
8735
|
}
|
|
8673
8736
|
case "MemberExpression": {
|
|
8674
8737
|
const { type: obj, shortCircuits } = this.chainObject(expr, expr.object, env);
|
|
8738
|
+
this.checkPrivateMember(expr.property, obj, expr.property.name);
|
|
8675
8739
|
const key = this.refKeyOf(expr);
|
|
8676
8740
|
const narrowed = key === void 0 ? void 0 : env.get(key);
|
|
8677
8741
|
this.checkStringMember(expr, obj, literal(expr.property.name));
|
|
@@ -8807,6 +8871,7 @@ var TypeAnalyzer = class {
|
|
|
8807
8871
|
});
|
|
8808
8872
|
}
|
|
8809
8873
|
inferMethodCall(expr, objType, env) {
|
|
8874
|
+
this.checkPrivateMember(expr.method, objType, expr.method.name);
|
|
8810
8875
|
const method = this.propertyType(objType, expr.method.name);
|
|
8811
8876
|
const united = this.unionSignatures(method);
|
|
8812
8877
|
const fns = united ?? this.overloadsOf(method);
|