@tilua/parser 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1675 @@
1
+ interface BaseToken {
2
+ line: {
3
+ start: number;
4
+ end: number;
5
+ };
6
+ column: {
7
+ start: number;
8
+ end: number;
9
+ };
10
+ }
11
+ declare const Keywords: readonly ["and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", "continue", "const", "let", "import", "export", "from", "as"];
12
+ interface KeywordToken extends BaseToken {
13
+ type: "Keyword";
14
+ value: typeof Keywords[number];
15
+ }
16
+ interface IdentifierToken extends BaseToken {
17
+ type: "Identifier";
18
+ value: string;
19
+ }
20
+ type LiteralToken = (BaseToken & {
21
+ type: "Literal";
22
+ kind: "number";
23
+ value: number;
24
+ raw: string;
25
+ }) | (BaseToken & {
26
+ type: "Literal";
27
+ kind: "string";
28
+ value: string;
29
+ raw: string;
30
+ }) | (BaseToken & {
31
+ type: "Literal";
32
+ kind: "nil";
33
+ value: null;
34
+ }) | (BaseToken & {
35
+ type: "Literal";
36
+ kind: "boolean";
37
+ value: boolean;
38
+ });
39
+ declare const Operators: readonly ["+=", "-=", "*=", "/=", "//=", "%=", "^=", "..=", "==", "~=", "<=", ">=", "//", "..", "...", "+", "-", "*", "/", "%", "^", "#", "<", ">", "="];
40
+ interface OperatorToken extends BaseToken {
41
+ type: "Operator";
42
+ value: typeof Operators[number];
43
+ }
44
+ declare const Punctuators: readonly ["::", "(", ")", "{", "}", "[", "]", ";", ":", ",", ".", "?", "=>", "->", "&", "|", "@"];
45
+ interface PunctuatorToken extends BaseToken {
46
+ type: "Punctuator";
47
+ value: typeof Punctuators[number];
48
+ }
49
+ interface InterpolatedStringPart_String {
50
+ kind: "string";
51
+ value: string;
52
+ raw: string;
53
+ }
54
+ interface InterpolatedStringPart_Expression {
55
+ kind: "expression";
56
+ raw: string;
57
+ /** Where `raw` starts in the file, so what is parsed from it can be
58
+ * placed there rather than at the top of an imaginary one. */
59
+ line: number;
60
+ column: number;
61
+ }
62
+ interface InterpolatedStringToken extends BaseToken {
63
+ type: "InterpolatedString";
64
+ parts: (InterpolatedStringPart_String | InterpolatedStringPart_Expression)[];
65
+ }
66
+ interface EOFToken extends BaseToken {
67
+ type: "EOF";
68
+ }
69
+ type Token = KeywordToken | LiteralToken | OperatorToken | PunctuatorToken | IdentifierToken | InterpolatedStringToken | EOFToken;
70
+ declare class LexError extends Error {
71
+ line: number;
72
+ column: number;
73
+ constructor(message: string, line: number, column: number);
74
+ }
75
+ /** A `--` comment: its text after the dashes (a long comment's content), and
76
+ * where it starts and ends. */
77
+ interface SourceComment {
78
+ text: string;
79
+ line: number;
80
+ column: number;
81
+ endLine: number;
82
+ }
83
+ interface TokenizeOptions {
84
+ /** When given, a malformed token is recorded here instead of thrown, and
85
+ * lexing goes on: an unclosed string or comment ends at the end of its
86
+ * line (a long bracket at the end of the source), and a character that
87
+ * starts no token is skipped. An editor mid-keystroke still gets every
88
+ * other token. */
89
+ errors?: LexError[];
90
+ /** When given, every comment is collected here, in order. */
91
+ comments?: SourceComment[];
92
+ }
93
+ declare function tokenize(source: string, options?: TokenizeOptions): Token[];
94
+
95
+ /**
96
+ * Comments that switch checking off, as TypeScript's `// @ts-...` comments do:
97
+ *
98
+ * --@tilua-nocheck no scope or type errors anywhere in this file
99
+ * --@tilua-ignore none on the next line of code
100
+ * --@tilua-expect-error none on the next line of code, and an error if
101
+ * that line has none to suppress
102
+ *
103
+ * A space after `--` is fine, and so is text after the directive (a reason).
104
+ * `nocheck` counts only in the comments before the first line of code, as in
105
+ * TypeScript. Syntax errors are never suppressed: code that does not parse
106
+ * cannot be compiled either way.
107
+ */
108
+ type DirectiveKind = "nocheck" | "ignore" | "expect-error";
109
+ interface Directive {
110
+ kind: DirectiveKind;
111
+ /** Where the comment starts. */
112
+ line: number;
113
+ column: number;
114
+ /** `ignore` / `expect-error`: the line whose diagnostics it covers — the
115
+ * next line with code on it. */
116
+ target?: number;
117
+ }
118
+ interface Directives {
119
+ /** The file has `--@tilua-nocheck` before its first line of code. */
120
+ nocheck: boolean;
121
+ /** Every directive, in order — a `nocheck` after the code starts included,
122
+ * so a tool can point out that it does nothing. */
123
+ all: Directive[];
124
+ }
125
+ /** The directives in `comments`, placed against `tokens` (both from one
126
+ * `tokenize` of the file). */
127
+ declare function readDirectives(comments: readonly SourceComment[], tokens: readonly Token[]): Directives;
128
+ /** The directives of `source`, for a caller that parsed it some other way. */
129
+ declare function directivesOf(source: string): Directives;
130
+ interface DirectiveOutcome<T> {
131
+ /** The diagnostics no directive suppresses. */
132
+ kept: T[];
133
+ /** `--@tilua-expect-error` comments with nothing to suppress. Each is an
134
+ * error to report: "Unused '@tilua-expect-error' directive". */
135
+ unusedExpectErrors: Directive[];
136
+ }
137
+ /** Filter scope and type diagnostics — never syntax errors — through the
138
+ * file's directives. `lineOf` gives the line a diagnostic starts on. */
139
+ declare function applyDirectives<T>(directives: Directives, diagnostics: readonly T[], lineOf: (diagnostic: T) => number): DirectiveOutcome<T>;
140
+ declare const UNUSED_EXPECT_ERROR = "Unused '@tilua-expect-error' directive";
141
+
142
+ interface BaseNode {
143
+ line: {
144
+ start: number;
145
+ end: number;
146
+ };
147
+ column: {
148
+ start: number;
149
+ end: number;
150
+ };
151
+ }
152
+ interface Program extends BaseNode {
153
+ type: "Program";
154
+ body: Block;
155
+ }
156
+ interface Block extends BaseNode {
157
+ type: "Block";
158
+ statements: Statement[];
159
+ }
160
+ interface ImportSpecifier extends BaseNode {
161
+ type: "ImportSpecifier";
162
+ /** the exported name in the source module */
163
+ imported: Identifier;
164
+ /** the local binding name — same as `imported` unless renamed with `as` */
165
+ local: Identifier;
166
+ }
167
+ interface ImportStatement extends BaseNode {
168
+ type: "ImportStatement";
169
+ /** `import Default from '...'` */
170
+ defaultImport?: Identifier;
171
+ /** `import * as Module from '...'` — the module's exports as one value. */
172
+ namespaceImport?: Identifier;
173
+ /** `import type { A } from '...'`: every name it brings in is a type and
174
+ * may only be used as one — never as a value. It exists for the type
175
+ * checker alone, and leaves nothing in compiled code. */
176
+ isTypeOnly?: boolean;
177
+ /** `import { a, b as c } from '...'` */
178
+ specifiers: ImportSpecifier[];
179
+ source: StringLiteral;
180
+ }
181
+ /** `export const x = 1`, `export let y = 2`, `export function f() end` */
182
+ interface ExportStatement extends BaseNode {
183
+ type: "ExportStatement";
184
+ declaration: VariableDeclaration | FunctionDeclaration | ClassDeclaration;
185
+ }
186
+ /** `export default <expr>` — mirrors JS default export / dynamic import()'s
187
+ * `{ default: ... }` shape. Distinct from ExportStatement because the
188
+ * right-hand side is any expression, not necessarily a declaration. */
189
+ interface ExportDefaultStatement extends BaseNode {
190
+ type: "ExportDefaultStatement";
191
+ /** `export default class Name ... end` keeps its name: it declares the
192
+ * class here as well as exporting it, the way TypeScript's does. */
193
+ declaration: Expression | ClassDeclaration;
194
+ }
195
+ interface ExportSpecifier extends BaseNode {
196
+ type: "ExportSpecifier";
197
+ /** The name in this module — or, with `from`, in the other module. */
198
+ local: Identifier;
199
+ /** The name it is exported as — same as `local` unless renamed with `as`. */
200
+ exported: Identifier;
201
+ }
202
+ /** `export { a, b as c }` exports names declared elsewhere in the module;
203
+ * `export { a, b as c } from "./x"` re-exports another module's names. */
204
+ interface ExportNamedStatement extends BaseNode {
205
+ type: "ExportNamedStatement";
206
+ specifiers: ExportSpecifier[];
207
+ source?: StringLiteral;
208
+ }
209
+ /** `export * from "./x"` — every named export of another module (not its
210
+ * default), except names this module exports itself. */
211
+ interface ExportAllStatement extends BaseNode {
212
+ type: "ExportAllStatement";
213
+ source: StringLiteral;
214
+ }
215
+ type Statement = VariableDeclaration | FunctionDeclaration | FunctionDeclarationStatement | ClassDeclaration | AssignmentStatement | CompoundAssignmentStatement | CallStatement | ExpressionStatement | DoStatement | WhileStatement | RepeatStatement | IfStatement | NumericForStatement | GenericForStatement | ReturnStatement | BreakStatement | ContinueStatement | TypeAliasStatement | ExportTypeAliasStatement | ImportStatement | ExportStatement | ExportDefaultStatement | ExportNamedStatement | ExportAllStatement | DeclareStatement | DeclareClassStatement | ErrorStatement;
216
+ /** `declare game: DataModel` / `declare function require(m: string): unknown`
217
+ * — an ambient value/function declaration for a definitions file (`.d.tilua`).
218
+ * Contributes a global type; emits no runtime code. */
219
+ interface DeclareStatement extends BaseNode {
220
+ type: "DeclareStatement";
221
+ name: string;
222
+ /** The name as a node, so tools can point at it — `name` has no span. */
223
+ id: Identifier;
224
+ /** the declared value's type (function form is lowered to a FunctionTypeNode) */
225
+ valueType: TypeNode;
226
+ }
227
+ /** `declare class Part extends BasePart { Shape: EnumItem }` — a *nominal*
228
+ * type for a definitions file, the way Roblox's own classes are: a `Part` is
229
+ * an `Instance` because it extends one, not because it has the same members,
230
+ * and no table literal is ever a `Part`. The body lists the members the class
231
+ * adds; it inherits the rest. Declares a type only, no value. */
232
+ interface DeclareClassStatement extends BaseNode {
233
+ type: "DeclareClassStatement";
234
+ name: Identifier;
235
+ /** `extends Base` — another class. */
236
+ superclass?: TypeReference;
237
+ body: TableTypeNode;
238
+ }
239
+ /** A statement position that could not be parsed. Only produced when parsing
240
+ * in recovery mode (`parseWithRecovery`); its span covers the skipped tokens
241
+ * so tools can still map a cursor there. */
242
+ interface ErrorStatement extends BaseNode {
243
+ type: "ErrorStatement";
244
+ }
245
+ /** `const x = 1` / `let x, y = a, b` — the only variable-binding form in tilua
246
+ * (Luau's `local` is gone). `const` bindings are immutable and infer literal
247
+ * types (`const n = 1` → `1`); `let` bindings are mutable and widen. */
248
+ interface VariableDeclaration extends BaseNode {
249
+ type: "VariableDeclaration";
250
+ kind: "const" | "let";
251
+ names: BindingTarget[];
252
+ init: Expression[];
253
+ }
254
+ type BindingTarget = IdentifierPattern | ObjectPattern | ArrayPattern;
255
+ interface IdentifierPattern extends BaseNode {
256
+ type: "IdentifierPattern";
257
+ name: string;
258
+ /** only meaningful at the top level of a binding (`local x: T`, `{a}: T`) */
259
+ typeAnnotation?: TypeNode;
260
+ /** `local x <const>` attribute list */
261
+ attributes?: string[];
262
+ }
263
+ interface ObjectPattern extends BaseNode {
264
+ type: "ObjectPattern";
265
+ properties: ObjectPatternProperty[];
266
+ /** `...rest` — collects the remaining own keys into a new object */
267
+ rest?: BindingTarget;
268
+ typeAnnotation?: TypeNode;
269
+ }
270
+ interface ObjectPatternProperty extends BaseNode {
271
+ type: "ObjectPatternProperty";
272
+ /** identifier/string key, or any expression when `computed` */
273
+ key: Identifier | StringLiteral | Expression;
274
+ computed: boolean;
275
+ /** binding target; for shorthand this is an IdentifierPattern named after `key` */
276
+ value: BindingTarget;
277
+ /** `{ a = 1 }` / `{ a: b = 1 }` default */
278
+ default?: Expression;
279
+ shorthand: boolean;
280
+ }
281
+ interface ArrayPattern extends BaseNode {
282
+ type: "ArrayPattern";
283
+ /** `null` entries are elision holes (`[, a]`) */
284
+ elements: (ArrayPatternElement | null)[];
285
+ /** `...rest` — collects the remaining elements into a new array */
286
+ rest?: BindingTarget;
287
+ typeAnnotation?: TypeNode;
288
+ }
289
+ interface ArrayPatternElement extends BaseNode {
290
+ type: "ArrayPatternElement";
291
+ value: BindingTarget;
292
+ default?: Expression;
293
+ }
294
+ /** `function f() ... end` — declares `f` in the enclosing scope, visible to
295
+ * its own body (so it can recurse). Like TypeScript's function declaration,
296
+ * the name cannot be reassigned. `function a.b() end` and `function T:m() end`
297
+ * assign to a member instead: see `FunctionDeclarationStatement`. */
298
+ interface FunctionDeclaration extends BaseNode {
299
+ type: "FunctionDeclaration";
300
+ /** The name on the line the body is written on, when the declaration is
301
+ * an overload set — `name` is the first signature's. */
302
+ implementationName?: Identifier;
303
+ name: Identifier;
304
+ func: FunctionBody;
305
+ attributes?: string[];
306
+ /** TS-style overload signatures preceding the implementation (`func`). */
307
+ signatures?: FunctionSignature[];
308
+ }
309
+ /** `function a.b() end` / `function T:m() end` — defines a member. */
310
+ interface FunctionDeclarationStatement extends BaseNode {
311
+ type: "FunctionDeclarationStatement";
312
+ target: FunctionName;
313
+ isMethod: boolean;
314
+ func: FunctionBody;
315
+ attributes?: string[];
316
+ /** TS-style overload signatures preceding the implementation (`func`). */
317
+ signatures?: FunctionSignature[];
318
+ }
319
+ /** A bodyless function declaration — an overload signature. tilua uses the
320
+ * exact TS shape: one or more `function f(...): T` lines with no `end`,
321
+ * followed by the implementation `function f(...) ... end`. */
322
+ interface FunctionSignature extends BaseNode {
323
+ type: "FunctionSignature";
324
+ /** The name this signature was written with — one line of an overload
325
+ * set, each of which a tool can point at on its own. */
326
+ name?: Identifier;
327
+ generics: GenericTypeParameter[];
328
+ params: FunctionParameter[];
329
+ hasVarargs: boolean;
330
+ varargTypeAnnotation?: TypeNode;
331
+ returnType?: TypeNode;
332
+ /** `: v is T` / `: asserts v` instead of a plain return type. */
333
+ predicate?: TypePredicateNode;
334
+ }
335
+ interface FunctionName extends BaseNode {
336
+ type: "FunctionName";
337
+ base: Identifier;
338
+ path: Identifier[];
339
+ method?: Identifier;
340
+ }
341
+ /** `class Name extends Base ... end` — tilua's one runtime class form.
342
+ *
343
+ * It is sugar, and the shape it stands for is the ordinary Lua one: the
344
+ * class is a single table holding the methods and the statics, and an
345
+ * instance is a table whose metatable points at it. An instance therefore
346
+ * references *the class*, not a copy and not a prototype chain of its own —
347
+ * one class, one place its behaviour lives.
348
+ *
349
+ * The declaration contributes both a type (the instance type, nominal, as
350
+ * `declare class` does) and a value (the class table, with `new` and the
351
+ * statics on it). */
352
+ interface ClassDeclaration extends BaseNode {
353
+ type: "ClassDeclaration";
354
+ name: Identifier;
355
+ /** `class Box<T>` — the instance type is then generic, and `Box<number>`
356
+ * instantiates it. */
357
+ typeParams: GenericTypeParameter[];
358
+ /** `extends Base` / `extends Box<number>` — another class declared in
359
+ * this file or imported, with its own arguments filled in. */
360
+ superclass?: Identifier;
361
+ /** The arguments `extends Box<number>` was written with. */
362
+ superArguments?: TypeNode[];
363
+ members: ClassMember[];
364
+ }
365
+ /** `class ... end` written where a value goes: `const Counter = class ... end`,
366
+ * `export default class ... end`. The name is optional and, when written, is
367
+ * visible only inside the class — as in JavaScript. An expression has no name
368
+ * to instantiate, so it takes no type parameters. */
369
+ interface ClassExpression extends BaseNode {
370
+ type: "ClassExpression";
371
+ name?: Identifier;
372
+ superclass?: Identifier;
373
+ superArguments?: TypeNode[];
374
+ members: ClassMember[];
375
+ }
376
+ type ClassMember = ClassField | ClassMethod | ClassAccessor | ClassConstructor;
377
+ /** The two ways a class is written. Everything after parsing treats them
378
+ * alike: only the name and the type parameters differ. */
379
+ type ClassLike = ClassDeclaration | ClassExpression;
380
+ /** `x: number` / `x = 1` / `static count = 0`. An instance field is assigned
381
+ * when the instance is built, before the constructor body runs; a `static`
382
+ * one is assigned on the class table, once. */
383
+ interface ClassField extends BaseNode {
384
+ type: "ClassField";
385
+ name: Identifier;
386
+ isStatic: boolean;
387
+ typeAnnotation?: TypeNode;
388
+ init?: Expression;
389
+ }
390
+ /** `function name(...) ... end` inside a class body — `this` is bound in it.
391
+ * A `static` one is a plain function on the class table, with no `this`. */
392
+ interface ClassMethod extends BaseNode {
393
+ type: "ClassMethod";
394
+ name: Identifier;
395
+ isStatic: boolean;
396
+ func: FunctionBody;
397
+ /** TS-style overload signatures preceding the implementation. */
398
+ signatures?: FunctionSignature[];
399
+ }
400
+ /** `get name(): T ... end` / `set name(v: T) ... end` — read and written as a
401
+ * property, run as a function. */
402
+ interface ClassAccessor extends BaseNode {
403
+ type: "ClassAccessor";
404
+ kind: "get" | "set";
405
+ name: Identifier;
406
+ isStatic: boolean;
407
+ func: FunctionBody;
408
+ }
409
+ /** `constructor(...) ... end` — runs on a fresh instance. A class that
410
+ * extends another must call `super(...)` before touching `this`. */
411
+ interface ClassConstructor extends BaseNode {
412
+ type: "ClassConstructor";
413
+ func: FunctionBody;
414
+ }
415
+ /** `new Name(args)` — builds an instance. Lowers to the class's own
416
+ * `Name.new(args)`, which is also callable by hand. */
417
+ interface NewExpression extends BaseNode {
418
+ type: "NewExpression";
419
+ callee: Expression;
420
+ arguments: Expression[];
421
+ typeArguments?: (TypeNode | TypePackNode)[];
422
+ }
423
+ /** `super` — only inside a class that extends another: `super(...)` in the
424
+ * constructor runs the base's on this instance, and `super.method(...)` in a
425
+ * method calls the base's version of it. */
426
+ interface SuperExpression extends BaseNode {
427
+ type: "SuperExpression";
428
+ }
429
+ interface AssignmentStatement extends BaseNode {
430
+ type: "AssignmentStatement";
431
+ targets: (Expression | ObjectPattern | ArrayPattern)[];
432
+ values: Expression[];
433
+ }
434
+ interface CompoundAssignmentStatement extends BaseNode {
435
+ type: "CompoundAssignmentStatement";
436
+ operator: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "^=" | "..=";
437
+ target: Expression;
438
+ value: Expression;
439
+ }
440
+ interface CallStatement extends BaseNode {
441
+ type: "CallStatement";
442
+ expression: CallExpression | MethodCallExpression | NewExpression;
443
+ }
444
+ /** An expression written as a statement, where Lua would want a call or an
445
+ * assignment: `value` on a line of its own.
446
+ *
447
+ * It does nothing, and the compiler drops it. It is here because writing a
448
+ * name and asking the editor about it — hover, completion — is how code gets
449
+ * written, and making that a syntax error means the file stops being
450
+ * analysable exactly when the help is wanted. A call is a `CallStatement`
451
+ * still; this is every other shape. */
452
+ interface ExpressionStatement extends BaseNode {
453
+ type: "ExpressionStatement";
454
+ expression: Expression;
455
+ }
456
+ interface DoStatement extends BaseNode {
457
+ type: "DoStatement";
458
+ body: Block;
459
+ }
460
+ interface WhileStatement extends BaseNode {
461
+ type: "WhileStatement";
462
+ condition: Expression;
463
+ body: Block;
464
+ }
465
+ interface RepeatStatement extends BaseNode {
466
+ type: "RepeatStatement";
467
+ body: Block;
468
+ condition: Expression;
469
+ }
470
+ interface IfClause extends BaseNode {
471
+ type: "IfClause";
472
+ condition: Expression;
473
+ body: Block;
474
+ }
475
+ interface IfStatement extends BaseNode {
476
+ type: "IfStatement";
477
+ clauses: IfClause[];
478
+ alternate?: Block;
479
+ }
480
+ interface NumericForStatement extends BaseNode {
481
+ type: "NumericForStatement";
482
+ variable: TypedIdentifier;
483
+ start: Expression;
484
+ end: Expression;
485
+ step?: Expression;
486
+ body: Block;
487
+ }
488
+ interface GenericForStatement extends BaseNode {
489
+ type: "GenericForStatement";
490
+ variables: BindingTarget[];
491
+ iterators: Expression[];
492
+ body: Block;
493
+ }
494
+ interface ReturnStatement extends BaseNode {
495
+ type: "ReturnStatement";
496
+ arguments: Expression[];
497
+ }
498
+ interface BreakStatement extends BaseNode {
499
+ type: "BreakStatement";
500
+ }
501
+ interface ContinueStatement extends BaseNode {
502
+ type: "ContinueStatement";
503
+ }
504
+ interface TypeAliasStatement extends BaseNode {
505
+ type: "TypeAliasStatement";
506
+ name: Identifier;
507
+ generics: GenericTypeParameter[];
508
+ definition: TypeNode;
509
+ }
510
+ interface ExportTypeAliasStatement extends BaseNode {
511
+ type: "ExportTypeAliasStatement";
512
+ alias: TypeAliasStatement;
513
+ }
514
+ interface GenericTypeParameter extends BaseNode {
515
+ type: "GenericTypeParameter";
516
+ name: string;
517
+ /** The name as a node. Absent on parameters the analyzer synthesizes. */
518
+ id?: Identifier;
519
+ isPack?: boolean;
520
+ /** `<const T>` — infer the argument at its narrowest instead of widening
521
+ * it: literals stay literal and array literals become tuples. */
522
+ isConst?: boolean;
523
+ /** `<T extends C>` upper bound (TS style). */
524
+ constraint?: TypeNode;
525
+ default?: TypeNode | TypePackNode;
526
+ }
527
+ type Expression = Identifier | NilLiteral | BooleanLiteral | NumberLiteral | StringLiteral | InterpolatedStringExpression | VarargExpression | FunctionExpression | TableExpression | ArrayExpression | BinaryExpression | UnaryExpression | MemberExpression | IndexExpression | CallExpression | MethodCallExpression | NewExpression | SuperExpression | ClassExpression | SpreadElement | ParenthesizedExpression | TypeAssertionExpression | SatisfiesExpression | AsConstExpression | IfElseExpression | ErrorExpression;
528
+ /** An expression that could not be parsed. Only produced in recovery mode
529
+ * (`parseWithRecovery`), where a broken initializer, condition, field value or
530
+ * argument keeps its place in the tree; its span covers the skipped tokens
531
+ * (and is empty when nothing was written). Its type is `any`. */
532
+ interface ErrorExpression extends BaseNode {
533
+ type: "ErrorExpression";
534
+ }
535
+ interface Identifier extends BaseNode {
536
+ type: "Identifier";
537
+ name: string;
538
+ }
539
+ interface TypedIdentifier extends BaseNode {
540
+ type: "TypedIdentifier";
541
+ name: string;
542
+ typeAnnotation?: TypeNode;
543
+ attributes?: string[];
544
+ }
545
+ interface NilLiteral extends BaseNode {
546
+ type: "NilLiteral";
547
+ }
548
+ interface BooleanLiteral extends BaseNode {
549
+ type: "BooleanLiteral";
550
+ value: boolean;
551
+ }
552
+ interface NumberLiteral extends BaseNode {
553
+ type: "NumberLiteral";
554
+ value: number;
555
+ raw: string;
556
+ }
557
+ interface StringLiteral extends BaseNode {
558
+ type: "StringLiteral";
559
+ value: string;
560
+ raw: string;
561
+ }
562
+ type InterpolatedStringPart = {
563
+ kind: "string";
564
+ value: string;
565
+ raw: string;
566
+ } | {
567
+ kind: "expression";
568
+ expression: Expression;
569
+ };
570
+ interface InterpolatedStringExpression extends BaseNode {
571
+ type: "InterpolatedStringExpression";
572
+ parts: InterpolatedStringPart[];
573
+ }
574
+ interface VarargExpression extends BaseNode {
575
+ type: "VarargExpression";
576
+ }
577
+ interface FunctionParameter extends BaseNode {
578
+ type: "FunctionParameter";
579
+ /** `...rest: T[]` — every argument from this position on, as an array,
580
+ * the way JavaScript's rest parameter collects them. It is always last,
581
+ * and the function is a vararg function: `...` still means Lua's pack
582
+ * (`const a, b = ...`), and this is the array of it. */
583
+ rest?: boolean;
584
+ /** `name?: T` — the argument may be omitted, and its type admits `nil`. */
585
+ optional?: boolean;
586
+ /** the parameter name, or `""` when `pattern` is set */
587
+ name: string;
588
+ /** JS-style destructured parameter (`function f({a}, [b]) end`) */
589
+ pattern?: ObjectPattern | ArrayPattern;
590
+ typeAnnotation?: TypeNode;
591
+ /** default value (`function f(a = 1) end`) */
592
+ default?: Expression;
593
+ }
594
+ interface FunctionBody extends BaseNode {
595
+ type: "FunctionBody";
596
+ generics: GenericTypeParameter[];
597
+ params: FunctionParameter[];
598
+ hasVarargs: boolean;
599
+ varargTypeAnnotation?: TypeNode;
600
+ returnType?: TypeNode;
601
+ /** `: v is T` / `: asserts v` instead of a plain return type. */
602
+ predicate?: TypePredicateNode;
603
+ /** Declared as `function T:m(...)`, so `params[0]` is the injected `self`. */
604
+ isMethod?: boolean;
605
+ body: Block;
606
+ }
607
+ interface FunctionExpression extends BaseNode {
608
+ type: "FunctionExpression";
609
+ func: FunctionBody;
610
+ }
611
+ type TableField =
612
+ /** `a: v` or `"a": v` — JS colon syntax (NOT Luau `a = v`). */
613
+ {
614
+ type: "TableFieldNamed";
615
+ key: Identifier | StringLiteral;
616
+ value: Expression;
617
+ }
618
+ /** `[expr]: v` — computed key. */
619
+ | {
620
+ type: "TableFieldComputed";
621
+ key: Expression;
622
+ value: Expression;
623
+ }
624
+ /** `{ a }` shorthand — sugar for `{ a: a }`. */
625
+ | {
626
+ type: "TableFieldShorthand";
627
+ name: Identifier;
628
+ }
629
+ /** `{ ...expr }` — JS object spread. */
630
+ | {
631
+ type: "TableFieldSpread";
632
+ argument: Expression;
633
+ };
634
+ /** `{ a: 1, [k]: v }` — object literal (Luau `{}` narrowed to objects only). */
635
+ interface TableExpression extends BaseNode {
636
+ type: "TableExpression";
637
+ fields: TableField[];
638
+ }
639
+ /** `[1, 2, ...rest]` — array literal. Lowers to a Luau `{1, 2}` sequence table. */
640
+ interface ArrayExpression extends BaseNode {
641
+ type: "ArrayExpression";
642
+ elements: (Expression | SpreadElement)[];
643
+ }
644
+ /** `...expr` — the values of an array, one after another, where a list of
645
+ * values is written: inside an array literal (`[...xs, 1]`) and in a call's
646
+ * arguments (`f(a, ...rest)`). It is not a value of its own, and the parser
647
+ * only produces one in those two places.
648
+ *
649
+ * Lua spreads with `table.unpack`, which only yields every value when it is
650
+ * written last; anywhere else the compiler builds the whole list first. Bare
651
+ * `...` is unaffected — that is the vararg pack, and `f(...)` passes it on
652
+ * as it always did. */
653
+ interface SpreadElement extends BaseNode {
654
+ type: "SpreadElement";
655
+ argument: Expression;
656
+ }
657
+ declare const BinaryOperators: readonly ["+", "-", "*", "/", "//", "%", "^", "..", "==", "~=", "<", ">", "<=", ">=", "and", "or"];
658
+ interface BinaryExpression extends BaseNode {
659
+ type: "BinaryExpression";
660
+ operator: typeof BinaryOperators[number];
661
+ left: Expression;
662
+ right: Expression;
663
+ }
664
+ declare const UnaryOperators: readonly ["-", "not", "#"];
665
+ interface UnaryExpression extends BaseNode {
666
+ type: "UnaryExpression";
667
+ operator: typeof UnaryOperators[number];
668
+ argument: Expression;
669
+ }
670
+ interface MemberExpression extends BaseNode {
671
+ type: "MemberExpression";
672
+ object: Expression;
673
+ property: Identifier;
674
+ /** `object?.property` — when `object` is nil, the whole chain this link
675
+ * belongs to is nil and nothing after it is evaluated. */
676
+ optional?: boolean;
677
+ }
678
+ interface IndexExpression extends BaseNode {
679
+ type: "IndexExpression";
680
+ object: Expression;
681
+ index: Expression;
682
+ }
683
+ interface CallExpression extends BaseNode {
684
+ type: "CallExpression";
685
+ callee: Expression;
686
+ arguments: Expression[];
687
+ /** `f<T>(x)` — type arguments written out rather than inferred. */
688
+ typeArguments?: (TypeNode | TypePackNode)[];
689
+ /** `f?.(...)` — see `MemberExpression.optional`. The call does not happen,
690
+ * and the arguments are not evaluated, when `callee` is nil. */
691
+ optional?: boolean;
692
+ /** The `(` opened on a line after the callee ended:
693
+ *
694
+ * const value = map[key]
695
+ * ("text"):upper()
696
+ *
697
+ * is one statement — a call of `map[key]` — because a line break does
698
+ * not end a statement, in Lua or in JavaScript. Flagged here so the
699
+ * analyzer can say so; Lua 5.1 calls it "ambiguous syntax". */
700
+ argumentsOnNewLine?: boolean;
701
+ }
702
+ interface MethodCallExpression extends BaseNode {
703
+ type: "MethodCallExpression";
704
+ object: Expression;
705
+ method: Identifier;
706
+ arguments: Expression[];
707
+ /** `obj:m<T>(x)` — see `CallExpression.typeArguments`. */
708
+ typeArguments?: (TypeNode | TypePackNode)[];
709
+ /** `object?:method(...)` — see `MemberExpression.optional`. The
710
+ * arguments are not evaluated when `object` is nil. */
711
+ optional?: boolean;
712
+ }
713
+ interface ParenthesizedExpression extends BaseNode {
714
+ type: "ParenthesizedExpression";
715
+ expression: Expression;
716
+ }
717
+ /** `expr satisfies T` — checks that `expr` is assignable to `T` without
718
+ * changing its inferred type, so a literal keeps its narrow type while still
719
+ * being validated against a wider contract. Unlike `as`, it never widens or
720
+ * reinterprets. */
721
+ interface SatisfiesExpression extends BaseNode {
722
+ type: "SatisfiesExpression";
723
+ expression: Expression;
724
+ typeAnnotation: TypeNode;
725
+ }
726
+ interface TypeAssertionExpression extends BaseNode {
727
+ type: "TypeAssertionExpression";
728
+ expression: Expression;
729
+ typeAnnotation: TypeNode;
730
+ }
731
+ /** `expr as const` — freezes the expression's inferred type to its narrowest
732
+ * (literal) form, the way TypeScript's `as const` does. Kept as a distinct
733
+ * node from TypeAssertionExpression because there's no TypeNode on the
734
+ * right-hand side: the type checker computes the literal type itself. */
735
+ interface AsConstExpression extends BaseNode {
736
+ type: "AsConstExpression";
737
+ expression: Expression;
738
+ }
739
+ interface IfElseExpression extends BaseNode {
740
+ type: "IfElseExpression";
741
+ clauses: {
742
+ condition: Expression;
743
+ body: Expression;
744
+ }[];
745
+ alternate: Expression;
746
+ }
747
+ type TypeNode = TypeReference | TypeLiteralString | TypeLiteralBoolean | TypeLiteralNumber | TableTypeNode | ArrayTypeNode | TupleTypeNode | FunctionTypeNode | UnionTypeNode | IntersectionTypeNode | ParenthesizedTypeNode | TypeofTypeNode | VariadicTypeNode | TypePackNode | KeyofTypeNode | IndexedAccessTypeNode | ConditionalTypeNode | InferTypeNode | MappedTypeNode | TemplateLiteralTypeNode | DifferenceTypeNode;
748
+ /** `A - B` — every value of `A` that is not a `B`. Binds tighter than `|`
749
+ * and looser than `&`, so `A | B - C` is `A | (B - C)`.
750
+ *
751
+ * Mostly it simplifies away (a union drops members; `string - "a"` is just
752
+ * `string`), but over an opaque type it is retained — which is what lets the
753
+ * `else` of `if a == 1` on an `unknown` say `unknown - 1` instead of
754
+ * forgetting the test. `Exclude<T, U>` is defined as `T - U`. */
755
+ interface DifferenceTypeNode extends BaseNode {
756
+ type: "DifferenceTypeNode";
757
+ base: TypeNode;
758
+ excluded: TypeNode;
759
+ }
760
+ /** A template literal type: `` `on${string}` ``, `` `get${K}` ``.
761
+ * `quasis` are the literal chunks and `types` the interpolated types;
762
+ * `quasis.length === types.length + 1`, exactly as in an ECMAScript template.
763
+ * When every interpolation is a union of string literals the type reduces to
764
+ * the union of all concatenations; otherwise it stays a pattern that literal
765
+ * strings are matched against. */
766
+ interface TemplateLiteralTypeNode extends BaseNode {
767
+ type: "TemplateLiteralTypeNode";
768
+ quasis: string[];
769
+ types: TypeNode[];
770
+ }
771
+ /** `keyof T` — the union of `T`'s property names as string-literal types,
772
+ * plus its indexer key type when it has one. */
773
+ interface KeyofTypeNode extends BaseNode {
774
+ type: "KeyofTypeNode";
775
+ target: TypeNode;
776
+ }
777
+ /** `T[K]` — indexed access. Distinguished from the `T[]` array suffix by
778
+ * whether the brackets are empty. */
779
+ interface IndexedAccessTypeNode extends BaseNode {
780
+ type: "IndexedAccessTypeNode";
781
+ objectType: TypeNode;
782
+ indexType: TypeNode;
783
+ }
784
+ /** `C extends E ? A : B`. Distributes over a naked type parameter, as in
785
+ * TypeScript, which is what makes `Exclude<T, U>` filter a union. */
786
+ interface ConditionalTypeNode extends BaseNode {
787
+ type: "ConditionalTypeNode";
788
+ checkType: TypeNode;
789
+ extendsType: TypeNode;
790
+ trueType: TypeNode;
791
+ falseType: TypeNode;
792
+ }
793
+ /** `infer U`, only meaningful inside a conditional's `extends` clause: it
794
+ * binds `U` to whatever matched at that position. */
795
+ interface InferTypeNode extends BaseNode {
796
+ type: "InferTypeNode";
797
+ name: string;
798
+ /** The bound name as a node. */
799
+ id?: Identifier;
800
+ }
801
+ /** `{ [K in C]: V }` — a mapped type. `optional` / `readonly` carry the
802
+ * modifier as written: `true` adds it (`?`), `false` removes it (`-?`),
803
+ * `undefined` leaves the source property's modifier alone. */
804
+ interface MappedTypeNode extends BaseNode {
805
+ type: "MappedTypeNode";
806
+ /** The name bound to each key in turn (`K`). */
807
+ parameter: string;
808
+ /** `parameter` as a node. */
809
+ parameterId?: Identifier;
810
+ /** The union of keys to map over (`C`). */
811
+ constraint: TypeNode;
812
+ /** `[K in C as R]` — remaps each key through `R`. */
813
+ nameType?: TypeNode;
814
+ /** The property type, which may mention `parameter`. */
815
+ template: TypeNode;
816
+ optional?: boolean;
817
+ readonly?: boolean;
818
+ }
819
+ /** The return position of a TypeScript-style type guard:
820
+ * `function isStr(v: unknown): v is string`, `function check(v): asserts v`,
821
+ * or `function assertStr(v): asserts v is string`.
822
+ *
823
+ * Deliberately *not* a member of `TypeNode` — it may only appear as a
824
+ * function's return annotation, and keeping it out of the union means every
825
+ * existing `TypeNode` consumer stays exhaustive without change. A function
826
+ * carrying one returns `boolean` (`is`) or nothing (`asserts`). */
827
+ interface TypePredicateNode extends BaseNode {
828
+ type: "TypePredicateNode";
829
+ /** Name of the parameter this guard talks about. */
830
+ parameterName: string;
831
+ /** `asserts x` — narrows the rest of the enclosing block, not a branch. */
832
+ asserts: boolean;
833
+ /** Absent for a bare `asserts x` (a truthiness assertion). */
834
+ typeAnnotation?: TypeNode;
835
+ }
836
+ interface TypePackNode extends BaseNode {
837
+ type: "TypePackNode";
838
+ types: TypeNode[];
839
+ hasVarargs: boolean;
840
+ varargType?: TypeNode;
841
+ }
842
+ interface TypeReference extends BaseNode {
843
+ type: "TypeReference";
844
+ base: string;
845
+ namespace?: string;
846
+ typeArguments: (TypeNode | TypePackNode)[];
847
+ }
848
+ interface TypeLiteralString extends BaseNode {
849
+ type: "TypeLiteralString";
850
+ value: string;
851
+ }
852
+ interface TypeLiteralBoolean extends BaseNode {
853
+ type: "TypeLiteralBoolean";
854
+ value: boolean;
855
+ }
856
+ /** `1`, `3.5` — a single-valued number type. The checker already produces
857
+ * these when narrowing (`if n == 1`), so they have to be writable too. */
858
+ interface TypeLiteralNumber extends BaseNode {
859
+ type: "TypeLiteralNumber";
860
+ value: number;
861
+ }
862
+ type TableTypeProperty = ({
863
+ type: "TableTypeIndexer";
864
+ keyType: TypeNode;
865
+ valueType: TypeNode;
866
+ } & BaseNode)
867
+ /** `name: T` (required) or `name?: T` (optional — TS style, the property
868
+ * may be absent). `optional` reflects the `?` after the name only;
869
+ * `name: T | nil` is a required property whose value may be nil. */
870
+ | ({
871
+ type: "TableTypeProperty";
872
+ name: string;
873
+ key: Identifier;
874
+ valueType: TypeNode;
875
+ optional: boolean;
876
+ readonly?: boolean;
877
+ } & BaseNode);
878
+ interface TableTypeNode extends BaseNode {
879
+ type: "TableTypeNode";
880
+ properties: TableTypeProperty[];
881
+ }
882
+ /** `T[]` — array type. Replaces Luau's `{T}` array-table notation. */
883
+ interface ArrayTypeNode extends BaseNode {
884
+ type: "ArrayTypeNode";
885
+ element: TypeNode;
886
+ }
887
+ /** `[number, string]` — fixed-length tuple type. */
888
+ interface TupleTypeNode extends BaseNode {
889
+ type: "TupleTypeNode";
890
+ elements: TypeNode[];
891
+ }
892
+ interface FunctionTypeParameter extends BaseNode {
893
+ type: "FunctionTypeParameter";
894
+ /** `(...rest: T[]) -> R` — see `FunctionParameter.rest`. */
895
+ rest?: boolean;
896
+ /** `name?: T` — the argument may be omitted, and its type admits `nil`. */
897
+ optional?: boolean;
898
+ name?: string;
899
+ /** The name as a node (absent for an unnamed parameter). */
900
+ id?: Identifier;
901
+ typeAnnotation: TypeNode;
902
+ }
903
+ interface FunctionTypeNode extends BaseNode {
904
+ type: "FunctionTypeNode";
905
+ generics: GenericTypeParameter[];
906
+ params: FunctionTypeParameter[];
907
+ hasVarargs: boolean;
908
+ varargType?: TypeNode;
909
+ returnType: TypeNode;
910
+ /** `(v: unknown) -> v is string` — a guard written as a function *type*. */
911
+ predicate?: TypePredicateNode;
912
+ }
913
+ interface UnionTypeNode extends BaseNode {
914
+ type: "UnionTypeNode";
915
+ types: TypeNode[];
916
+ }
917
+ interface IntersectionTypeNode extends BaseNode {
918
+ type: "IntersectionTypeNode";
919
+ types: TypeNode[];
920
+ }
921
+ interface ParenthesizedTypeNode extends BaseNode {
922
+ type: "ParenthesizedTypeNode";
923
+ typeAnnotation: TypeNode;
924
+ }
925
+ /** `typeof x` / `typeof x.y` (TypeScript's type query) or `typeof(expr)`
926
+ * (Luau's spelling): the type of a value. */
927
+ interface TypeofTypeNode extends BaseNode {
928
+ type: "TypeofTypeNode";
929
+ expression: Expression;
930
+ }
931
+ interface VariadicTypeNode extends BaseNode {
932
+ type: "VariadicTypeNode";
933
+ typeAnnotation: TypeNode;
934
+ }
935
+ type Node = Program | Block | Statement | Expression | TypeNode | FunctionBody | FunctionParameter | FunctionName | IfClause | TypedIdentifier | GenericTypeParameter | FunctionSignature | TypePredicateNode | TableField | SpreadElement | FunctionTypeParameter | TableTypeProperty | BindingTarget | ObjectPatternProperty | ArrayPatternElement;
936
+
937
+ declare class ParseError extends Error {
938
+ line: number;
939
+ column: number;
940
+ constructor(message: string, line: number, column: number);
941
+ }
942
+ interface ParserOptions {
943
+ /** When true, `parseProgram` records syntax errors in `.errors` and
944
+ * synchronizes to the next statement boundary instead of throwing on the
945
+ * first one. The returned AST has an `ErrorStatement` wherever a statement
946
+ * could not be parsed. */
947
+ recover?: boolean;
948
+ /** Recovery only: read where a block ends from indentation when an `end`
949
+ * is missing — a line indented no deeper than the line that opened the
950
+ * block is past it. Valid code never needs this; `parseWithRecovery`
951
+ * reparses with it when the first pass found an `end` missing. */
952
+ indentation?: boolean;
953
+ }
954
+ declare function parse(source: string): Program;
955
+ declare function parseTokens(tokens: Token[]): Program;
956
+ /** `inClass` carries the enclosing class in. A template's `${...}` is parsed
957
+ * on its own, so without it a `super` written inside one in a class method
958
+ * would read as an ordinary name. */
959
+ declare function parseExpressionFromSource(raw: string, inClass?: boolean): Expression;
960
+ interface RecoverResult {
961
+ program: Program;
962
+ errors: ParseError[];
963
+ /** The file's `--@tilua-...` comments; see `applyDirectives`. */
964
+ directives: Directives;
965
+ }
966
+ /**
967
+ * Like `parse`, but never throws on a syntax error: it records every error and
968
+ * returns a best-effort AST. A broken expression becomes an `ErrorExpression`,
969
+ * a broken field or argument is skipped to the next `,`, a missing `)`, `}`,
970
+ * `then`, `do` or `end` is recorded and read past, and only what none of those
971
+ * cover becomes an `ErrorStatement`. A malformed token (an unclosed string) is
972
+ * an error too, and the rest of the file still lexes.
973
+ *
974
+ * This is the entry point a language server should use for open documents.
975
+ */
976
+ declare function parseWithRecovery(source: string): RecoverResult;
977
+
978
+ type BindingId = number;
979
+ type BindingKind = "local" | "param" | "self" | "for-numeric" | "for-generic" | "global";
980
+ /** A node that can serve as a binding's "declared here" site. */
981
+ type DeclarationNode = Identifier | TypedIdentifier | FunctionParameter | IdentifierPattern;
982
+ interface Binding {
983
+ readonly id: BindingId;
984
+ /** Name at the point this binding was created. Rename passes update
985
+ * this and every node in `references` (+ `declarationNode`) together —
986
+ * this field is just what analysis saw, not a source of truth after a
987
+ * rename pass has run. */
988
+ name: string;
989
+ readonly kind: BindingKind;
990
+ /** Absent for a `global` binding that was never assigned to in this
991
+ * file (e.g. only ever read, or a pre-registered builtin). */
992
+ declarationNode?: DeclarationNode;
993
+ /** Every Identifier *usage* resolved to this binding (does not include
994
+ * `declarationNode` itself). */
995
+ readonly references: Identifier[];
996
+ /** True for globals pre-registered via `analyzeScopes`'s
997
+ * `builtinGlobals` option (e.g. `game`, `script`, `print`). Such
998
+ * bindings are never given a `declarationNode` from assignment
999
+ * inference, since they're not really "defined" in this file. */
1000
+ isBuiltin?: boolean;
1001
+ /** True for a binding that cannot be reassigned: a `const`, an import, or
1002
+ * a function declaration. */
1003
+ isConst?: boolean;
1004
+ /** Set when the binding comes from something other than `const` / `let`,
1005
+ * which is also what an error about reassigning it names. */
1006
+ declaredBy?: "import" | "namespace" | "function" | "type" | "class";
1007
+ }
1008
+ interface ScopeDiagnostic {
1009
+ /** the offending node (redeclaration site, or assignment target) */
1010
+ node: {
1011
+ line: {
1012
+ start: number;
1013
+ end: number;
1014
+ };
1015
+ column: {
1016
+ start: number;
1017
+ end: number;
1018
+ };
1019
+ };
1020
+ message: string;
1021
+ kind: "redeclare" | "const-assign" | "type-only" | "undeclared" | "use-before-define";
1022
+ }
1023
+ interface ScopeAnalysis {
1024
+ /** Every Identifier that appears in a variable *usage* position (i.e.
1025
+ * every node also reachable through some `Binding.references`, plus
1026
+ * `FunctionDeclarationStatement.target.base`), mapped to its binding.
1027
+ * Property names, method names, table field names, and type-position
1028
+ * identifiers are never entered here — they aren't variable refs. */
1029
+ readonly bindingOf: Map<Identifier | IdentifierPattern, BindingId>;
1030
+ readonly bindings: Map<BindingId, Binding>;
1031
+ /** Redeclaration-in-same-scope and assignment-to-const errors. */
1032
+ readonly diagnostics: ScopeDiagnostic[];
1033
+ /** Convenience: every global binding's id, keyed by name. Global
1034
+ * bindings have no lexical scope, so this is the closest thing to
1035
+ * "the" scope for them — and later a multi-file language server can
1036
+ * swap this map out for a project-wide registry without changing
1037
+ * anything else about this shape. */
1038
+ readonly globalsByName: Map<string, BindingId>;
1039
+ }
1040
+ interface AnalyzeScopesOptions {
1041
+ /** Names to pre-register as global bindings with `isBuiltin: true`
1042
+ * before the walk starts (e.g. Roblox/Luau standard globals:
1043
+ * `game`, `script`, `workspace`, `print`, `pairs`, ...). Referencing
1044
+ * one of these does not count as "defining" it, so `declarationNode`
1045
+ * is left unset even though the binding exists up front. */
1046
+ builtinGlobals?: readonly string[];
1047
+ /** Report each read of a name nothing declares — not a local, not one of
1048
+ * `builtinGlobals`, not `declare`d in the file, never assigned as a
1049
+ * global: "Cannot find name 'x'", as TypeScript says. Only meaningful
1050
+ * when `builtinGlobals` lists everything the file's type libraries
1051
+ * declare, so it is off unless asked for. */
1052
+ reportUndeclared?: boolean;
1053
+ }
1054
+ declare function getBinding(analysis: ScopeAnalysis, id: Identifier | IdentifierPattern): Binding | undefined;
1055
+ declare function isGlobal(binding: Binding): boolean;
1056
+ /** True if a global binding was never assigned to anywhere in this file
1057
+ * (and isn't a pre-registered builtin) — i.e. it's read-only and
1058
+ * undeclared, which is almost always a typo rather than an intentional
1059
+ * implicit global. Handy for a "possibly undefined global" diagnostic. */
1060
+ declare function isUnassignedGlobal(binding: Binding): boolean;
1061
+ declare function analyzeScopes(program: Program, options?: AnalyzeScopesOptions): ScopeAnalysis;
1062
+
1063
+ type Type = AnyType | UnknownType | NeverType | PrimitiveType | LiteralType | ArrayType | TupleType | ObjectType | FunctionType | UnionType | IntersectionType | TypeParamType | GenericRefType | KeyofType | IndexedAccessType | ConditionalType | InferType | MappedType | TemplateLiteralType | DifferenceType;
1064
+ /** `any` — opts out of checking. Assignable to and from everything. */
1065
+ interface AnyType {
1066
+ kind: "any";
1067
+ alias?: string;
1068
+ }
1069
+ /** `unknown` — top type. Everything is assignable to it; it is assignable to nothing but itself. */
1070
+ interface UnknownType {
1071
+ kind: "unknown";
1072
+ alias?: string;
1073
+ /** The `unknown` a program wrote, as opposed to the one the analyzer falls
1074
+ * back to when it cannot work a type out. Only a written one makes reading
1075
+ * a member of it an error — the fallback means "not known here", and
1076
+ * reporting that would be noise. */
1077
+ declared?: boolean;
1078
+ }
1079
+ /** `never` — bottom type. Assignable to everything; nothing (but never) is assignable to it. */
1080
+ interface NeverType {
1081
+ kind: "never";
1082
+ alias?: string;
1083
+ }
1084
+ type PrimitiveName = "nil" | "boolean" | "number" | "string" | "thread" | "buffer";
1085
+ interface PrimitiveType {
1086
+ kind: "primitive";
1087
+ name: PrimitiveName;
1088
+ alias?: string;
1089
+ }
1090
+ /** `"foo"`, `42`, `true` — a single-valued type. `base` is the primitive it widens to. */
1091
+ interface LiteralType {
1092
+ kind: "literal";
1093
+ base: "boolean" | "number" | "string";
1094
+ value: string | number | boolean;
1095
+ alias?: string;
1096
+ }
1097
+ /** `T[]` */
1098
+ interface ArrayType {
1099
+ kind: "array";
1100
+ element: Type;
1101
+ alias?: string;
1102
+ }
1103
+ /** `[A, B, C]` — fixed length.
1104
+ *
1105
+ * `isPack` marks the other thing this shape is used for: a *type pack*, the
1106
+ * several values a Lua function returns (`(number, string)`). The two are
1107
+ * structurally identical but behave differently in an expression list — a
1108
+ * pack spreads across several names, a tuple is one value — so they have to
1109
+ * be told apart. */
1110
+ interface TupleType {
1111
+ kind: "tuple";
1112
+ elements: Type[];
1113
+ isPack?: boolean;
1114
+ alias?: string;
1115
+ }
1116
+ interface ObjectProperty {
1117
+ type: Type;
1118
+ optional: boolean;
1119
+ readonly?: boolean;
1120
+ }
1121
+ interface ObjectType {
1122
+ kind: "object";
1123
+ properties: Map<string, ObjectProperty>;
1124
+ /** `{ [K]: V }` catch-all, if present. */
1125
+ indexer?: {
1126
+ key: Type;
1127
+ value: Type;
1128
+ };
1129
+ /** `object` was produced by `as const` — literal members are kept narrow
1130
+ * and every property is `readonly`. */
1131
+ frozen?: boolean;
1132
+ /** The alias this object was resolved from — display only, ignored by
1133
+ * `isAssignable` (the type is structural). Dropped on `widen`/`substitute`. */
1134
+ name?: string;
1135
+ /** Set on a `declare class` — the type is then *nominal*. See `ClassInfo`. */
1136
+ class?: ClassInfo;
1137
+ }
1138
+ /** What makes an object a class instance. `properties` then holds every
1139
+ * member, inherited ones included. Only the class itself and the classes
1140
+ * extending it are assignable to it — no table literal, no structurally
1141
+ * identical class. Going the other way, a class satisfies a shape naming
1142
+ * members it has (`{ Name: string }`) but is not a table: never a
1143
+ * `{ [K]: V }` or `{}`, which is what keeps `typeof(part)` from matching the
1144
+ * `{ [unknown]: unknown }` overload. */
1145
+ interface ClassInfo {
1146
+ name: string;
1147
+ /** The class it directly extends, if any. */
1148
+ superclass?: string;
1149
+ /** The class itself, then each class it extends, nearest first. */
1150
+ ancestors: readonly string[];
1151
+ /** For a generic class, the arguments each level of the chain was made
1152
+ * with, by class name — its own and every class it extends. `Box<number>`
1153
+ * holds `{ Box: [number] }`, and a `class Ints extends Box<number>` holds
1154
+ * the same entry under `Box`, which is what tells it apart from a
1155
+ * `Box<string>`. A class with no type parameters anywhere carries
1156
+ * nothing, and costs nothing. */
1157
+ typeArguments?: ReadonlyMap<string, readonly Type[]>;
1158
+ }
1159
+ declare function isClassType(t: Type): t is ObjectType & {
1160
+ class: ClassInfo;
1161
+ };
1162
+ interface FunctionParam {
1163
+ name?: string;
1164
+ type: Type;
1165
+ optional?: boolean;
1166
+ }
1167
+ /** A TS-style type guard: `function f(v: unknown): v is string` narrows `v` at
1168
+ * every call site used as a condition. `asserts` variants narrow the *rest of
1169
+ * the enclosing block* instead of a branch (`assert(x)`), and a missing `type`
1170
+ * means a bare truthiness assertion (`asserts v`). */
1171
+ interface TypePredicate {
1172
+ /** Index into `params` of the parameter this guard talks about. */
1173
+ param: number;
1174
+ /** The type the parameter is narrowed to; absent = narrow to truthy. */
1175
+ type?: Type;
1176
+ asserts: boolean;
1177
+ }
1178
+ interface FunctionType {
1179
+ kind: "function";
1180
+ params: FunctionParam[];
1181
+ varargs?: Type;
1182
+ /** A tuple when the function returns multiple values. */
1183
+ returns: Type;
1184
+ /** Names of the function's own generic parameters (`function f<T>(...)`).
1185
+ * `params` / `returns` may contain `typeParam` nodes for these. */
1186
+ typeParams?: string[];
1187
+ /** `<T = Instance>` — what a call uses for a parameter it is not given and
1188
+ * cannot infer. */
1189
+ typeParamDefaults?: Record<string, Type>;
1190
+ /** Set when the function was declared with an `x is T` / `asserts x` return. */
1191
+ predicate?: TypePredicate;
1192
+ alias?: string;
1193
+ }
1194
+ /** A bound generic parameter (`T` inside `function f<T>(...)` or
1195
+ * `type Box<T> = ...`). Resolved away by `substitute` at instantiation.
1196
+ * `constraint` is the `<T extends C>` upper bound, used for member access on a
1197
+ * bare `T` and as the fallback when `T` can't be inferred. */
1198
+ interface TypeParamType {
1199
+ kind: "typeParam";
1200
+ name: string;
1201
+ constraint?: Type;
1202
+ /** Declared `<const T>`: the call site infers the argument at its
1203
+ * narrowest rather than widening it. */
1204
+ isConst?: boolean;
1205
+ }
1206
+ declare function typeParam(name: string, constraint?: Type, isConst?: boolean): TypeParamType;
1207
+ interface UnionType {
1208
+ kind: "union";
1209
+ types: Type[];
1210
+ alias?: string;
1211
+ }
1212
+ interface IntersectionType {
1213
+ kind: "intersection";
1214
+ types: Type[];
1215
+ /** The alias this was resolved from — display only, exactly like
1216
+ * `ObjectType.name`. A class hierarchy written as `type Part = BasePart &
1217
+ * { ... }` is unreadable without it. */
1218
+ name?: string;
1219
+ }
1220
+ /** An unresolved reference: an in-scope generic parameter, or a named type
1221
+ * that couldn't be resolved to an alias in this pass. */
1222
+ interface GenericRefType {
1223
+ kind: "genericRef";
1224
+ name: string;
1225
+ typeArguments: Type[];
1226
+ }
1227
+ /** `keyof T`. */
1228
+ interface KeyofType {
1229
+ kind: "keyof";
1230
+ target: Type;
1231
+ }
1232
+ /** `T[K]`. */
1233
+ interface IndexedAccessType {
1234
+ kind: "indexedAccess";
1235
+ objectType: Type;
1236
+ indexType: Type;
1237
+ }
1238
+ /** `C extends E ? A : B`. */
1239
+ interface ConditionalType {
1240
+ kind: "conditional";
1241
+ checkType: Type;
1242
+ extendsType: Type;
1243
+ trueType: Type;
1244
+ falseType: Type;
1245
+ /** Names bound by `infer` inside `extendsType`. */
1246
+ inferVars: string[];
1247
+ /** Set when `checkType` is a *naked* type parameter, to that parameter's
1248
+ * name. Such a conditional distributes over a union, and inside each
1249
+ * branch the parameter denotes the single member being tested — the
1250
+ * property `Exclude<T, U>` relies on. */
1251
+ distributeParam?: string;
1252
+ }
1253
+ /** `infer U`, valid only inside a conditional's `extends` clause. */
1254
+ interface InferType {
1255
+ kind: "infer";
1256
+ name: string;
1257
+ }
1258
+ /** `A - B` — every value of `A` that is not a `B`.
1259
+ *
1260
+ * Only kept when `A` is *opaque*: `unknown`, or a type parameter or nominal
1261
+ * reference not yet resolved. For a union the subtraction is performed by
1262
+ * dropping members, and for a concrete type such as `string` it is discarded
1263
+ * (`string - "a"` supports exactly the same operations as `string`, and
1264
+ * TypeScript likewise does not track it). For `unknown`, though, the
1265
+ * subtraction is the *only* thing known about the value, so throwing it away
1266
+ * loses the whole result of the test:
1267
+ *
1268
+ * let a: unknown
1269
+ * if a == 1 then -- a: 1
1270
+ * else -- a: unknown - 1
1271
+ * end
1272
+ */
1273
+ interface DifferenceType {
1274
+ kind: "difference";
1275
+ base: Type;
1276
+ excluded: Type;
1277
+ }
1278
+ /** `` `on${string}` `` — literal chunks interleaved with interpolated types
1279
+ * (`quasis.length === types.length + 1`). Reduced to a union of string
1280
+ * literals when every interpolation is one; otherwise it stays a *pattern*
1281
+ * and `isAssignable` matches literal strings against it. */
1282
+ interface TemplateLiteralType {
1283
+ kind: "templateLiteral";
1284
+ quasis: string[];
1285
+ types: Type[];
1286
+ alias?: string;
1287
+ }
1288
+ /** The alias `type` is printed as instead of its structure, if it has one. */
1289
+ declare function aliasNameOf(type: Type): string | undefined;
1290
+ /** The same type, printed as what it is made of. */
1291
+ declare function withoutAliasName(type: Type): Type;
1292
+ /** `type` remembered as the alias it was written as. A type that already
1293
+ * carries one keeps it: the name nearest what the reader wrote wins. */
1294
+ declare function withAliasName(type: Type, alias: string): Type;
1295
+ /** `{ [K in C]: V }`. `optional` / `readonly`: `true` adds the modifier,
1296
+ * `false` strips it, `undefined` inherits it from the source property. */
1297
+ interface MappedType {
1298
+ kind: "mapped";
1299
+ parameter: string;
1300
+ constraint: Type;
1301
+ nameType?: Type;
1302
+ template: Type;
1303
+ optional?: boolean;
1304
+ readonly?: boolean;
1305
+ /** The `T` of `[K in keyof T]`, kept so a homomorphic mapped type can carry
1306
+ * each source property's own `?` / `readonly` across. */
1307
+ source?: Type;
1308
+ }
1309
+ declare const anyType: AnyType;
1310
+ declare const unknownType: UnknownType;
1311
+ declare const declaredUnknownType: UnknownType;
1312
+ declare const neverType: NeverType;
1313
+ declare const nilType: PrimitiveType;
1314
+ declare const booleanType: PrimitiveType;
1315
+ declare const numberType: PrimitiveType;
1316
+ declare const stringType: PrimitiveType;
1317
+ declare const threadType: PrimitiveType;
1318
+ declare const bufferType: PrimitiveType;
1319
+ declare function primitive(name: PrimitiveName): PrimitiveType;
1320
+ declare function literal(value: string | number | boolean): LiteralType;
1321
+ declare function arrayOf(element: Type): ArrayType;
1322
+ declare function tuple(elements: Type[], isPack?: boolean): TupleType;
1323
+ declare function objectType(entries: Iterable<[string, ObjectProperty]>, indexer?: ObjectType["indexer"], frozen?: boolean): ObjectType;
1324
+ declare function fn(params: FunctionParam[], returns: Type, varargs?: Type, typeParams?: string[], predicate?: TypePredicate): FunctionType;
1325
+ declare function substitute(t: Type, subst: Map<string, Type>): Type;
1326
+ declare function unify(param: Type, arg: Type, vars: Set<string>, out: Map<string, Type>): void;
1327
+ declare function union(types: Type[]): Type;
1328
+ declare function intersection(types: Type[]): Type;
1329
+ /** `base - excluded`, simplified as far as the base allows. */
1330
+ declare function difference(base: Type, excluded: Type): Type;
1331
+ /** `T | nil` — the type of an optional property or parameter. */
1332
+ declare function optional(t: Type): Type;
1333
+ /** Widens literal types to their primitive base (the default for a plain
1334
+ * `local x = "foo"` binding, unless `as const` says otherwise). Recurses
1335
+ * into arrays/tuples/objects/unions. */
1336
+ declare function widen(t: Type): Type;
1337
+ declare function setAliasExpander(fn: ((t: GenericRefType) => Type) | undefined): void;
1338
+ declare function setDeferredBound(fn: ((t: Type) => Type | undefined) | undefined): void;
1339
+ declare function isAssignable(rawA: Type, rawB: Type): boolean;
1340
+ declare function equalTypes(a: Type, b: Type): boolean;
1341
+ /** Keep the parts of `t` compatible with `filter` — TypeScript's
1342
+ * `getNarrowedType`. Per union member: a member already assignable to the
1343
+ * filter survives as-is; a member the filter is assignable to is *replaced*
1344
+ * by the filter (so `string` narrowed by `"a"` becomes `"a"`, not `string`);
1345
+ * anything else is dropped. `any` / `unknown` narrow straight to the filter. */
1346
+ declare function narrowTo(t: Type, filter: Type): Type;
1347
+ /** Remove the parts of `t` assignable to `exclude` (the `else` branch).
1348
+ * `boolean` minus a `true`/`false` literal leaves the other literal — the
1349
+ * only primitive here with a finite, enumerable domain. */
1350
+ declare function narrowExclude(t: Type, exclude: Type): Type;
1351
+ /** `nil | false` — every falsy value in Luau. Built literally rather than via
1352
+ * `union()`, which would format its members for deduping and so touch caches
1353
+ * declared further down this module. */
1354
+ declare const falsyType: Type;
1355
+ /** Can a value of this type ever be truthy? */
1356
+ declare function isPossiblyTruthy(t: Type): boolean;
1357
+ /** Can a value of this type ever be falsy? */
1358
+ declare function isPossiblyFalsy(t: Type): boolean;
1359
+ /** Keep only what can be truthy — drops `nil` and the `false` literal, and
1360
+ * narrows a bare `boolean` to `true`. */
1361
+ declare function narrowTruthy(t: Type): Type;
1362
+ /** Keep only what can be falsy — `nil` and `false`. */
1363
+ declare function narrowFalsy(t: Type): Type;
1364
+ declare function containsTypeParam(t: Type, seen?: Set<Type>, bound?: Set<string>): boolean;
1365
+ /** Structurally match `arg` against `pattern`, binding every `infer` name it
1366
+ * contains into `out`. This is what turns `T extends (...unknown) -> infer R`
1367
+ * into `R = <the return type>`. Returns false when the shapes cannot match at
1368
+ * all; a `true` result still needs the usual assignability check. */
1369
+ declare function matchInfer(arg: Type, pattern: Type, out: Map<string, Type>): boolean;
1370
+ /** Does a concrete string match a template literal *pattern*? Each
1371
+ * interpolation is matched against the widest thing it could stand for:
1372
+ * `string` swallows any run, `number` a numeric run, and a literal union only
1373
+ * its own members. Anchored at both ends, like TypeScript. */
1374
+ declare function templateMatches(value: string, pattern: TemplateLiteralType): boolean;
1375
+ /** Do these two types share any value? The compatibility test behind
1376
+ * discriminant filtering and `narrowTo`. */
1377
+ declare function overlaps(a: Type, b: Type): boolean;
1378
+ declare function formatType(t: Type): string;
1379
+
1380
+ interface TypeDiagnostic {
1381
+ /** Usually an expression or statement; a type where the type is wrong
1382
+ * (`declare class A extends NotAClass`), or a block where nothing in it
1383
+ * is to blame (a function that never returns). Only its span is read. */
1384
+ node: Expression | Statement | TypeNode | Block | ClassMember;
1385
+ message: string;
1386
+ }
1387
+ interface TypeAnalysis {
1388
+ /** Inferred type of every expression node. */
1389
+ readonly typeOf: Map<Expression, Type>;
1390
+ /** Declared (or first-inferred) type of every value binding. */
1391
+ readonly bindingType: Map<BindingId, Type>;
1392
+ /** Type of a specific variable *reference*, after flow narrowing at that
1393
+ * point. For an un-narrowed reference this equals `bindingType`. */
1394
+ readonly narrowedTypeOf: Map<Identifier, Type>;
1395
+ /** What every type annotation node resolves to — `number`, `Shape`,
1396
+ * `typeof x`, a property's type inside `{ ... }`. Inside a generic alias or
1397
+ * function its parameters stay unresolved (`T`). */
1398
+ readonly typeOfTypeNode: Map<TypeNode | TypePackNode, Type>;
1399
+ /** What each call argument is expected to be: the parameter it lands on,
1400
+ * with the signature's type parameters replaced by their constraints — a
1401
+ * union when an overload set disagrees. Recorded even for a call that does
1402
+ * not type-check, since that is exactly when an editor wants to offer the
1403
+ * values that would. */
1404
+ readonly expectedTypeOf: Map<Expression, Type>;
1405
+ /** Top-level type aliases, resolved — and the type names this module
1406
+ * imports, so tooling treats both alike. */
1407
+ readonly aliases: Map<string, Type>;
1408
+ readonly diagnostics: TypeDiagnostic[];
1409
+ }
1410
+ /** A type a module exports: the resolved type, plus the parameter names of a
1411
+ * generic alias so an importer can instantiate it (`Box<number>`). */
1412
+ interface ExportedType {
1413
+ readonly type: Type;
1414
+ readonly params: readonly string[];
1415
+ }
1416
+ /** What a module makes available to `import`. See `moduleExports`. */
1417
+ interface ModuleExports {
1418
+ /** `export const` / `export let` / `export function` names. */
1419
+ readonly values: ReadonlyMap<string, Type>;
1420
+ /** `export type` names. */
1421
+ readonly types: ReadonlyMap<string, ExportedType>;
1422
+ /** `export default <expr>`. */
1423
+ readonly default?: Type;
1424
+ /** The module is still being analyzed further up an import cycle. Its
1425
+ * names read as `any`, and nothing about them is reported. */
1426
+ readonly partial?: boolean;
1427
+ }
1428
+ interface AnalyzeTypesOptions {
1429
+ /** Types for pre-registered globals (`analyzeScopes`'s `builtinGlobals`).
1430
+ * Anything not listed is treated as `any`. Overrides `libs`. */
1431
+ globalTypes?: Record<string, Type>;
1432
+ /** Extra named types available to annotations (e.g. Roblox classes). */
1433
+ libTypes?: Record<string, Type>;
1434
+ /** Parsed definitions files (`.d.tilua`): their `type` aliases become
1435
+ * available to annotations and their `declare` statements seed global
1436
+ * types. A project lists them under `types` in `tilua.config.json`; see
1437
+ * `resolveTypeLibraries`. */
1438
+ libs?: readonly Program[];
1439
+ /** Resolve an `import`'s module path to what that module exports. Called
1440
+ * once per distinct path. Return `undefined` when there is no such module:
1441
+ * the import is reported and its names are `any`. Without this option
1442
+ * every import is `any` — a single file cannot know better. */
1443
+ resolveModule?: (specifier: string) => ModuleExports | undefined;
1444
+ /** Emit assignability diagnostics (default: true). */
1445
+ diagnostics?: boolean;
1446
+ /** Report each type name nothing declares: "Cannot find name 'Nope'".
1447
+ * Only meaningful when `libs` holds everything the file can name, so it
1448
+ * is off unless asked for — exactly like `analyzeScopes`'s
1449
+ * `reportUndeclared`. */
1450
+ reportUnknownTypes?: boolean;
1451
+ }
1452
+ declare function analyzeTypes(program: Program, scopes: ScopeAnalysis, options?: AnalyzeTypesOptions): TypeAnalysis;
1453
+ /** The exports of an analyzed module, in the shape another module's
1454
+ * `resolveModule` returns. */
1455
+ declare function moduleExports(program: Program, scopes: ScopeAnalysis, types: TypeAnalysis,
1456
+ /** For `export ... from`: the same resolver the module was analyzed with. */
1457
+ resolveModule?: (specifier: string) => ModuleExports | undefined): ModuleExports;
1458
+
1459
+ /**
1460
+ * The types that belong to the language itself, available in every file with
1461
+ * or without a type library — as TypeScript's `Partial` and `ReturnType` are.
1462
+ *
1463
+ * They are written in tilua on top of `keyof`, `T[K]`, conditional types with
1464
+ * `infer`, mapped types and set difference; the analyzer knows none of these
1465
+ * names. A type library or the file itself may declare one of them again, and
1466
+ * that declaration wins.
1467
+ *
1468
+ * What a runtime provides — `print`, `string`, `game` — is not here: that is a
1469
+ * type library's job (`@tilua-types/lua`, `@tilua-types/roblox`).
1470
+ *
1471
+ * The methods an array and a string answer to — `names:filter(f)`,
1472
+ * `text:trim()` — are a library's too. `propertyType` reads them from types
1473
+ * named `ArrayMethods<T>` and `StringMethods`, whichever library declares
1474
+ * those; the library also says which of them the compiler must emit code for
1475
+ * (`tilua.methods` in its package.json). Nothing about `filter` is written
1476
+ * into the analyzer.
1477
+ */
1478
+ 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 (...unknown) => infer R ? R : never\ntype Parameters<T> = T extends (...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";
1479
+
1480
+ interface ProjectHost {
1481
+ /** A file's text, or `undefined` when there is no such file. */
1482
+ readFile(path: string): string | undefined;
1483
+ }
1484
+ declare const nodeHost: ProjectHost;
1485
+
1486
+ declare const CONFIG_FILE_NAMES: readonly ["tilua.config.json", "tilua.config.jsonc"];
1487
+ interface TiluaConfig {
1488
+ /** Absolute path of the config file. */
1489
+ readonly path: string;
1490
+ /** The folder it sits in. Relative paths in it resolve from here. */
1491
+ readonly directory: string;
1492
+ /** The config file's text, for locating problems in it. */
1493
+ readonly source: string;
1494
+ /** Type libraries to load, in order: `"lua"`, `"@tilua-types/roblox"`, `"./types"`. */
1495
+ readonly types: readonly string[];
1496
+ /** Import path aliases, as in tsconfig: `{ "@shared/*": ["src/shared/*"] }`. */
1497
+ readonly paths: Readonly<Record<string, readonly string[]>>;
1498
+ /** Where `paths` targets resolve from, absolute. The config's folder unless set. */
1499
+ readonly baseUrl: string;
1500
+ /** Absolute path of a Rojo sourcemap, or `null` for none. */
1501
+ readonly sourceMap: string | null;
1502
+ /** Which Lua the compiler must emit for. `"luau"` (the default) keeps
1503
+ * Luau's own syntax; `"lua51"` also lowers what stock Lua 5.1 has no
1504
+ * syntax for. The parser does not care — it is the compiler's to act on,
1505
+ * and lives here because it belongs to the project. */
1506
+ readonly target: BuildTarget;
1507
+ }
1508
+ /** `"luau"` is Roblox's Lua. `"lua51"` is stock Lua 5.1. */
1509
+ type BuildTarget = "luau" | "lua51";
1510
+ interface ConfigProblem {
1511
+ /** The file the problem is about: a config file, or a sourcemap it names. */
1512
+ readonly file: string;
1513
+ readonly message: string;
1514
+ /** 1-based position in `file`, when the problem has one. */
1515
+ readonly line?: number;
1516
+ readonly column?: number;
1517
+ }
1518
+ interface ConfigLookup {
1519
+ /** The config that applies, if one was found and could be read. */
1520
+ readonly config?: TiluaConfig;
1521
+ readonly problems: readonly ConfigProblem[];
1522
+ /** Every config path looked at on the way up, found or not — what a cache
1523
+ * must watch, so that creating or deleting a config is noticed. */
1524
+ readonly searched: readonly string[];
1525
+ }
1526
+ /** The config that applies to `file`: the nearest one in its folder or above. */
1527
+ declare function findConfig(file: string, host?: ProjectHost): ConfigLookup;
1528
+ /** Read and check one config file. Problems do not stop the rest of it from
1529
+ * applying: an unknown option is reported and the known ones still work. */
1530
+ declare function loadConfig(path: string, host?: ProjectHost): {
1531
+ config?: TiluaConfig;
1532
+ problems: ConfigProblem[];
1533
+ };
1534
+ /** Blank out `//` and `/* *\/` comments and trailing commas, keeping every
1535
+ * other character where it was — so a JSON error's position still points
1536
+ * into the original text. */
1537
+ declare function stripJsonComments(text: string): string;
1538
+
1539
+ interface TypeLibraries {
1540
+ /** Definitions files, dependencies before what depends on them. */
1541
+ readonly files: readonly string[];
1542
+ /** Lowering modules the libraries ship, in the same order. */
1543
+ readonly lowerings: readonly LoweringModule[];
1544
+ readonly problems: readonly ConfigProblem[];
1545
+ }
1546
+ /** A library's own lowering: JavaScript the compiler loads and asks what a
1547
+ * call written against this library's types should become.
1548
+ *
1549
+ * The library declares the *types* in its definitions file; this is the other
1550
+ * half. `names:filter(f)` is a call to a function only because `@tilua-types/lua`
1551
+ * says so and ships the Luau behind it — the compiler knows how to ask, and
1552
+ * nothing about `filter`.
1553
+ *
1554
+ * `tilua.lowering` in the package.json names the module; what it must export
1555
+ * is the compiler's business (see @tilua/compiler's `LoweringPlugin`). */
1556
+ interface LoweringModule {
1557
+ /** The JavaScript module to load. */
1558
+ readonly file: string;
1559
+ /** The package it came from, for reporting. */
1560
+ readonly from: string;
1561
+ }
1562
+ declare function resolveTypeLibraries(config: TiluaConfig, host?: ProjectHost): TypeLibraries;
1563
+
1564
+ /**
1565
+ * The contract between a type library and the compiler.
1566
+ *
1567
+ * A library's definitions file says what a value *is*; when what it gives is
1568
+ * not something the value already answers to, the library must also say how
1569
+ * it runs. `names:filter(f)` is a call to a function because `@tilua-types/lua`
1570
+ * declares the method and ships the Luau behind it — the compiler lowers the
1571
+ * language (`import`, `export`, `?.`, `a ? b : c`, destructuring, spreads)
1572
+ * and asks a library about everything else.
1573
+ *
1574
+ * These types are declarations only: nothing here runs, and the parser never
1575
+ * loads a lowering module. They live here so a library can be checked against
1576
+ * the same contract the compiler implements, without depending on the
1577
+ * compiler — in TypeScript, or by JSDoc in the JavaScript it ships:
1578
+ *
1579
+ * // lowering.mjs, in a type library
1580
+ * // @ts-check
1581
+ * /** @type {import("@tilua/parser").LoweringPlugin} *\/
1582
+ * const plugin = {
1583
+ * runtime: { array: "local __NAME__ = {}\n..." },
1584
+ * methodCall({ method, receiver, use }) {
1585
+ * if (receiver?.kind === "array" && method === "filter") {
1586
+ * return { callee: `${use("array")}.filter` }
1587
+ * }
1588
+ * return undefined
1589
+ * },
1590
+ * }
1591
+ * export default plugin
1592
+ */
1593
+
1594
+ interface LoweringPlugin {
1595
+ /** Luau the plugin needs in the output, by a key it chooses. Each is a
1596
+ * file's worth of source with `__NAME__` standing for the local the
1597
+ * compiler gives it, and each is emitted once, at the top of the output,
1598
+ * only if `use` asked for it:
1599
+ *
1600
+ * local __NAME__ = {}
1601
+ * function __NAME__.filter(t, test) ... end
1602
+ */
1603
+ readonly runtime?: Readonly<Record<string, string>>;
1604
+ /** What `receiver:method(...)` becomes. `undefined` leaves a plain Luau
1605
+ * method call, which is what a value that answers to the method itself
1606
+ * wants — `text:upper()` reaches Lua's own. */
1607
+ methodCall?(call: MethodCall): MethodLowering | undefined;
1608
+ }
1609
+ interface MethodCall {
1610
+ /** The name written after `:`. */
1611
+ readonly method: string;
1612
+ /** The receiver's type, as the analyzer worked it out. `undefined` when
1613
+ * nothing typed it, where a plugin should decline rather than guess. */
1614
+ readonly receiver: Type | undefined;
1615
+ /** How many arguments were written. */
1616
+ readonly argumentCount: number;
1617
+ /** The local name the output gives one of `runtime`'s entries, emitting
1618
+ * it if this is the first call that needed it. */
1619
+ use(runtime: string): string;
1620
+ }
1621
+ interface MethodLowering {
1622
+ /** What to call instead: a name, or a `table.member` path — usually built
1623
+ * from `use(...)`. */
1624
+ readonly callee: string;
1625
+ /** Pass the receiver as the first argument. Default: yes. */
1626
+ readonly passReceiver?: boolean;
1627
+ }
1628
+
1629
+ /** Every file `specifier` could mean from `fromFile`, in the order they are
1630
+ * tried. A resolver that caches should watch all of them: creating an earlier
1631
+ * candidate changes what the import means. */
1632
+ declare function moduleCandidates(fromFile: string, specifier: string, config?: TiluaConfig): string[];
1633
+ /** The file `specifier` names from `fromFile`, if it exists. */
1634
+ declare function resolveModulePath(fromFile: string, specifier: string, config?: TiluaConfig, host?: ProjectHost): string | undefined;
1635
+
1636
+ interface SourceMapNode {
1637
+ name: string;
1638
+ className: string;
1639
+ filePaths?: string[];
1640
+ children?: SourceMapNode[];
1641
+ }
1642
+ interface SourceMapOptions {
1643
+ /** The type names the loaded libraries define. An instance of a class not
1644
+ * among them is typed as `Instance`. */
1645
+ readonly classes: ReadonlySet<string>;
1646
+ /** A class's own member names. A child whose name a member already takes
1647
+ * is left out — Roblox resolves the member first. Defaults to the members
1648
+ * every instance has. */
1649
+ readonly membersOf?: (className: string) => ReadonlySet<string>;
1650
+ }
1651
+ interface SourceMapTypes {
1652
+ /** The tree's classes, and `game` / `workspace` for a place. */
1653
+ readonly program: Program;
1654
+ /** `declare script: ...` for a file the tree maps, or `undefined`. */
1655
+ scriptFor(file: string): Program | undefined;
1656
+ }
1657
+ declare function sourceMapTypes(text: string, path: string, options: SourceMapOptions): {
1658
+ types?: SourceMapTypes;
1659
+ problem?: string;
1660
+ };
1661
+
1662
+ declare const tilua: {
1663
+ readonly tokenize: typeof tokenize;
1664
+ readonly parseTokens: typeof parseTokens;
1665
+ readonly parse: typeof parse;
1666
+ readonly parseExpressionFromSource: typeof parseExpressionFromSource;
1667
+ readonly parseWithRecovery: typeof parseWithRecovery;
1668
+ readonly analyzeScopes: typeof analyzeScopes;
1669
+ readonly getBinding: typeof getBinding;
1670
+ readonly isGlobal: typeof isGlobal;
1671
+ readonly isUnassignedGlobal: typeof isUnassignedGlobal;
1672
+ readonly analyzeTypes: typeof analyzeTypes;
1673
+ };
1674
+
1675
+ 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 };