@tilua/parser 4.0.0 → 5.0.1

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.d.cts CHANGED
@@ -36,7 +36,7 @@ type LiteralToken = (BaseToken & {
36
36
  kind: "boolean";
37
37
  value: boolean;
38
38
  });
39
- declare const Operators: readonly ["+=", "-=", "*=", "/=", "//=", "%=", "^=", "..=", "==", "~=", "<=", ">=", "//", "..", "...", "+", "-", "*", "/", "%", "^", "#", "<", ">", "="];
39
+ declare const Operators: readonly ["+=", "-=", "*=", "/=", "//=", "%=", "^=", "..=", "==", "~=", "<=", ">=", "//", "..", "...", "??", "++", "--", "+", "-", "*", "/", "%", "^", "#", "<", ">", "="];
40
40
  interface OperatorToken extends BaseToken {
41
41
  type: "Operator";
42
42
  value: typeof Operators[number];
@@ -205,6 +205,9 @@ interface ExportNamedStatement extends BaseNode {
205
205
  type: "ExportNamedStatement";
206
206
  specifiers: ExportSpecifier[];
207
207
  source?: StringLiteral;
208
+ /** `export type { A }`: the names are types, and only types are
209
+ * exported — compiled code keeps no trace of it. */
210
+ typeOnly?: boolean;
208
211
  }
209
212
  /** `export * from "./x"` — every named export of another module (not its
210
213
  * default), except names this module exports itself. */
@@ -483,6 +486,9 @@ interface CompoundAssignmentStatement extends BaseNode {
483
486
  operator: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "^=" | "..=";
484
487
  target: Expression;
485
488
  value: Expression;
489
+ /** Written `n++` / `n--`: the same statement as `n += 1` / `n -= 1`,
490
+ * whose `value` is then a `1` spanning the operator. */
491
+ postfix?: "++" | "--";
486
492
  }
487
493
  interface CallStatement extends BaseNode {
488
494
  type: "CallStatement";
@@ -559,6 +565,16 @@ interface TypeAliasStatement extends BaseNode {
559
565
  name: Identifier;
560
566
  generics: GenericTypeParameter[];
561
567
  definition: TypeNode;
568
+ /** Written `interface Name extends A, B { ... }`. The alias is then the
569
+ * bases and the body together — `definition` is `A & B & { ... }` — and
570
+ * two interfaces of one name are one, their members merged. */
571
+ interface?: InterfaceParts;
572
+ }
573
+ /** What an `interface` was written as: the shapes it extends, and its own
574
+ * members. */
575
+ interface InterfaceParts {
576
+ extends: TypeReference[];
577
+ body: TableTypeNode;
562
578
  }
563
579
  interface ExportTypeAliasStatement extends BaseNode {
564
580
  type: "ExportTypeAliasStatement";
@@ -575,8 +591,12 @@ interface GenericTypeParameter extends BaseNode {
575
591
  /** `<T extends C>` upper bound (TS style). */
576
592
  constraint?: TypeNode;
577
593
  default?: TypeNode;
594
+ /** `<out T>`, `<in T>`, `<in out T>`: how the type compares by `T` —
595
+ * `out` as `T` does, `in` the other way round, both only when equal.
596
+ * Checked against how the body uses `T`. */
597
+ variance?: "in" | "out" | "in out";
578
598
  }
579
- type Expression = Identifier | NilLiteral | BooleanLiteral | NumberLiteral | StringLiteral | InterpolatedStringExpression | FunctionExpression | TableExpression | ArrayExpression | BinaryExpression | UnaryExpression | MemberExpression | IndexExpression | CallExpression | MethodCallExpression | SuperExpression | ClassExpression | SpreadElement | ParenthesizedExpression | TypeAssertionExpression | SatisfiesExpression | AsConstExpression | IfElseExpression | ErrorExpression;
599
+ type Expression = Identifier | NilLiteral | BooleanLiteral | NumberLiteral | StringLiteral | InterpolatedStringExpression | FunctionExpression | TableExpression | ArrayExpression | BinaryExpression | UnaryExpression | MemberExpression | IndexExpression | CallExpression | MethodCallExpression | SuperExpression | ClassExpression | SpreadElement | ParenthesizedExpression | ImportExpression | TypeAssertionExpression | SatisfiesExpression | AsConstExpression | IfElseExpression | ErrorExpression;
580
600
  /** An expression that could not be parsed. Only produced in recovery mode
581
601
  * (`parseWithRecovery`), where a broken initializer, condition, field value or
582
602
  * argument keeps its place in the tree; its span covers the skipped tokens
@@ -690,7 +710,16 @@ type TableField =
690
710
  | {
691
711
  type: "TableFieldSpread";
692
712
  argument: Expression;
693
- };
713
+ }
714
+ /** `{ get name() { ... } }` / `{ set name(v) { ... } }` — read as a
715
+ * property, run as a function. `func` takes the object as `this`, an
716
+ * implicit first parameter, as a class method does. */
717
+ | {
718
+ type: "TableFieldAccessor";
719
+ kind: "get" | "set";
720
+ key: Identifier | StringLiteral;
721
+ func: FunctionBody;
722
+ } & BaseNode;
694
723
  /** `{ a: 1, [k]: v }` — object literal (Luau `{}` narrowed to objects only). */
695
724
  interface TableExpression extends BaseNode {
696
725
  type: "TableExpression";
@@ -712,7 +741,7 @@ interface SpreadElement extends BaseNode {
712
741
  type: "SpreadElement";
713
742
  argument: Expression;
714
743
  }
715
- declare const BinaryOperators: readonly ["+", "-", "*", "/", "//", "%", "^", "..", "==", "~=", "<", ">", "<=", ">=", "and", "or"];
744
+ declare const BinaryOperators: readonly ["+", "-", "*", "/", "//", "%", "^", "..", "==", "~=", "<", ">", "<=", ">=", "and", "or", "??", "in", "instanceof"];
716
745
  interface BinaryExpression extends BaseNode {
717
746
  type: "BinaryExpression";
718
747
  operator: typeof BinaryOperators[number];
@@ -773,6 +802,15 @@ interface MethodCallExpression extends BaseNode {
773
802
  * arguments are not evaluated when `object` is nil. */
774
803
  optional?: boolean;
775
804
  }
805
+ /** `import("./module")` — the module's exports as one value, the one
806
+ * `import * as M from "./module"` would name `M`, read where the expression
807
+ * runs instead of before the file does. The module is loaded the first time
808
+ * anything asks for it. `source` has to be a string literal: which module it
809
+ * is must be known when the project is built. */
810
+ interface ImportExpression extends BaseNode {
811
+ type: "ImportExpression";
812
+ source: Expression;
813
+ }
776
814
  interface ParenthesizedExpression extends BaseNode {
777
815
  type: "ParenthesizedExpression";
778
816
  expression: Expression;
@@ -807,19 +845,7 @@ interface IfElseExpression extends BaseNode {
807
845
  }[];
808
846
  alternate: Expression;
809
847
  }
810
- type TypeNode = TypeReference | TypeLiteralString | TypeLiteralBoolean | TypeLiteralNumber | TableTypeNode | ArrayTypeNode | TupleTypeNode | FunctionTypeNode | UnionTypeNode | IntersectionTypeNode | ParenthesizedTypeNode | TypeofTypeNode | KeyofTypeNode | IndexedAccessTypeNode | ConditionalTypeNode | InferTypeNode | MappedTypeNode | TemplateLiteralTypeNode | DifferenceTypeNode;
811
- /** `A - B` — every value of `A` that is not a `B`. Binds tighter than `|`
812
- * and looser than `&`, so `A | B - C` is `A | (B - C)`.
813
- *
814
- * Mostly it simplifies away (a union drops members; `string - "a"` is just
815
- * `string`), but over an opaque type it is retained — which is what lets the
816
- * `else` of `if a == 1` on an `unknown` say `unknown - 1` instead of
817
- * forgetting the test. `Exclude<T, U>` is defined as `T - U`. */
818
- interface DifferenceTypeNode extends BaseNode {
819
- type: "DifferenceTypeNode";
820
- base: TypeNode;
821
- excluded: TypeNode;
822
- }
848
+ type TypeNode = TypeReference | TypeLiteralString | TypeLiteralBoolean | TypeLiteralNumber | TableTypeNode | ArrayTypeNode | TupleTypeNode | FunctionTypeNode | UnionTypeNode | IntersectionTypeNode | ParenthesizedTypeNode | TypeofTypeNode | KeyofTypeNode | IndexedAccessTypeNode | ConditionalTypeNode | InferTypeNode | MappedTypeNode | TemplateLiteralTypeNode | RestTypeNode;
823
849
  /** A template literal type: `` `on${string}` ``, `` `get${K}` ``.
824
850
  * `quasis` are the literal chunks and `types` the interpolated types;
825
851
  * `quasis.length === types.length + 1`, exactly as in an ECMAScript template.
@@ -860,6 +886,14 @@ interface InferTypeNode extends BaseNode {
860
886
  name: string;
861
887
  /** The bound name as a node. */
862
888
  id?: Identifier;
889
+ /** `infer N extends number`: what matched only counts if it is one — and
890
+ * out of a template literal, `"42"` read as a `number` is `42`. */
891
+ constraint?: TypeNode;
892
+ }
893
+ /** `...T` inside a tuple type: the elements of `T`, in its place. */
894
+ interface RestTypeNode extends BaseNode {
895
+ type: "RestTypeNode";
896
+ typeAnnotation: TypeNode;
863
897
  }
864
898
  /** `{ [K in C]: V }` — a mapped type. `optional` / `readonly` carry the
865
899
  * modifier as written: `true` adds it (`?`), `false` removes it (`-?`),
@@ -931,10 +965,20 @@ type TableTypeProperty = ({
931
965
  valueType: TypeNode;
932
966
  optional: boolean;
933
967
  readonly?: boolean;
968
+ /** Written as a method, `name(x: T): R`: `valueType` is the function,
969
+ * its receiver first — `(self: this, x: T) => R`. */
970
+ method?: boolean;
971
+ /** Written as `get name(): T` / `set name(v: T)`: what the property
972
+ * holds. A getter without a setter is read-only. */
973
+ accessor?: "get" | "set" | "both";
934
974
  } & BaseNode);
935
975
  interface TableTypeNode extends BaseNode {
936
976
  type: "TableTypeNode";
937
977
  properties: TableTypeProperty[];
978
+ /** `{ (x: number): string }` — what calling a value of this type does.
979
+ * Several are overloads. The type is then these functions together
980
+ * with the properties. */
981
+ callSignatures?: FunctionTypeNode[];
938
982
  }
939
983
  /** `T[]` — array type. Replaces Luau's `{T}` array-table notation. */
940
984
  interface ArrayTypeNode extends BaseNode {
@@ -944,14 +988,22 @@ interface ArrayTypeNode extends BaseNode {
944
988
  isReadonly?: boolean;
945
989
  }
946
990
  /** `[number, string]` — a tuple type; `[string, ...number[]]` ends in a rest
947
- * of as many more as there are. */
991
+ * of as many more as there are. A spread of anything else — `[...T, U]`, a
992
+ * type parameter or another tuple — stays among `elements` as a
993
+ * `RestTypeNode`, and is laid out once what it spreads is known. */
948
994
  interface TupleTypeNode extends BaseNode {
949
995
  type: "TupleTypeNode";
950
996
  elements: TypeNode[];
997
+ /** `[x: number, y: number]` — the name each element was written with,
998
+ * where it was. Display only. */
999
+ labels?: (string | undefined)[];
951
1000
  /** `...number[]` at the end: the array type the rest of it is. */
952
1001
  rest?: TypeNode;
953
1002
  /** `readonly [A, B]` — see `ArrayTypeNode.isReadonly`. */
954
1003
  isReadonly?: boolean;
1004
+ /** `[A, B?]`, `[a: A, b?: B]`: which elements may be left out — each
1005
+ * then read as `T | nil`, which in Lua is the same thing. */
1006
+ optional?: boolean[];
955
1007
  }
956
1008
  interface FunctionTypeParameter extends BaseNode {
957
1009
  type: "FunctionTypeParameter";
@@ -1101,11 +1153,14 @@ interface AnalyzeScopesOptions {
1101
1153
  * one of these does not count as "defining" it, so `declarationNode`
1102
1154
  * is left unset even though the binding exists up front. */
1103
1155
  builtinGlobals?: readonly string[];
1156
+ /** Leave out the standard library's globals (`print`, `pairs`, ...),
1157
+ * which are otherwise there for every file. The config's `"noLib"`. */
1158
+ noLib?: boolean;
1104
1159
  /** Report each read of a name nothing declares — not a local, not one of
1105
1160
  * `builtinGlobals`, not `declare`d in the file, never assigned as a
1106
1161
  * global: "Cannot find name 'x'", as TypeScript says. Only meaningful
1107
1162
  * when `builtinGlobals` lists everything the file's type libraries
1108
- * declare, so it is off unless asked for. */
1163
+ * declare beyond the standard library, so it is off unless asked for. */
1109
1164
  reportUndeclared?: boolean;
1110
1165
  }
1111
1166
  declare function getBinding(analysis: ScopeAnalysis, id: Identifier | IdentifierPattern): Binding | undefined;
@@ -1121,7 +1176,7 @@ declare function isUnassignedGlobal(binding: Binding): boolean;
1121
1176
  declare const LANGUAGE_GLOBALS: readonly string[];
1122
1177
  declare function analyzeScopes(program: Program, options?: AnalyzeScopesOptions): ScopeAnalysis;
1123
1178
 
1124
- type Type = AnyType | UnknownType | NeverType | PrimitiveType | LiteralType | ArrayType | TupleType | ObjectType | FunctionType | UnionType | IntersectionType | TypeParamType | GenericRefType | KeyofType | IndexedAccessType | ConditionalType | InferType | MappedType | TemplateLiteralType | DifferenceType;
1179
+ type Type = AnyType | UnknownType | NeverType | PrimitiveType | LiteralType | ArrayType | TupleType | ObjectType | FunctionType | UnionType | IntersectionType | TypeParamType | GenericRefType | KeyofType | IndexedAccessType | ConditionalType | InferType | MappedType | TemplateLiteralType | DifferenceType | SpreadType;
1125
1180
  /** `any` — opts out of checking. Assignable to and from everything. */
1126
1181
  interface AnyType {
1127
1182
  kind: "any";
@@ -1142,7 +1197,9 @@ interface NeverType {
1142
1197
  kind: "never";
1143
1198
  alias?: string;
1144
1199
  }
1145
- type PrimitiveName = "nil" | "boolean" | "number" | "string" | "thread" | "buffer";
1200
+ /** `object` is TypeScript's: any value that is not one of the others — a
1201
+ * table, a list, a function, a class instance. */
1202
+ type PrimitiveName = "nil" | "boolean" | "number" | "string" | "thread" | "buffer" | "object";
1146
1203
  interface PrimitiveType {
1147
1204
  kind: "primitive";
1148
1205
  name: PrimitiveName;
@@ -1171,7 +1228,32 @@ interface TupleType {
1171
1228
  rest?: Type;
1172
1229
  alias?: string;
1173
1230
  readonly?: boolean;
1231
+ /** `[number, string?]`: how many of the elements have to be there — the
1232
+ * ones from here on may be left out, and hold `nil` when they are. All
1233
+ * of them when absent. */
1234
+ minLength?: number;
1235
+ /** `[x: number, y?: number]`: the name each element was written with,
1236
+ * where it was. Display only. */
1237
+ names?: readonly (string | undefined)[];
1238
+ }
1239
+ /** `made`, rebuilt from `from`, keeping what `tuple` does not carry: that
1240
+ * it is read-only, which of its places may be left out, and their names —
1241
+ * so long as it has as many places as `from` had. */
1242
+ declare function tupleMeta(made: TupleType, from: TupleType): TupleType;
1243
+ /** How many places a tuple has to have. */
1244
+ declare function minLengthOf(t: TupleType): number;
1245
+ /** What a tuple's `length` is: one number, or each it may be. */
1246
+ declare function tupleLength(t: TupleType): Type;
1247
+ /** `...T` among a tuple's elements, where `T` is not known yet — a type
1248
+ * parameter, an `infer`, a type-level operator still waiting on one. It only
1249
+ * ever stands inside a `TupleType`'s `elements`: `tuple` lays out a spread of
1250
+ * anything known (a tuple's elements in its place, an array's as the rest),
1251
+ * so once its type parameters are filled in none is left. */
1252
+ interface SpreadType {
1253
+ kind: "spread";
1254
+ type: Type;
1174
1255
  }
1256
+ declare function spread(type: Type): SpreadType;
1175
1257
  interface ObjectProperty {
1176
1258
  type: Type;
1177
1259
  optional: boolean;
@@ -1226,6 +1308,10 @@ interface ClassInfo {
1226
1308
  * `Box<string>`. A class with no type parameters anywhere carries
1227
1309
  * nothing, and costs nothing. */
1228
1310
  typeArguments?: ReadonlyMap<string, readonly Type[]>;
1311
+ /** A `class` the program writes, whose instances are Lua tables — as
1312
+ * opposed to a `declare class`, a value the host made (a Roblox
1313
+ * `Instance`, a `Vector3`), which knows how to print itself. */
1314
+ runtime?: boolean;
1229
1315
  }
1230
1316
  declare function isClassType(t: Type): t is ObjectType & {
1231
1317
  class: ClassInfo;
@@ -1279,6 +1365,9 @@ interface TypeParamType {
1279
1365
  /** Declared `<const T>`: the call site infers the argument at its
1280
1366
  * narrowest rather than widening it. */
1281
1367
  isConst?: boolean;
1368
+ /** Written inside `NoInfer<...>`: an argument there is checked against
1369
+ * the parameter, never read to work out what it is. */
1370
+ noInfer?: boolean;
1282
1371
  }
1283
1372
  declare function typeParam(name: string, constraint?: Type, isConst?: boolean): TypeParamType;
1284
1373
  interface UnionType {
@@ -1309,6 +1398,9 @@ interface GenericRefType {
1309
1398
  /** A module's own alias resolution, handed out on the refs it creates. */
1310
1399
  interface TypeOrigin {
1311
1400
  expand(t: GenericRefType): Type;
1401
+ /** How the alias `name` compares by each of its parameters, where it
1402
+ * says (`<out T>`, `<in T>`, `<in out T>`). */
1403
+ variances?(name: string): readonly (string | undefined)[] | undefined;
1312
1404
  }
1313
1405
  /** `keyof T`. */
1314
1406
  interface KeyofType {
@@ -1320,6 +1412,7 @@ interface IndexedAccessType {
1320
1412
  kind: "indexedAccess";
1321
1413
  objectType: Type;
1322
1414
  indexType: Type;
1415
+ alias?: string;
1323
1416
  }
1324
1417
  /** `C extends E ? A : B`. */
1325
1418
  interface ConditionalType {
@@ -1335,26 +1428,29 @@ interface ConditionalType {
1335
1428
  * branch the parameter denotes the single member being tested — the
1336
1429
  * property `Exclude<T, U>` relies on. */
1337
1430
  distributeParam?: string;
1431
+ alias?: string;
1338
1432
  }
1339
1433
  /** `infer U`, valid only inside a conditional's `extends` clause. */
1340
1434
  interface InferType {
1341
1435
  kind: "infer";
1342
1436
  name: string;
1437
+ /** `infer N extends number` — see `InferTypeNode.constraint`. */
1438
+ constraint?: Type;
1343
1439
  }
1344
- /** `A - B` — every value of `A` that is not a `B`.
1440
+ /** `Exclude<A, B>` — every value of `A` that is not a `B`.
1345
1441
  *
1346
- * Only kept when `A` is *opaque*: `unknown`, or a type parameter or nominal
1347
- * reference not yet resolved. For a union the subtraction is performed by
1348
- * dropping members, and for a concrete type such as `string` it is discarded
1349
- * (`string - "a"` supports exactly the same operations as `string`, and
1350
- * TypeScript likewise does not track it). For `unknown`, though, the
1351
- * subtraction is the *only* thing known about the value, so throwing it away
1352
- * loses the whole result of the test:
1442
+ * Only kept when `A` is *opaque*: `unknown`, `any`, or a type parameter or
1443
+ * nominal reference not yet resolved. For a union the subtraction is
1444
+ * performed by dropping members, and for a concrete type such as `string` it
1445
+ * is discarded (`Exclude<string, "a">` supports exactly the same operations
1446
+ * as `string`). For `unknown`, though, the subtraction is the *only* thing
1447
+ * known about the value, so throwing it away — as TypeScript's `Exclude`
1448
+ * does — loses the whole result of the test:
1353
1449
  *
1354
1450
  * let a: unknown
1355
- * if a == 1 then -- a: 1
1356
- * else -- a: unknown - 1
1357
- * end
1451
+ * if (a == 1) { -- a: 1
1452
+ * } else { -- a: Exclude<unknown, 1>
1453
+ * }
1358
1454
  */
1359
1455
  interface DifferenceType {
1360
1456
  kind: "difference";
@@ -1391,6 +1487,7 @@ interface MappedType {
1391
1487
  /** The `T` of `[K in keyof T]`, kept so a homomorphic mapped type can carry
1392
1488
  * each source property's own `?` / `readonly` across. */
1393
1489
  source?: Type;
1490
+ alias?: string;
1394
1491
  }
1395
1492
  declare const anyType: AnyType;
1396
1493
  declare const unknownType: UnknownType;
@@ -1402,10 +1499,13 @@ declare const numberType: PrimitiveType;
1402
1499
  declare const stringType: PrimitiveType;
1403
1500
  declare const threadType: PrimitiveType;
1404
1501
  declare const bufferType: PrimitiveType;
1502
+ declare const objectKeywordType: PrimitiveType;
1405
1503
  declare function primitive(name: PrimitiveName): PrimitiveType;
1406
1504
  declare function literal(value: string | number | boolean): LiteralType;
1407
1505
  declare function arrayOf(element: Type): ArrayType;
1408
1506
  declare function tuple(elements: Type[], rest?: Type): TupleType;
1507
+ /** Does this tuple still have a spread to lay out? */
1508
+ declare function hasSpread(t: TupleType): boolean;
1409
1509
  /** Every element type a tuple can hold, the rest's included. */
1410
1510
  declare function tupleMembers(t: TupleType): Type[];
1411
1511
  declare function objectType(entries: Iterable<[string, ObjectProperty]>, indexer?: ObjectType["indexer"], frozen?: boolean): ObjectType;
@@ -1422,8 +1522,13 @@ type Unification = "union" | "first";
1422
1522
  declare function unify(param: Type, arg: Type, vars: Set<string>, out: Map<string, Type>, how?: Unification): void;
1423
1523
  declare function union(types: Type[]): Type;
1424
1524
  declare function intersection(types: Type[]): Type;
1425
- /** `base - excluded`, simplified as far as the base allows. */
1525
+ /** `Exclude<base, excluded>`, simplified as far as the base allows. */
1426
1526
  declare function difference(base: Type, excluded: Type): Type;
1527
+ /** A method's type with its receiver left out: what it takes after `this`
1528
+ * (or a definitions file's `self`) — what `text.upper` is, the receiver
1529
+ * being `text`. A guard on a later parameter moves with it. Anything else is
1530
+ * returned as it is. */
1531
+ declare function withoutReceiver(t: Type): Type;
1427
1532
  /** `T | nil` — the type of an optional property or parameter. */
1428
1533
  declare function optional(t: Type): Type;
1429
1534
  /** Widens literal types to their primitive base (the default for a plain
@@ -1432,7 +1537,15 @@ declare function optional(t: Type): Type;
1432
1537
  declare function widen(t: Type): Type;
1433
1538
  declare function setAliasExpander(fn: ((t: GenericRefType) => Type) | undefined): void;
1434
1539
  declare function setDeferredBound(fn: ((t: Type) => Type | undefined) | undefined): void;
1540
+ declare function setBuiltinMember(fn: ((t: Type, name: string) => Type | undefined) | undefined): void;
1435
1541
  declare function isAssignable(rawA: Type, rawB: Type): boolean;
1542
+ /** A tuple's places as the parameters they are, with their names, and the
1543
+ * ones that may be left out optional: `[a: number, b?: string]` is
1544
+ * `(a: number, b?: string)`. */
1545
+ declare function tupleParams(t: TupleType): FunctionParam[];
1546
+ /** Parameters as the tuple they are: `(a: number, b?: string)` is
1547
+ * `[a: number, b?: string]`. */
1548
+ declare function paramsAsTuple(params: readonly FunctionParam[], rest?: Type): TupleType;
1436
1549
  declare function equalTypes(a: Type, b: Type): boolean;
1437
1550
  /** Keep the parts of `t` compatible with `filter` — TypeScript's
1438
1551
  * `getNarrowedType`. Per union member: a member already assignable to the
@@ -1458,11 +1571,26 @@ declare function narrowTruthy(t: Type): Type;
1458
1571
  /** Keep only what can be falsy — `nil` and `false`. */
1459
1572
  declare function narrowFalsy(t: Type): Type;
1460
1573
  declare function containsTypeParam(t: Type, seen?: Set<Type>, bound?: Set<string>): boolean;
1574
+ /** The name of TypeScript's polymorphic `this` type: the value a member is
1575
+ * read from. It is a type parameter filled in where a member is read (see
1576
+ * `withThis`), so it never keeps a type waiting the way a generic's own
1577
+ * parameters do — `keyof` an interface whose methods take `self: this` is
1578
+ * as known as any other. */
1579
+ declare const THIS_TYPE = "this";
1580
+ /** Does `t` mention the polymorphic `this` — outside a class, whose members
1581
+ * are read one at a time? */
1582
+ declare function mentionsThis(t: Type): boolean;
1583
+ /** `t` with `this` standing for `receiver`. */
1584
+ declare function withThis(t: Type, receiver: Type): Type;
1461
1585
  /** Structurally match `arg` against `pattern`, binding every `infer` name it
1462
1586
  * contains into `out`. This is what turns `T extends (...unknown) -> infer R`
1463
1587
  * into `R = <the return type>`. Returns false when the shapes cannot match at
1464
- * all; a `true` result still needs the usual assignability check. */
1465
- declare function matchInfer(arg: Type, pattern: Type, out: Map<string, Type>): boolean;
1588
+ * all; a `true` result still needs the usual assignability check.
1589
+ *
1590
+ * `contra` is set below a function's parameter: a name inferred from several
1591
+ * places there is what all of them take — their intersection, which is how
1592
+ * `UnionToIntersection` works — where anywhere else it is their union. */
1593
+ declare function matchInfer(arg: Type, pattern: Type, out: Map<string, Type>, contra?: boolean): boolean;
1466
1594
  /** Does a concrete string match a template literal *pattern*? Each
1467
1595
  * interpolation is matched against the widest thing it could stand for:
1468
1596
  * `string` swallows any run, `number` a numeric run, and a literal union only
@@ -1522,6 +1650,15 @@ interface TypeAnalysis {
1522
1650
  * gave it (`declare metatable`), and which library declared that. A call
1523
1651
  * missing here reached a member of the receiver's own. */
1524
1652
  readonly methodSources: ReadonlyMap<MethodCallExpression, MethodSource>;
1653
+ /** Each `value.method` read with `.` that reaches a method the value's
1654
+ * metatable gives it — `names.filter`, `text.trim` — and which library
1655
+ * declared that. The method is a function like any other: called with
1656
+ * `.` it is handed its `self` the way any function is handed its first
1657
+ * argument, `names.filter(names, f)`. No Lua array has a `filter` to
1658
+ * read, so the compiler writes the read as what the method really is. */
1659
+ readonly methodReads: ReadonlyMap<MemberExpression, MethodSource>;
1660
+ /** Each `.length` read of a string or a list: Luau's `#`. */
1661
+ readonly lengths: ReadonlySet<MemberExpression>;
1525
1662
  /** Each `typeof v` whose `v`, where it is a table at all, is known by its
1526
1663
  * type to be an array or to be an object. One missing here has to be
1527
1664
  * told apart as the program runs. */
@@ -1572,6 +1709,9 @@ interface AnalyzeTypesOptions {
1572
1709
  * types. A project lists them under `types` in `tilua.config.json`; see
1573
1710
  * `resolveTypeLibraries`. */
1574
1711
  libs?: readonly Program[];
1712
+ /** Leave the standard library out: no `print`, no `string`, nothing but
1713
+ * what `libs` declare. The config's `"noLib": true`. */
1714
+ noLib?: boolean;
1575
1715
  /** Resolve an `import`'s module path to what that module exports. Called
1576
1716
  * once per distinct path. Return `undefined` when there is no such module:
1577
1717
  * the import is reported and its names are `any`. Without this option
@@ -1597,8 +1737,8 @@ resolveModule?: (specifier: string) => ModuleExports | undefined): ModuleExports
1597
1737
  * or without a type library — as TypeScript's `Partial` and `ReturnType` are.
1598
1738
  *
1599
1739
  * They are written in tilua on top of `keyof`, `T[K]`, conditional types with
1600
- * `infer`, mapped types and set difference; the analyzer knows none of these
1601
- * names. A type library or the file itself may declare one of them again, and
1740
+ * `infer`, mapped types and `Exclude`; the analyzer knows none of these
1741
+ * names but `Exclude`. A type library or the file itself may declare one of them again, and
1602
1742
  * that declaration wins.
1603
1743
  *
1604
1744
  * What a runtime provides — `print`, `string`, `game` — is not here: that is a
@@ -1616,7 +1756,28 @@ resolveModule?: (specifier: string) => ModuleExports | undefined): ModuleExports
1616
1756
  * `ObjectValues<T>` and `ObjectEntries<T>`, an object's members as tuples in
1617
1757
  * the order they were written.
1618
1758
  */
1619
- declare const PRELUDE_SOURCE = "\n-- In Luau only `nil` and `false` are falsy: `0` and `\"\"` are truthy.\n-- These are what truthiness narrowing computes, made available to write down.\ntype Falsy = nil | false\ntype Truthy<T> = T - Falsy\n\n-- `-` is set difference. Over a union it drops members; over a concrete type\n-- it simplifies away; over an opaque type (`unknown`, an unresolved parameter)\n-- it is kept, so `Exclude<unknown, 1>` stays `unknown - 1`.\ntype Exclude<T, U> = T - U\ntype Extract<T, U> = T extends U ? T : never\ntype NonNullable<T> = T - nil\n\ntype ReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never\ntype Parameters<T> = T extends (...args: infer P) => unknown ? P : never\n\ntype Partial<T> = { [K in keyof T]?: T[K] }\ntype Required<T> = { [K in keyof T]-?: T[K] }\ntype Readonly<T> = { readonly [K in keyof T]: T[K] }\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }\n\ntype Pick<T, K> = { [P in K]: T[P] }\ntype Omit<T, K> = Pick<T, Exclude<keyof T, K>>\ntype Record<K, V> = { [P in K]: V }\n\n-- ============================================================\n-- The metatables of the language's own values\n-- ============================================================\n\n-- A string's methods. The first group is Lua's string library, which a\n-- string really answers to; where Lua answers several values, tilua answers\n-- one, as the global functions do (`find` is an array, `gsub` the new\n-- string). The second group is written the way JavaScript writes it.\n--\n-- Positions are Lua's: `sub` and `slice` count from 1, and `indexOf` is\n-- `nil` when the text is not there.\ndeclare metatable string: {\n __index: {\n upper: (self: string) => string,\n lower: (self: string) => string,\n len: (self: string) => number,\n sub: (self: string, i: number, j?: number) => string,\n rep: (self: string, n: number, separator?: string) => string,\n reverse: (self: string) => string,\n format: (self: string, ...args: unknown[]) => string,\n byte: ((self: string, i?: number) => number) & ((self: string, i: number, j: number) => number[]),\n find: (self: string, pattern: string, init?: number, plain?: boolean) => [number, number, ...string[]] | nil,\n match: (self: string, pattern: string, init?: number) => [...string[]] | nil,\n gmatch: (self: string, pattern: string) => () => [string, ...string[]] | nil,\n gsub: (self: string, pattern: string, replacement: unknown, n?: number) => string,\n\n trim: (self: string) => string,\n trimStart: (self: string) => string,\n trimEnd: (self: string) => string,\n startsWith: (self: string, text: string) => boolean,\n endsWith: (self: string, text: string) => boolean,\n includes: (self: string, text: string) => boolean,\n indexOf: (self: string, text: string, start?: number) => number | nil,\n slice: (self: string, start?: number, stop?: number) => string,\n replace: (self: string, text: string, replacement: string) => string,\n replaceAll: (self: string, text: string, replacement: string) => string,\n padStart: (self: string, length: number, padding?: string) => string,\n padEnd: (self: string, length: number, padding?: string) => string,\n },\n}\n\n-- An array's methods. Lua gives an array no metatable: the compiler lowers\n-- each call to a plain function, so they work on any array, one a Lua\n-- library made included.\n--\n-- Indices are Lua's: the first element is 1, and `indexOf` / `findIndex`\n-- answer `nil` rather than JavaScript's -1. `sort` takes Lua's comparator\n-- (true when `a` comes first). `push`, `pop`, `shift`, `unshift`,\n-- `sort` and `reverse` change the array; everything else returns a new one.\n-- A `filter` whose test is a guard \u2014 `v is S`, or `v => v ~= nil` \u2014\n-- answers an array of what it let through.\ndeclare metatable<T> T[]: {\n __index: {\n find: (self: T[], test: (value: T, index: number) => boolean) => T | nil,\n findIndex: (self: T[], test: (value: T, index: number) => boolean) => number | nil,\n filter: (<S extends T>(self: T[], test: (value: T, index: number) => value is S) => S[])\n & ((self: T[], test: (value: T, index: number) => boolean) => T[]),\n map: <U>(self: T[], transform: (value: T, index: number) => U) => U[],\n forEach: (self: T[], visit: (value: T, index: number) => nil) => nil,\n some: (self: T[], test: (value: T, index: number) => boolean) => boolean,\n every: (self: T[], test: (value: T, index: number) => boolean) => boolean,\n reduce: <U>(self: T[], step: (total: U, value: T, index: number) => U, initial: U) => U,\n includes: (self: T[], value: T) => boolean,\n indexOf: (self: T[], value: T, start?: number) => number | nil,\n join: (self: T[], separator?: string) => string,\n concat: (self: T[], ...others: T[][]) => T[],\n slice: (self: T[], start?: number, stop?: number) => T[],\n flat: (self: T[]) => T[],\n reverse: (self: T[]) => T[],\n sort: (self: T[], compare?: (a: T, b: T) => boolean) => T[],\n push: (self: T[], ...args: T[]) => number,\n pop: (self: T[]) => T | nil,\n shift: (self: T[]) => T | nil,\n unshift: (self: T[], ...args: T[]) => number,\n },\n}\n\n-- A table's methods. Unlike JavaScript's `Object.keys`, they answer a\n-- tuple, in the order the table's type wrote its members:\n--\n-- const point = { x: 1, y: \"up\" }\n-- point:keys() -- [\"x\", \"y\"]\n-- point:values() -- [number, string]\n-- point:entries() -- [[\"x\", number], [\"y\", string]]\n--\n-- A Lua table has no order of its own, so the compiler hands its runtime the\n-- keys as the type lists them. An optional member keeps its place, holding\n-- `nil` when it is missing; an indexer's keys follow the named ones. A\n-- member of the table's own with one of these names is what a call reaches,\n-- and a class instance, which has a metatable of its own, has none of them.\n--\n-- The rest are JavaScript's `Object` functions, written as methods of the\n-- table they take first:\n--\n-- point:hasOwn(\"x\") -- Object.hasOwn(point, \"x\")\n-- point:assign({ z: 3 }) -- Object.assign(point, { z: 3 })\n-- point:freeze() -- Object.freeze(point)\n--\n-- `hasOwn` asks the table itself, not what its metatable's `__index`\n-- lends it. `assign` copies each source's members onto the table, later ones\n-- over earlier ones, skipping a `nil` source, and answers the table. `freeze`\n-- is Luau's `table.freeze`; under Lua 5.1, which cannot freeze a table, the\n-- table is answered as it is and `isFrozen` is false.\ndeclare metatable<T extends {}> T: {\n __index: {\n keys: (self: T) => ObjectKeys<T>,\n values: (self: T) => ObjectValues<T>,\n entries: (self: T) => ObjectEntries<T>,\n\n hasOwn: (self: T, key: unknown) => boolean,\n hasOwnProperty: (self: T, key: unknown) => boolean,\n assign: (<U>(self: T, source: U) => T & U)\n & (<U, V>(self: T, a: U, b: V) => T & U & V)\n & (<U, V, W>(self: T, a: U, b: V, c: W) => T & U & V & W)\n -- Generic like the rest: a plain signature would be tried first.\n & (<S extends {}>(self: T, ...sources: S[]) => T),\n freeze: (self: T) => Readonly<T>,\n isFrozen: (self: T) => boolean,\n },\n}\n";
1759
+ declare const PRELUDE_SOURCE = "\n-- In Luau only `nil` and `false` are falsy: `0` and `\"\"` are truthy.\n-- These are what truthiness narrowing computes, made available to write down.\ntype Falsy = nil | false\ntype Truthy<T> = Exclude<T, Falsy>\n\n-- `Exclude<T, U>` is the analyzer's own: what of `T` is not a `U`. Over a\n-- union it drops the members it takes whole; over `unknown`, `any`, a\n-- primitive or an unresolved parameter it is kept \u2014 `Exclude<string, \"a\">` is\n-- a string that is not `\"a\"` \u2014 unlike TypeScript's.\ntype Extract<T, U> = T extends U ? T : never\ntype NonNullable<T> = Exclude<T, nil>\n\ntype ReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never\ntype Parameters<T> = T extends (...args: infer P) => unknown ? P : never\n\ntype Partial<T> = { [K in keyof T]?: T[K] }\ntype Required<T> = { [K in keyof T]-?: T[K] }\ntype Readonly<T> = { readonly [K in keyof T]: T[K] }\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }\n\n-- A class table builds with `new`: `InstanceType<typeof Dog>` is a `Dog`.\ntype InstanceType<T> = T extends { new: (...args: any[]) => infer R } ? R : never\ntype ConstructorParameters<T> = T extends { new: (...args: infer P) => any } ? P : never\n\ntype Pick<T, K> = { [P in K]: T[P] }\ntype Omit<T, K> = Pick<T, Exclude<keyof T, K>>\ntype Record<K, V> = { [P in K]: V }\n\n-- ============================================================\n-- The metatables of the language's own values\n-- ============================================================\n\n-- A string's methods. The first group is Lua's string library, which a\n-- string really answers to; where Lua answers several values, tilua answers\n-- one, as the global functions do (`find` is an array, `gsub` the new\n-- string). The second group is written the way JavaScript writes it.\n--\n-- Positions are Lua's: `sub` and `slice` count from 1, and `indexOf` is\n-- `nil` when the text is not there.\ndeclare metatable string: {\n __index: {\n upper: (self: string) => string,\n lower: (self: string) => string,\n len: (self: string) => number,\n sub: (self: string, i: number, j?: number) => string,\n rep: (self: string, n: number, separator?: string) => string,\n reverse: (self: string) => string,\n format: (self: string, ...args: unknown[]) => string,\n byte: ((self: string, i?: number) => number) & ((self: string, i: number, j: number) => number[]),\n find: (self: string, pattern: string, init?: number, plain?: boolean) => [number, number, ...string[]] | nil,\n match: (self: string, pattern: string, init?: number) => [...string[]] | nil,\n gmatch: (self: string, pattern: string) => () => [string, ...string[]] | nil,\n gsub: (self: string, pattern: string, replacement: unknown, n?: number) => string,\n\n trim: (self: string) => string,\n trimStart: (self: string) => string,\n trimEnd: (self: string) => string,\n startsWith: (self: string, text: string) => boolean,\n endsWith: (self: string, text: string) => boolean,\n includes: (self: string, text: string) => boolean,\n indexOf: (self: string, text: string, start?: number) => number | nil,\n slice: (self: string, start?: number, stop?: number) => string,\n replace: (self: string, text: string, replacement: string) => string,\n replaceAll: (self: string, text: string, replacement: string) => string,\n padStart: (self: string, length: number, padding?: string) => string,\n padEnd: (self: string, length: number, padding?: string) => string,\n },\n}\n\n-- An array's methods. Lua gives an array no metatable: the compiler lowers\n-- each call to a plain function, so they work on any array, one a Lua\n-- library made included.\n--\n-- Indices are Lua's: the first element is 1, and `indexOf` / `findIndex`\n-- answer `nil` rather than JavaScript's -1. `sort` takes Lua's comparator\n-- (true when `a` comes first). `push`, `pop`, `shift`, `unshift`,\n-- `sort` and `reverse` change the array; everything else returns a new one.\n-- The ones that only read take a `readonly T[]` too \u2014 `as const` lists, and\n-- what a function promised not to change \u2014 as TypeScript's `ReadonlyArray`.\n-- A `filter` whose test is a guard \u2014 `v is S`, or `v => v ~= nil` \u2014\n-- answers an array of what it let through.\ndeclare metatable<T> T[]: {\n __index: {\n find: (self: readonly T[], test: (value: T, index: number) => boolean) => T | nil,\n findIndex: (self: readonly T[], test: (value: T, index: number) => boolean) => number | nil,\n filter: (<S extends T>(self: readonly T[], test: (value: T, index: number) => value is S) => S[])\n & ((self: readonly T[], test: (value: T, index: number) => boolean) => T[]),\n map: <U>(self: readonly T[], transform: (value: T, index: number) => U) => U[],\n forEach: (self: readonly T[], visit: (value: T, index: number) => nil) => nil,\n some: (self: readonly T[], test: (value: T, index: number) => boolean) => boolean,\n every: (self: readonly T[], test: (value: T, index: number) => boolean) => boolean,\n reduce: <U>(self: readonly T[], step: (total: U, value: T, index: number) => U, initial: U) => U,\n -- Asking is not adding: any value may be looked for, and finding it\n -- says it is one of the array's \u2014 `if (names:includes(s))` narrows `s`.\n includes: (self: readonly T[], value: unknown) => value is T,\n indexOf: (self: readonly T[], value: unknown, start?: number) => number | nil,\n join: (self: readonly T[], separator?: string) => string,\n concat: <U>(self: readonly T[], ...others: (readonly U[])[]) => (T | U)[],\n slice: (self: readonly T[], start?: number, stop?: number) => T[],\n flat: (self: readonly T[]) => T[],\n -- JavaScript's, as arrays rather than iterators: `for (const [i, v] in\n -- xs:entries())` walks positions and values, counting from 1.\n keys: (self: readonly T[]) => number[],\n values: (self: readonly T[]) => T[],\n entries: (self: readonly T[]) => [number, T][],\n reverse: (self: T[]) => T[],\n sort: (self: T[], compare?: (a: T, b: T) => boolean) => T[],\n push: (self: T[], ...args: T[]) => number,\n pop: (self: T[]) => T | nil,\n shift: (self: T[]) => T | nil,\n unshift: (self: T[], ...args: T[]) => number,\n },\n}\n\n-- A table's methods. Unlike JavaScript's `Object.keys`, they answer a\n-- tuple, in the order the table's type wrote its members:\n--\n-- const point = { x: 1, y: \"up\" }\n-- point:keys() -- [\"x\", \"y\"]\n-- point:values() -- [number, string]\n-- point:entries() -- [[\"x\", number], [\"y\", string]]\n--\n-- A Lua table has no order of its own, so the compiler hands its runtime the\n-- keys as the type lists them. An optional member keeps its place, holding\n-- `nil` when it is missing; an indexer's keys follow the named ones. A\n-- member of the table's own with one of these names is what a call reaches,\n-- and a class instance, which has a metatable of its own, has none of them.\n--\n-- The rest are JavaScript's `Object` functions, written as methods of the\n-- table they take first:\n--\n-- point:hasOwn(\"x\") -- Object.hasOwn(point, \"x\")\n-- point:assign({ z: 3 }) -- Object.assign(point, { z: 3 })\n-- point:freeze() -- Object.freeze(point)\n--\n-- `hasOwn` asks the table itself, not what its metatable's `__index`\n-- lends it. `assign` copies each source's members onto the table, later ones\n-- over earlier ones, skipping a `nil` source, and answers the table. `freeze`\n-- is Luau's `table.freeze`; under Lua 5.1, which cannot freeze a table, the\n-- table is answered as it is and `isFrozen` is false.\ndeclare metatable<T extends {}> T: {\n __index: {\n keys: (self: T) => ObjectKeys<T>,\n values: (self: T) => ObjectValues<T>,\n entries: (self: T) => ObjectEntries<T>,\n\n hasOwn: (self: T, key: unknown) => boolean,\n hasOwnProperty: (self: T, key: unknown) => boolean,\n assign: (<U>(self: T, source: U) => T & U)\n & (<U, V>(self: T, a: U, b: V) => T & U & V)\n & (<U, V, W>(self: T, a: U, b: V, c: W) => T & U & V & W)\n -- Generic like the rest: a plain signature would be tried first.\n & (<S extends {}>(self: T, ...sources: S[]) => T),\n freeze: (self: T) => Readonly<T>,\n isFrozen: (self: T) => boolean,\n },\n}\n";
1760
+
1761
+ /**
1762
+ * The Lua 5.1 standard library, always there — as TypeScript always has
1763
+ * JavaScript's. `print`, `pairs`, `string`, `math`, `table`, `pcall`,
1764
+ * `console`: every file can name them with no type library listed in
1765
+ * `tilua.config.json`. A project that wants none of it says `"noLib": true`.
1766
+ *
1767
+ * It is a type library like any other, loaded before the ones a project
1768
+ * lists — so `@tilua-types/roblox` adds Luau's and Roblox's on top of it —
1769
+ * and what it declares runs as Lua's own, except where Lua answers several
1770
+ * values: the compiler lowers those (`pcall`, `string.find`, ...) and the
1771
+ * console, in its `standard` lowering.
1772
+ *
1773
+ * `@tilua-types/lua`, where this used to live, is not loaded when a project
1774
+ * still names it: it would declare everything twice.
1775
+ */
1776
+ declare const STANDARD_LIBRARY_SOURCE = "\n-- The Lua 5.1 standard library, written in tilua.\n--\n-- This is the floor every tilua project stands on, the way TypeScript stands\n-- on JavaScript's: the functions and libraries Lua itself defines, there in\n-- every file without being asked for. Nothing here is Luau's or Roblox's \u2014\n-- `buffer`, `table.create` and the rest live one layer up in\n-- `@tilua-types/roblox`, which adds to it.\n--\n-- Lua's `type()` is not here: what a value is, is asked with the language's\n-- own `typeof v`, which also tells an array from an object.\n--\n-- Adding to it is literal: a name declared again in a later file keeps what\n-- earlier files gave it. `declare table: { find: ... }` in `@tilua-types/roblox` does\n-- not replace this `table`, it extends it, and overloads of a function\n-- accumulate the same way. So the layers really are layers.\n\n-- ============================================================\n-- Base library\n-- ============================================================\n\ndeclare _G: { [string]: unknown }\ndeclare _VERSION: string\n\ndeclare function require(module: unknown): unknown\ndeclare function tostring(value: unknown): string\ndeclare function tonumber(value: unknown, base?: number): number | nil\ndeclare function print(...args: unknown[]): nil\n-- `error` never returns, which is what lets\n-- `if v == nil then error(\"...\") end` narrow the rest of the block.\ndeclare function error(message: unknown, level?: number): never\n\n-- `asserts value` \u2014 narrows the *rest of the enclosing block*, the way\n-- TypeScript's assertion signatures do:\n--\n-- const part = workspace:FindFirstChild(\"Part\") -- Instance | nil\n-- assert(part)\n-- part.Name -- Instance, no `?`\n\ndeclare function assert<T>(value: T, message?: string): asserts value\n\n-- `pcall` and `xpcall` answer the way a JavaScript result object does:\n--\n-- const { success, data, error } = pcall(load, \"config\")\n-- if (success) { use(data) } else { warn(error) }\n--\n-- `data` is what the function returned. These are not Luau's own `pcall`:\n-- where Luau answers several values, tilua has one, and the compiler puts its\n-- own functions in place of those globals (runtime/result.luau) \u2014 for calls,\n-- and for the global read as a value alike. The same goes for `string.find`,\n-- `string.match`, `string.gsub`, `string.byte`, `math.modf`, `math.frexp`,\n-- `next`, `select`, `unpack`, `loadstring`, `pairs`, `ipairs` and\n-- `string.gmatch` below.\ntype PcallResult<T> = { success: true, data: T, error: nil } | { success: false, data: nil, error: unknown }\n\ndeclare function pcall<A extends unknown[], T>(fn: (...args: A) => T, ...args: A): PcallResult<T>\ndeclare function xpcall<A extends unknown[], T>(fn: (...args: A) => T, handler: (err: unknown) => unknown, ...args: A): PcallResult<T>\n-- `select(\"#\", ...args)` counts; `select(n, ...args)` is what follows the\n-- n-th, as an array.\ndeclare function select(n: \"#\", ...args: unknown[]): number\ndeclare function select<T>(n: number, ...args: T[]): T[]\n-- A copy of the list, or of part of it.\ndeclare function unpack<V>(list: readonly V[], i?: number, j?: number): V[]\ndeclare function rawget(t: unknown, key: unknown): unknown\ndeclare function rawset<T>(t: T, key: unknown, value: unknown): T\ndeclare function rawequal(a: unknown, b: unknown): boolean\ndeclare function setmetatable<T>(t: T, mt: unknown): T\ndeclare function getmetatable(t: unknown): unknown\ndeclare function newproxy(addMeta?: boolean): unknown\n-- The entry after `key` \u2014 or nil, past the last one.\ndeclare function next<K, V>(t: { [K]: V }, key?: K): [K, V] | nil\n\n-- What `for (const item in source)` walks: `step` is called with the state\n-- and the item before it \u2014 `first` the first time \u2014 until it answers nil.\n-- An array, a table and an iterator function are walked too, so this is only\n-- what a source such as `pairs(t)` hands over.\ntype Iteration<S, T> = [(state: S, previous: T | nil) => T | nil, S, T | nil]\n\n-- `for (const [k, v] in pairs(t))` / `ipairs(t)`: each item is one `[key,\n-- value]` \u2014 a table, as every array is. The analyzer types it from `t` itself\n-- (a record's keys as literals, an array's elements); these declare the\n-- names, and their shape for any other use. Walking a list only reads it, so\n-- a read-only one (`as const`, `readonly T[]`) is walked as well.\ndeclare function pairs<V>(t: readonly V[]): Iteration<readonly V[], [number, V]>\ndeclare function pairs<K, V>(t: { [K]: V }): Iteration<{ [K]: V }, [K, V]>\ndeclare function ipairs<V>(t: readonly V[]): Iteration<readonly V[], [number, V]>\n\ndeclare function collectgarbage(option: \"count\"): number\ndeclare function gcinfo(): number\ndeclare function getfenv(target?: unknown): { [string]: unknown }\ndeclare function setfenv<T>(target: T, env: { [string]: unknown }): T\ndeclare function loadstring(source: string, chunkname?: string): [((...args: unknown[]) => unknown) | nil, string | nil]\n\ndeclare debug: {\n traceback: (message?: string, level?: number) => string,\n}\n\ndeclare string: {\n format: (fmt: string, ...args: unknown[]) => string,\n sub: (s: string, i: number, j?: number) => string,\n len: (s: string) => number,\n upper: (s: string) => string,\n lower: (s: string) => string,\n rep: (s: string, n: number, sep?: string) => string,\n reverse: (s: string) => string,\n -- Where the pattern is, then what it captured \u2014 or nil.\n find: (s: string, pattern: string, init?: number, plain?: boolean) => [number, number, ...string[]] | nil,\n -- What it captured (the whole match when there are no captures), as\n -- JavaScript's `match` answers \u2014 or nil.\n match: (s: string, pattern: string, init?: number) => [...string[]] | nil,\n -- Each match's captures (the whole match when there are none), one\n -- array at a time: `for (const [word] in s:gmatch(\"%a+\"))`.\n gmatch: (s: string, pattern: string) => () => [string, ...string[]] | nil,\n -- The new string, as JavaScript's `replace` answers; Luau's count of\n -- replacements is left behind.\n gsub: (s: string, pattern: string, repl: unknown, n?: number) => string,\n -- One code for one position; an array of them for a range.\n byte: ((s: string, i?: number) => number) & ((s: string, i: number, j: number) => number[]),\n char: (...args: number[]) => string,\n}\n\ndeclare math: {\n abs: (x: number) => number,\n floor: (x: number) => number,\n ceil: (x: number) => number,\n fmod: (x: number, y: number) => number,\n modf: (x: number) => [number, number],\n sqrt: (x: number) => number,\n pow: (x: number, y: number) => number,\n exp: (x: number) => number,\n log: (x: number, base?: number) => number,\n log10: (x: number) => number,\n frexp: (x: number) => [number, number],\n ldexp: (m: number, e: number) => number,\n min: (...args: number[]) => number,\n max: (...args: number[]) => number, \n sin: (x: number) => number,\n cos: (x: number) => number,\n tan: (x: number) => number,\n asin: (x: number) => number,\n acos: (x: number) => number,\n atan: (x: number) => number,\n atan2: (y: number, x: number) => number,\n sinh: (x: number) => number,\n cosh: (x: number) => number,\n tanh: (x: number) => number,\n rad: (deg: number) => number,\n deg: (rad: number) => number,\n random: (m?: number, n?: number) => number,\n randomseed: (x: number) => nil,\n huge: number,\n pi: number,\n}\n\n\ndeclare table: {\n -- `insert(t, v)` appends; `insert(t, pos, v)` puts it there.\n insert: (<T>(t: T[], value: T) => nil) & (<T>(t: T[], pos: number, value: T) => nil),\n remove: <T>(t: T[], pos?: number) => T | nil,\n concat: (t: readonly (string | number)[], sep?: string, i?: number, j?: number) => string,\n sort: <T>(t: T[], compare?: (a: T, b: T) => boolean) => nil,\n -- Lua 5.1's originals. Deprecated there and gone from 5.2 on, but Luau\n -- still answers to them, so code being ported still type-checks.\n getn: <T>(t: readonly T[]) => number,\n maxn: <T>(t: readonly T[]) => number,\n foreach: <K, V, R>(t: { [K]: V }, f: (key: K, value: V) => R) => R | nil,\n foreachi: <V, R>(t: readonly V[], f: (index: number, value: V) => R) => R | nil,\n}\n\ndeclare os: {\n time: (t?: unknown) => number,\n clock: () => number,\n date: (format?: string, time?: number) => unknown,\n difftime: (a: number, b: number) => number,\n}\n\ndeclare coroutine: {\n create: (fn: (...args: unknown[]) => unknown) => thread,\n -- Answers like `pcall`: `{ success, data, error }`, `data` what the\n -- coroutine yielded or returned.\n resume: (co: thread, ...args: unknown[]) => PcallResult<unknown>,\n yield: (...args: unknown[]) => unknown,\n wrap: (fn: (...args: unknown[]) => unknown) => (...args: unknown[]) => unknown,\n status: (co: thread) => string,\n running: () => thread,\n}\n\n-- A string's, an array's and a table's methods \u2014 `text:trim()`,\n-- `names:filter(f)`, `point:keys()` \u2014 are the language's: their metatables\n-- are declared in @tilua/parser's prelude, and the compiler runs them. A\n-- library adds to one with `declare metatable` of the same target, as\n-- `@tilua-types/roblox` gives a string Luau's `split`.\n\n-- The console. Written with `:` \u2014 `console:log(value)` \u2014 and lowered by the\n-- compiler (standard.ts) into runtime/console.luau, not into `print`.\n--\n-- Every line starts with the place that called it: `[src/main:12]: ...`.\n-- `print` and `warn` are left as written; `error` puts `src/main.tilua:12:` in\n-- its message, as Lua does.\n--\n-- `log` expands what it is given the way a browser console does: a table is\n-- printed as its contents, not as an address. A function prints as the type it\n-- was inferred to have *and* the code it was written as, both of which the\n-- compiler passes along, since neither exists once the code is running.\n--\n-- `error` reports in the project's own files: a bundle is one Luau file, so\n-- Luau's own line numbers name a file nobody wrote. It does not raise on the\n-- calling thread \u2014 the error goes to `task.spawn`, so reporting a problem\n-- never becomes one.\ntype Console = {\n log: (self: Console, ...args: unknown[]) => nil,\n warn: (self: Console, ...args: unknown[]) => nil,\n error: (self: Console, ...args: unknown[]) => nil,\n}\n\ndeclare console: Console\n";
1777
+ /** The standard library, parsed once. */
1778
+ declare function standardLibrary(): Program;
1779
+ /** The globals the standard library declares: `print`, `string`, ... */
1780
+ declare function standardGlobals(): readonly string[];
1620
1781
 
1621
1782
  interface ProjectHost {
1622
1783
  /** A file's text, or `undefined` when there is no such file. */
@@ -1649,9 +1810,22 @@ interface TiluaConfig {
1649
1810
  * syntax for. The parser does not care — it is the compiler's to act on,
1650
1811
  * and lives here because it belongs to the project. */
1651
1812
  readonly target: BuildTarget;
1813
+ /** How many files the compiler writes. `"single"` (the default) is one
1814
+ * file holding every module. `"chunks"` keeps what the entry imports in
1815
+ * the entry's file and writes what only an `import()` reaches to files of
1816
+ * their own, loaded when first asked for. `"modules"` writes one file per
1817
+ * module. Like `target`, it is the compiler's to act on. */
1818
+ readonly output: OutputMode;
1819
+ /** Leave out Lua's standard library, which every file otherwise has the
1820
+ * way every TypeScript file has JavaScript's: `print`, `string`, `pcall`.
1821
+ * For a host that offers none of it, or a library of one's own in its
1822
+ * place. `false` unless set. */
1823
+ readonly noLib: boolean;
1652
1824
  }
1653
1825
  /** `"luau"` is Roblox's Lua. `"lua51"` is stock Lua 5.1. */
1654
1826
  type BuildTarget = "luau" | "lua51";
1827
+ /** See `TiluaConfig.output`. */
1828
+ type OutputMode = "single" | "chunks" | "modules";
1655
1829
  interface ConfigProblem {
1656
1830
  /** The file the problem is about: a config file, or a sourcemap it names. */
1657
1831
  readonly file: string;
@@ -1857,6 +2031,10 @@ interface MethodLowering extends CallLowering {
1857
2031
  declare function moduleCandidates(fromFile: string, specifier: string, config?: TiluaConfig): string[];
1858
2032
  /** The file `specifier` names from `fromFile`, if it exists. */
1859
2033
  declare function resolveModulePath(fromFile: string, specifier: string, config?: TiluaConfig, host?: ProjectHost): string | undefined;
2034
+ /** Every `import("...")` in `program`, wherever it is written — in the order
2035
+ * they are written. A module they name belongs to the project as much as one
2036
+ * an `import` statement names, though nothing says so at the top of the file. */
2037
+ declare function importExpressions(program: Program): ImportExpression[];
1860
2038
 
1861
2039
  interface SourceMapNode {
1862
2040
  name: string;
@@ -1957,4 +2135,4 @@ declare const tilua: {
1957
2135
  readonly analyzeTypes: typeof analyzeTypes;
1958
2136
  };
1959
2137
 
1960
- 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 DeclareMetatableStatement, 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, LANGUAGE_GLOBALS, LUAU_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 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 TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type Unification, type UnionType, type UnionTypeNode, type UnknownType, type VariableDeclaration, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, escapeLuauString, falsyType, findConfig, fn, formatType, getBinding, hasMembers, intersection, isAssignable, isClassType, isFunctionType, isGlobal, isIdentifier, isInstanceOf, isLuauName, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, luauString, matchInfer, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, returnsTuple, setAliasExpander, setDeferredBound, sourceMapTypes, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, tupleMembers, typeParam, unify, union, unknownType, widen, withAliasName, withoutAliasName, withoutNil };
2138
+ 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 DeclareMetatableStatement, type DeclareStatement, type DifferenceType, 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 ImportExpression, type ImportSpecifier, type ImportStatement, type IndexExpression, type IndexedAccessType, type IndexedAccessTypeNode, type InferType, type InferTypeNode, type InterfaceParts, type InterpolatedStringExpression, type InterpolatedStringPart, type InterpolatedStringPart_Expression, type InterpolatedStringPart_String, type InterpolatedStringToken, type IntersectionType, type IntersectionTypeNode, type KeyofType, type KeyofTypeNode, type KeywordToken, Keywords, LANGUAGE_GLOBALS, LUAU_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 NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, type OutputMode, 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 RestTypeNode, type ReturnStatement, STANDARD_LIBRARY_SOURCE, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SourceComment, type SourceMapNode, type SourceMapOptions, type SourceMapTypes, type SpreadElement, type SpreadType, type Statement, type StringLiteral, type SuperExpression, THIS_TYPE, 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 TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, UNUSED_EXPECT_ERROR, type UnaryExpression, UnaryOperators, type Unification, type UnionType, type UnionTypeNode, type UnknownType, type VariableDeclaration, type WhileStatement, aliasNameOf, analyzeScopes, analyzeTypes, anyType, applyDirectives, arrayOf, booleanType, bufferType, containsTypeParam, declaredUnknownType, tilua as default, difference, directivesOf, equalTypes, escapeLuauString, falsyType, findConfig, fn, formatType, getBinding, hasMembers, hasSpread, importExpressions, intersection, isAssignable, isClassType, isFunctionType, isGlobal, isIdentifier, isInstanceOf, isLuauName, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, loadConfig, luauString, matchInfer, mentionsThis, minLengthOf, moduleCandidates, moduleExports, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, nodeHost, numberType, objectKeywordType, objectType, optional, overlaps, paramsAsTuple, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, readDirectives, resolveModulePath, resolveTypeLibraries, returnsTuple, setAliasExpander, setBuiltinMember, setDeferredBound, sourceMapTypes, spread, standardGlobals, standardLibrary, stringType, stripJsonComments, substitute, templateMatches, threadType, tilua, tokenize, tuple, tupleLength, tupleMembers, tupleMeta, tupleParams, typeParam, unify, union, unknownType, widen, withAliasName, withThis, withoutAliasName, withoutNil, withoutReceiver };