luaut-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.
- package/README.md +129 -0
- package/dist/index.cjs +5582 -0
- package/dist/index.d.cts +1102 -0
- package/dist/index.d.ts +1102 -0
- package/dist/index.js +5489 -0
- package/dist/luau.d.luaut +244 -0
- package/dist/roblox.d.luaut +503 -0
- package/package.json +40 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1102 @@
|
|
|
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
|
+
}
|
|
58
|
+
interface InterpolatedStringToken extends BaseToken {
|
|
59
|
+
type: "InterpolatedString";
|
|
60
|
+
parts: (InterpolatedStringPart_String | InterpolatedStringPart_Expression)[];
|
|
61
|
+
}
|
|
62
|
+
interface EOFToken extends BaseToken {
|
|
63
|
+
type: "EOF";
|
|
64
|
+
}
|
|
65
|
+
type Token = KeywordToken | LiteralToken | OperatorToken | PunctuatorToken | IdentifierToken | InterpolatedStringToken | EOFToken;
|
|
66
|
+
declare class LexError extends Error {
|
|
67
|
+
line: number;
|
|
68
|
+
column: number;
|
|
69
|
+
constructor(message: string, line: number, column: number);
|
|
70
|
+
}
|
|
71
|
+
declare function tokenize(source: string): Token[];
|
|
72
|
+
|
|
73
|
+
interface BaseNode {
|
|
74
|
+
line: {
|
|
75
|
+
start: number;
|
|
76
|
+
end: number;
|
|
77
|
+
};
|
|
78
|
+
column: {
|
|
79
|
+
start: number;
|
|
80
|
+
end: number;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
interface Program extends BaseNode {
|
|
84
|
+
type: "Program";
|
|
85
|
+
body: Block;
|
|
86
|
+
}
|
|
87
|
+
interface Block extends BaseNode {
|
|
88
|
+
type: "Block";
|
|
89
|
+
statements: Statement[];
|
|
90
|
+
}
|
|
91
|
+
interface ImportSpecifier extends BaseNode {
|
|
92
|
+
type: "ImportSpecifier";
|
|
93
|
+
/** the exported name in the source module */
|
|
94
|
+
imported: Identifier;
|
|
95
|
+
/** the local binding name — same as `imported` unless renamed with `as` */
|
|
96
|
+
local: Identifier;
|
|
97
|
+
}
|
|
98
|
+
interface ImportStatement extends BaseNode {
|
|
99
|
+
type: "ImportStatement";
|
|
100
|
+
/** `import Default from '...'` */
|
|
101
|
+
defaultImport?: Identifier;
|
|
102
|
+
/** `import { a, b as c } from '...'` */
|
|
103
|
+
specifiers: ImportSpecifier[];
|
|
104
|
+
source: StringLiteral;
|
|
105
|
+
}
|
|
106
|
+
/** `export const x = 1`, `export let y = 2`, `export const function f() end` */
|
|
107
|
+
interface ExportStatement extends BaseNode {
|
|
108
|
+
type: "ExportStatement";
|
|
109
|
+
declaration: VariableDeclaration | FunctionDeclaration;
|
|
110
|
+
}
|
|
111
|
+
/** `export default <expr>` — mirrors JS default export / dynamic import()'s
|
|
112
|
+
* `{ default: ... }` shape. Distinct from ExportStatement because the
|
|
113
|
+
* right-hand side is any expression, not necessarily a declaration. */
|
|
114
|
+
interface ExportDefaultStatement extends BaseNode {
|
|
115
|
+
type: "ExportDefaultStatement";
|
|
116
|
+
declaration: Expression;
|
|
117
|
+
}
|
|
118
|
+
type Statement = VariableDeclaration | FunctionDeclaration | FunctionDeclarationStatement | AssignmentStatement | CompoundAssignmentStatement | CallStatement | DoStatement | WhileStatement | RepeatStatement | IfStatement | NumericForStatement | GenericForStatement | ReturnStatement | BreakStatement | ContinueStatement | TypeAliasStatement | ExportTypeAliasStatement | ImportStatement | ExportStatement | ExportDefaultStatement | DeclareStatement | ErrorStatement;
|
|
119
|
+
/** `declare game: DataModel` / `declare function require(m: string): unknown`
|
|
120
|
+
* — an ambient value/function declaration for a definitions file (`.d.luaut`).
|
|
121
|
+
* Contributes a global type; emits no runtime code. */
|
|
122
|
+
interface DeclareStatement extends BaseNode {
|
|
123
|
+
type: "DeclareStatement";
|
|
124
|
+
name: string;
|
|
125
|
+
/** the declared value's type (function form is lowered to a FunctionTypeNode) */
|
|
126
|
+
valueType: TypeNode;
|
|
127
|
+
}
|
|
128
|
+
/** A statement position that could not be parsed. Only produced when parsing
|
|
129
|
+
* in recovery mode (`parseWithRecovery`); its span covers the skipped tokens
|
|
130
|
+
* so tools can still map a cursor there. */
|
|
131
|
+
interface ErrorStatement extends BaseNode {
|
|
132
|
+
type: "ErrorStatement";
|
|
133
|
+
}
|
|
134
|
+
/** `const x = 1` / `let x, y = a, b` — the only variable-binding form in luaut
|
|
135
|
+
* (Luau's `local` is gone). `const` bindings are immutable and infer literal
|
|
136
|
+
* types (`const n = 1` → `1`); `let` bindings are mutable and widen. */
|
|
137
|
+
interface VariableDeclaration extends BaseNode {
|
|
138
|
+
type: "VariableDeclaration";
|
|
139
|
+
kind: "const" | "let";
|
|
140
|
+
names: BindingTarget[];
|
|
141
|
+
init: Expression[];
|
|
142
|
+
}
|
|
143
|
+
type BindingTarget = IdentifierPattern | ObjectPattern | ArrayPattern;
|
|
144
|
+
interface IdentifierPattern extends BaseNode {
|
|
145
|
+
type: "IdentifierPattern";
|
|
146
|
+
name: string;
|
|
147
|
+
/** only meaningful at the top level of a binding (`local x: T`, `{a}: T`) */
|
|
148
|
+
typeAnnotation?: TypeNode;
|
|
149
|
+
/** `local x <const>` attribute list */
|
|
150
|
+
attributes?: string[];
|
|
151
|
+
}
|
|
152
|
+
interface ObjectPattern extends BaseNode {
|
|
153
|
+
type: "ObjectPattern";
|
|
154
|
+
properties: ObjectPatternProperty[];
|
|
155
|
+
/** `...rest` — collects the remaining own keys into a new object */
|
|
156
|
+
rest?: BindingTarget;
|
|
157
|
+
typeAnnotation?: TypeNode;
|
|
158
|
+
}
|
|
159
|
+
interface ObjectPatternProperty extends BaseNode {
|
|
160
|
+
type: "ObjectPatternProperty";
|
|
161
|
+
/** identifier/string key, or any expression when `computed` */
|
|
162
|
+
key: Identifier | StringLiteral | Expression;
|
|
163
|
+
computed: boolean;
|
|
164
|
+
/** binding target; for shorthand this is an IdentifierPattern named after `key` */
|
|
165
|
+
value: BindingTarget;
|
|
166
|
+
/** `{ a = 1 }` / `{ a: b = 1 }` default */
|
|
167
|
+
default?: Expression;
|
|
168
|
+
shorthand: boolean;
|
|
169
|
+
}
|
|
170
|
+
interface ArrayPattern extends BaseNode {
|
|
171
|
+
type: "ArrayPattern";
|
|
172
|
+
/** `null` entries are elision holes (`[, a]`) */
|
|
173
|
+
elements: (ArrayPatternElement | null)[];
|
|
174
|
+
/** `...rest` — collects the remaining elements into a new array */
|
|
175
|
+
rest?: BindingTarget;
|
|
176
|
+
typeAnnotation?: TypeNode;
|
|
177
|
+
}
|
|
178
|
+
interface ArrayPatternElement extends BaseNode {
|
|
179
|
+
type: "ArrayPatternElement";
|
|
180
|
+
value: BindingTarget;
|
|
181
|
+
default?: Expression;
|
|
182
|
+
}
|
|
183
|
+
/** `const function f() ... end` / `let function f() ... end` — a named,
|
|
184
|
+
* self-referential (recursive) function binding. */
|
|
185
|
+
interface FunctionDeclaration extends BaseNode {
|
|
186
|
+
type: "FunctionDeclaration";
|
|
187
|
+
kind: "const" | "let";
|
|
188
|
+
name: Identifier;
|
|
189
|
+
func: FunctionBody;
|
|
190
|
+
attributes?: string[];
|
|
191
|
+
/** TS-style overload signatures preceding the implementation (`func`). */
|
|
192
|
+
signatures?: FunctionSignature[];
|
|
193
|
+
}
|
|
194
|
+
interface FunctionDeclarationStatement extends BaseNode {
|
|
195
|
+
type: "FunctionDeclarationStatement";
|
|
196
|
+
target: FunctionName;
|
|
197
|
+
isMethod: boolean;
|
|
198
|
+
func: FunctionBody;
|
|
199
|
+
attributes?: string[];
|
|
200
|
+
/** TS-style overload signatures preceding the implementation (`func`). */
|
|
201
|
+
signatures?: FunctionSignature[];
|
|
202
|
+
}
|
|
203
|
+
/** A bodyless function declaration — an overload signature. luaut uses the
|
|
204
|
+
* exact TS shape: one or more `function f(...): T` lines with no `end`,
|
|
205
|
+
* followed by the implementation `function f(...) ... end`. */
|
|
206
|
+
interface FunctionSignature extends BaseNode {
|
|
207
|
+
type: "FunctionSignature";
|
|
208
|
+
generics: GenericTypeParameter[];
|
|
209
|
+
params: FunctionParameter[];
|
|
210
|
+
hasVarargs: boolean;
|
|
211
|
+
varargTypeAnnotation?: TypeNode;
|
|
212
|
+
returnType?: TypeNode;
|
|
213
|
+
/** `: v is T` / `: asserts v` instead of a plain return type. */
|
|
214
|
+
predicate?: TypePredicateNode;
|
|
215
|
+
}
|
|
216
|
+
interface FunctionName extends BaseNode {
|
|
217
|
+
type: "FunctionName";
|
|
218
|
+
base: Identifier;
|
|
219
|
+
path: Identifier[];
|
|
220
|
+
method?: Identifier;
|
|
221
|
+
}
|
|
222
|
+
interface AssignmentStatement extends BaseNode {
|
|
223
|
+
type: "AssignmentStatement";
|
|
224
|
+
targets: (Expression | ObjectPattern | ArrayPattern)[];
|
|
225
|
+
values: Expression[];
|
|
226
|
+
}
|
|
227
|
+
interface CompoundAssignmentStatement extends BaseNode {
|
|
228
|
+
type: "CompoundAssignmentStatement";
|
|
229
|
+
operator: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "^=" | "..=";
|
|
230
|
+
target: Expression;
|
|
231
|
+
value: Expression;
|
|
232
|
+
}
|
|
233
|
+
interface CallStatement extends BaseNode {
|
|
234
|
+
type: "CallStatement";
|
|
235
|
+
expression: CallExpression | MethodCallExpression;
|
|
236
|
+
}
|
|
237
|
+
interface DoStatement extends BaseNode {
|
|
238
|
+
type: "DoStatement";
|
|
239
|
+
body: Block;
|
|
240
|
+
}
|
|
241
|
+
interface WhileStatement extends BaseNode {
|
|
242
|
+
type: "WhileStatement";
|
|
243
|
+
condition: Expression;
|
|
244
|
+
body: Block;
|
|
245
|
+
}
|
|
246
|
+
interface RepeatStatement extends BaseNode {
|
|
247
|
+
type: "RepeatStatement";
|
|
248
|
+
body: Block;
|
|
249
|
+
condition: Expression;
|
|
250
|
+
}
|
|
251
|
+
interface IfClause extends BaseNode {
|
|
252
|
+
type: "IfClause";
|
|
253
|
+
condition: Expression;
|
|
254
|
+
body: Block;
|
|
255
|
+
}
|
|
256
|
+
interface IfStatement extends BaseNode {
|
|
257
|
+
type: "IfStatement";
|
|
258
|
+
clauses: IfClause[];
|
|
259
|
+
alternate?: Block;
|
|
260
|
+
}
|
|
261
|
+
interface NumericForStatement extends BaseNode {
|
|
262
|
+
type: "NumericForStatement";
|
|
263
|
+
variable: TypedIdentifier;
|
|
264
|
+
start: Expression;
|
|
265
|
+
end: Expression;
|
|
266
|
+
step?: Expression;
|
|
267
|
+
body: Block;
|
|
268
|
+
}
|
|
269
|
+
interface GenericForStatement extends BaseNode {
|
|
270
|
+
type: "GenericForStatement";
|
|
271
|
+
variables: BindingTarget[];
|
|
272
|
+
iterators: Expression[];
|
|
273
|
+
body: Block;
|
|
274
|
+
}
|
|
275
|
+
interface ReturnStatement extends BaseNode {
|
|
276
|
+
type: "ReturnStatement";
|
|
277
|
+
arguments: Expression[];
|
|
278
|
+
}
|
|
279
|
+
interface BreakStatement extends BaseNode {
|
|
280
|
+
type: "BreakStatement";
|
|
281
|
+
}
|
|
282
|
+
interface ContinueStatement extends BaseNode {
|
|
283
|
+
type: "ContinueStatement";
|
|
284
|
+
}
|
|
285
|
+
interface TypeAliasStatement extends BaseNode {
|
|
286
|
+
type: "TypeAliasStatement";
|
|
287
|
+
name: Identifier;
|
|
288
|
+
generics: GenericTypeParameter[];
|
|
289
|
+
definition: TypeNode;
|
|
290
|
+
}
|
|
291
|
+
interface ExportTypeAliasStatement extends BaseNode {
|
|
292
|
+
type: "ExportTypeAliasStatement";
|
|
293
|
+
alias: TypeAliasStatement;
|
|
294
|
+
}
|
|
295
|
+
interface GenericTypeParameter extends BaseNode {
|
|
296
|
+
type: "GenericTypeParameter";
|
|
297
|
+
name: string;
|
|
298
|
+
isPack?: boolean;
|
|
299
|
+
/** `<const T>` — infer the argument at its narrowest instead of widening
|
|
300
|
+
* it: literals stay literal and array literals become tuples. */
|
|
301
|
+
isConst?: boolean;
|
|
302
|
+
/** `<T extends C>` upper bound (TS style). */
|
|
303
|
+
constraint?: TypeNode;
|
|
304
|
+
default?: TypeNode | TypePackNode;
|
|
305
|
+
}
|
|
306
|
+
type Expression = Identifier | NilLiteral | BooleanLiteral | NumberLiteral | StringLiteral | InterpolatedStringExpression | VarargExpression | FunctionExpression | TableExpression | ArrayExpression | BinaryExpression | UnaryExpression | MemberExpression | IndexExpression | CallExpression | MethodCallExpression | ParenthesizedExpression | TypeAssertionExpression | SatisfiesExpression | AsConstExpression | IfElseExpression;
|
|
307
|
+
interface Identifier extends BaseNode {
|
|
308
|
+
type: "Identifier";
|
|
309
|
+
name: string;
|
|
310
|
+
}
|
|
311
|
+
interface TypedIdentifier extends BaseNode {
|
|
312
|
+
type: "TypedIdentifier";
|
|
313
|
+
name: string;
|
|
314
|
+
typeAnnotation?: TypeNode;
|
|
315
|
+
attributes?: string[];
|
|
316
|
+
}
|
|
317
|
+
interface NilLiteral extends BaseNode {
|
|
318
|
+
type: "NilLiteral";
|
|
319
|
+
}
|
|
320
|
+
interface BooleanLiteral extends BaseNode {
|
|
321
|
+
type: "BooleanLiteral";
|
|
322
|
+
value: boolean;
|
|
323
|
+
}
|
|
324
|
+
interface NumberLiteral extends BaseNode {
|
|
325
|
+
type: "NumberLiteral";
|
|
326
|
+
value: number;
|
|
327
|
+
raw: string;
|
|
328
|
+
}
|
|
329
|
+
interface StringLiteral extends BaseNode {
|
|
330
|
+
type: "StringLiteral";
|
|
331
|
+
value: string;
|
|
332
|
+
raw: string;
|
|
333
|
+
}
|
|
334
|
+
type InterpolatedStringPart = {
|
|
335
|
+
kind: "string";
|
|
336
|
+
value: string;
|
|
337
|
+
raw: string;
|
|
338
|
+
} | {
|
|
339
|
+
kind: "expression";
|
|
340
|
+
expression: Expression;
|
|
341
|
+
};
|
|
342
|
+
interface InterpolatedStringExpression extends BaseNode {
|
|
343
|
+
type: "InterpolatedStringExpression";
|
|
344
|
+
parts: InterpolatedStringPart[];
|
|
345
|
+
}
|
|
346
|
+
interface VarargExpression extends BaseNode {
|
|
347
|
+
type: "VarargExpression";
|
|
348
|
+
}
|
|
349
|
+
interface FunctionParameter extends BaseNode {
|
|
350
|
+
type: "FunctionParameter";
|
|
351
|
+
/** `name?: T` — the argument may be omitted, and its type admits `nil`. */
|
|
352
|
+
optional?: boolean;
|
|
353
|
+
/** the parameter name, or `""` when `pattern` is set */
|
|
354
|
+
name: string;
|
|
355
|
+
/** JS-style destructured parameter (`function f({a}, [b]) end`) */
|
|
356
|
+
pattern?: ObjectPattern | ArrayPattern;
|
|
357
|
+
typeAnnotation?: TypeNode;
|
|
358
|
+
/** default value (`function f(a = 1) end`) */
|
|
359
|
+
default?: Expression;
|
|
360
|
+
}
|
|
361
|
+
interface FunctionBody extends BaseNode {
|
|
362
|
+
type: "FunctionBody";
|
|
363
|
+
generics: GenericTypeParameter[];
|
|
364
|
+
params: FunctionParameter[];
|
|
365
|
+
hasVarargs: boolean;
|
|
366
|
+
varargTypeAnnotation?: TypeNode;
|
|
367
|
+
returnType?: TypeNode;
|
|
368
|
+
/** `: v is T` / `: asserts v` instead of a plain return type. */
|
|
369
|
+
predicate?: TypePredicateNode;
|
|
370
|
+
/** Declared as `function T:m(...)`, so `params[0]` is the injected `self`. */
|
|
371
|
+
isMethod?: boolean;
|
|
372
|
+
body: Block;
|
|
373
|
+
}
|
|
374
|
+
interface FunctionExpression extends BaseNode {
|
|
375
|
+
type: "FunctionExpression";
|
|
376
|
+
func: FunctionBody;
|
|
377
|
+
}
|
|
378
|
+
type TableField =
|
|
379
|
+
/** `a: v` or `"a": v` — JS colon syntax (NOT Luau `a = v`). */
|
|
380
|
+
{
|
|
381
|
+
type: "TableFieldNamed";
|
|
382
|
+
key: Identifier | StringLiteral;
|
|
383
|
+
value: Expression;
|
|
384
|
+
}
|
|
385
|
+
/** `[expr]: v` — computed key. */
|
|
386
|
+
| {
|
|
387
|
+
type: "TableFieldComputed";
|
|
388
|
+
key: Expression;
|
|
389
|
+
value: Expression;
|
|
390
|
+
}
|
|
391
|
+
/** `{ a }` shorthand — sugar for `{ a: a }`. */
|
|
392
|
+
| {
|
|
393
|
+
type: "TableFieldShorthand";
|
|
394
|
+
name: Identifier;
|
|
395
|
+
}
|
|
396
|
+
/** `{ ...expr }` — JS object spread. */
|
|
397
|
+
| {
|
|
398
|
+
type: "TableFieldSpread";
|
|
399
|
+
argument: Expression;
|
|
400
|
+
};
|
|
401
|
+
/** `{ a: 1, [k]: v }` — object literal (Luau `{}` narrowed to objects only). */
|
|
402
|
+
interface TableExpression extends BaseNode {
|
|
403
|
+
type: "TableExpression";
|
|
404
|
+
fields: TableField[];
|
|
405
|
+
}
|
|
406
|
+
/** `[1, 2, ...rest]` — array literal. Lowers to a Luau `{1, 2}` sequence table. */
|
|
407
|
+
interface ArrayExpression extends BaseNode {
|
|
408
|
+
type: "ArrayExpression";
|
|
409
|
+
elements: (Expression | SpreadElement)[];
|
|
410
|
+
}
|
|
411
|
+
/** `...expr` inside an array literal. */
|
|
412
|
+
interface SpreadElement extends BaseNode {
|
|
413
|
+
type: "SpreadElement";
|
|
414
|
+
argument: Expression;
|
|
415
|
+
}
|
|
416
|
+
declare const BinaryOperators: readonly ["+", "-", "*", "/", "//", "%", "^", "..", "==", "~=", "<", ">", "<=", ">=", "and", "or"];
|
|
417
|
+
interface BinaryExpression extends BaseNode {
|
|
418
|
+
type: "BinaryExpression";
|
|
419
|
+
operator: typeof BinaryOperators[number];
|
|
420
|
+
left: Expression;
|
|
421
|
+
right: Expression;
|
|
422
|
+
}
|
|
423
|
+
declare const UnaryOperators: readonly ["-", "not", "#"];
|
|
424
|
+
interface UnaryExpression extends BaseNode {
|
|
425
|
+
type: "UnaryExpression";
|
|
426
|
+
operator: typeof UnaryOperators[number];
|
|
427
|
+
argument: Expression;
|
|
428
|
+
}
|
|
429
|
+
interface MemberExpression extends BaseNode {
|
|
430
|
+
type: "MemberExpression";
|
|
431
|
+
object: Expression;
|
|
432
|
+
property: Identifier;
|
|
433
|
+
}
|
|
434
|
+
interface IndexExpression extends BaseNode {
|
|
435
|
+
type: "IndexExpression";
|
|
436
|
+
object: Expression;
|
|
437
|
+
index: Expression;
|
|
438
|
+
}
|
|
439
|
+
interface CallExpression extends BaseNode {
|
|
440
|
+
type: "CallExpression";
|
|
441
|
+
callee: Expression;
|
|
442
|
+
arguments: Expression[];
|
|
443
|
+
}
|
|
444
|
+
interface MethodCallExpression extends BaseNode {
|
|
445
|
+
type: "MethodCallExpression";
|
|
446
|
+
object: Expression;
|
|
447
|
+
method: Identifier;
|
|
448
|
+
arguments: Expression[];
|
|
449
|
+
}
|
|
450
|
+
interface ParenthesizedExpression extends BaseNode {
|
|
451
|
+
type: "ParenthesizedExpression";
|
|
452
|
+
expression: Expression;
|
|
453
|
+
}
|
|
454
|
+
/** `expr satisfies T` — checks that `expr` is assignable to `T` without
|
|
455
|
+
* changing its inferred type, so a literal keeps its narrow type while still
|
|
456
|
+
* being validated against a wider contract. Unlike `as`, it never widens or
|
|
457
|
+
* reinterprets. */
|
|
458
|
+
interface SatisfiesExpression extends BaseNode {
|
|
459
|
+
type: "SatisfiesExpression";
|
|
460
|
+
expression: Expression;
|
|
461
|
+
typeAnnotation: TypeNode;
|
|
462
|
+
}
|
|
463
|
+
interface TypeAssertionExpression extends BaseNode {
|
|
464
|
+
type: "TypeAssertionExpression";
|
|
465
|
+
expression: Expression;
|
|
466
|
+
typeAnnotation: TypeNode;
|
|
467
|
+
}
|
|
468
|
+
/** `expr as const` — freezes the expression's inferred type to its narrowest
|
|
469
|
+
* (literal) form, the way TypeScript's `as const` does. Kept as a distinct
|
|
470
|
+
* node from TypeAssertionExpression because there's no TypeNode on the
|
|
471
|
+
* right-hand side: the type checker computes the literal type itself. */
|
|
472
|
+
interface AsConstExpression extends BaseNode {
|
|
473
|
+
type: "AsConstExpression";
|
|
474
|
+
expression: Expression;
|
|
475
|
+
}
|
|
476
|
+
interface IfElseExpression extends BaseNode {
|
|
477
|
+
type: "IfElseExpression";
|
|
478
|
+
clauses: {
|
|
479
|
+
condition: Expression;
|
|
480
|
+
body: Expression;
|
|
481
|
+
}[];
|
|
482
|
+
alternate: Expression;
|
|
483
|
+
}
|
|
484
|
+
type TypeNode = TypeReference | TypeLiteralString | TypeLiteralBoolean | TypeLiteralNumber | TableTypeNode | ArrayTypeNode | TupleTypeNode | FunctionTypeNode | UnionTypeNode | IntersectionTypeNode | ParenthesizedTypeNode | TypeofTypeNode | VariadicTypeNode | TypePackNode | KeyofTypeNode | IndexedAccessTypeNode | ConditionalTypeNode | InferTypeNode | MappedTypeNode | TemplateLiteralTypeNode | DifferenceTypeNode;
|
|
485
|
+
/** `A - B` — every value of `A` that is not a `B`. Binds tighter than `|`
|
|
486
|
+
* and looser than `&`, so `A | B - C` is `A | (B - C)`.
|
|
487
|
+
*
|
|
488
|
+
* Mostly it simplifies away (a union drops members; `string - "a"` is just
|
|
489
|
+
* `string`), but over an opaque type it is retained — which is what lets the
|
|
490
|
+
* `else` of `if a == 1` on an `unknown` say `unknown - 1` instead of
|
|
491
|
+
* forgetting the test. `Exclude<T, U>` is defined as `T - U`. */
|
|
492
|
+
interface DifferenceTypeNode extends BaseNode {
|
|
493
|
+
type: "DifferenceTypeNode";
|
|
494
|
+
base: TypeNode;
|
|
495
|
+
excluded: TypeNode;
|
|
496
|
+
}
|
|
497
|
+
/** A template literal type: `` `on${string}` ``, `` `get${K}` ``.
|
|
498
|
+
* `quasis` are the literal chunks and `types` the interpolated types;
|
|
499
|
+
* `quasis.length === types.length + 1`, exactly as in an ECMAScript template.
|
|
500
|
+
* When every interpolation is a union of string literals the type reduces to
|
|
501
|
+
* the union of all concatenations; otherwise it stays a pattern that literal
|
|
502
|
+
* strings are matched against. */
|
|
503
|
+
interface TemplateLiteralTypeNode extends BaseNode {
|
|
504
|
+
type: "TemplateLiteralTypeNode";
|
|
505
|
+
quasis: string[];
|
|
506
|
+
types: TypeNode[];
|
|
507
|
+
}
|
|
508
|
+
/** `keyof T` — the union of `T`'s property names as string-literal types,
|
|
509
|
+
* plus its indexer key type when it has one. */
|
|
510
|
+
interface KeyofTypeNode extends BaseNode {
|
|
511
|
+
type: "KeyofTypeNode";
|
|
512
|
+
target: TypeNode;
|
|
513
|
+
}
|
|
514
|
+
/** `T[K]` — indexed access. Distinguished from the `T[]` array suffix by
|
|
515
|
+
* whether the brackets are empty. */
|
|
516
|
+
interface IndexedAccessTypeNode extends BaseNode {
|
|
517
|
+
type: "IndexedAccessTypeNode";
|
|
518
|
+
objectType: TypeNode;
|
|
519
|
+
indexType: TypeNode;
|
|
520
|
+
}
|
|
521
|
+
/** `C extends E ? A : B`. Distributes over a naked type parameter, as in
|
|
522
|
+
* TypeScript, which is what makes `Exclude<T, U>` filter a union. */
|
|
523
|
+
interface ConditionalTypeNode extends BaseNode {
|
|
524
|
+
type: "ConditionalTypeNode";
|
|
525
|
+
checkType: TypeNode;
|
|
526
|
+
extendsType: TypeNode;
|
|
527
|
+
trueType: TypeNode;
|
|
528
|
+
falseType: TypeNode;
|
|
529
|
+
}
|
|
530
|
+
/** `infer U`, only meaningful inside a conditional's `extends` clause: it
|
|
531
|
+
* binds `U` to whatever matched at that position. */
|
|
532
|
+
interface InferTypeNode extends BaseNode {
|
|
533
|
+
type: "InferTypeNode";
|
|
534
|
+
name: string;
|
|
535
|
+
}
|
|
536
|
+
/** `{ [K in C]: V }` — a mapped type. `optional` / `readonly` carry the
|
|
537
|
+
* modifier as written: `true` adds it (`?`), `false` removes it (`-?`),
|
|
538
|
+
* `undefined` leaves the source property's modifier alone. */
|
|
539
|
+
interface MappedTypeNode extends BaseNode {
|
|
540
|
+
type: "MappedTypeNode";
|
|
541
|
+
/** The name bound to each key in turn (`K`). */
|
|
542
|
+
parameter: string;
|
|
543
|
+
/** The union of keys to map over (`C`). */
|
|
544
|
+
constraint: TypeNode;
|
|
545
|
+
/** `[K in C as R]` — remaps each key through `R`. */
|
|
546
|
+
nameType?: TypeNode;
|
|
547
|
+
/** The property type, which may mention `parameter`. */
|
|
548
|
+
template: TypeNode;
|
|
549
|
+
optional?: boolean;
|
|
550
|
+
readonly?: boolean;
|
|
551
|
+
}
|
|
552
|
+
/** The return position of a TypeScript-style type guard:
|
|
553
|
+
* `function isStr(v: unknown): v is string`, `function check(v): asserts v`,
|
|
554
|
+
* or `function assertStr(v): asserts v is string`.
|
|
555
|
+
*
|
|
556
|
+
* Deliberately *not* a member of `TypeNode` — it may only appear as a
|
|
557
|
+
* function's return annotation, and keeping it out of the union means every
|
|
558
|
+
* existing `TypeNode` consumer stays exhaustive without change. A function
|
|
559
|
+
* carrying one returns `boolean` (`is`) or nothing (`asserts`). */
|
|
560
|
+
interface TypePredicateNode extends BaseNode {
|
|
561
|
+
type: "TypePredicateNode";
|
|
562
|
+
/** Name of the parameter this guard talks about. */
|
|
563
|
+
parameterName: string;
|
|
564
|
+
/** `asserts x` — narrows the rest of the enclosing block, not a branch. */
|
|
565
|
+
asserts: boolean;
|
|
566
|
+
/** Absent for a bare `asserts x` (a truthiness assertion). */
|
|
567
|
+
typeAnnotation?: TypeNode;
|
|
568
|
+
}
|
|
569
|
+
interface TypePackNode extends BaseNode {
|
|
570
|
+
type: "TypePackNode";
|
|
571
|
+
types: TypeNode[];
|
|
572
|
+
hasVarargs: boolean;
|
|
573
|
+
varargType?: TypeNode;
|
|
574
|
+
}
|
|
575
|
+
interface TypeReference extends BaseNode {
|
|
576
|
+
type: "TypeReference";
|
|
577
|
+
base: string;
|
|
578
|
+
namespace?: string;
|
|
579
|
+
typeArguments: (TypeNode | TypePackNode)[];
|
|
580
|
+
}
|
|
581
|
+
interface TypeLiteralString extends BaseNode {
|
|
582
|
+
type: "TypeLiteralString";
|
|
583
|
+
value: string;
|
|
584
|
+
}
|
|
585
|
+
interface TypeLiteralBoolean extends BaseNode {
|
|
586
|
+
type: "TypeLiteralBoolean";
|
|
587
|
+
value: boolean;
|
|
588
|
+
}
|
|
589
|
+
/** `1`, `3.5` — a single-valued number type. The checker already produces
|
|
590
|
+
* these when narrowing (`if n == 1`), so they have to be writable too. */
|
|
591
|
+
interface TypeLiteralNumber extends BaseNode {
|
|
592
|
+
type: "TypeLiteralNumber";
|
|
593
|
+
value: number;
|
|
594
|
+
}
|
|
595
|
+
type TableTypeProperty = {
|
|
596
|
+
type: "TableTypeIndexer";
|
|
597
|
+
keyType: TypeNode;
|
|
598
|
+
valueType: TypeNode;
|
|
599
|
+
}
|
|
600
|
+
/** `name: T` (required) or `name?: T` (optional — TS style, the property
|
|
601
|
+
* may be absent). `optional` reflects the `?` after the name only;
|
|
602
|
+
* `name: T | nil` is a required property whose value may be nil. */
|
|
603
|
+
| {
|
|
604
|
+
type: "TableTypeProperty";
|
|
605
|
+
name: string;
|
|
606
|
+
valueType: TypeNode;
|
|
607
|
+
optional: boolean;
|
|
608
|
+
readonly?: boolean;
|
|
609
|
+
};
|
|
610
|
+
interface TableTypeNode extends BaseNode {
|
|
611
|
+
type: "TableTypeNode";
|
|
612
|
+
properties: TableTypeProperty[];
|
|
613
|
+
}
|
|
614
|
+
/** `T[]` — array type. Replaces Luau's `{T}` array-table notation. */
|
|
615
|
+
interface ArrayTypeNode extends BaseNode {
|
|
616
|
+
type: "ArrayTypeNode";
|
|
617
|
+
element: TypeNode;
|
|
618
|
+
}
|
|
619
|
+
/** `[number, string]` — fixed-length tuple type. */
|
|
620
|
+
interface TupleTypeNode extends BaseNode {
|
|
621
|
+
type: "TupleTypeNode";
|
|
622
|
+
elements: TypeNode[];
|
|
623
|
+
}
|
|
624
|
+
interface FunctionTypeParameter extends BaseNode {
|
|
625
|
+
type: "FunctionTypeParameter";
|
|
626
|
+
/** `name?: T` — the argument may be omitted, and its type admits `nil`. */
|
|
627
|
+
optional?: boolean;
|
|
628
|
+
name?: string;
|
|
629
|
+
typeAnnotation: TypeNode;
|
|
630
|
+
}
|
|
631
|
+
interface FunctionTypeNode extends BaseNode {
|
|
632
|
+
type: "FunctionTypeNode";
|
|
633
|
+
generics: GenericTypeParameter[];
|
|
634
|
+
params: FunctionTypeParameter[];
|
|
635
|
+
hasVarargs: boolean;
|
|
636
|
+
varargType?: TypeNode;
|
|
637
|
+
returnType: TypeNode;
|
|
638
|
+
/** `(v: unknown) -> v is string` — a guard written as a function *type*. */
|
|
639
|
+
predicate?: TypePredicateNode;
|
|
640
|
+
}
|
|
641
|
+
interface UnionTypeNode extends BaseNode {
|
|
642
|
+
type: "UnionTypeNode";
|
|
643
|
+
types: TypeNode[];
|
|
644
|
+
}
|
|
645
|
+
interface IntersectionTypeNode extends BaseNode {
|
|
646
|
+
type: "IntersectionTypeNode";
|
|
647
|
+
types: TypeNode[];
|
|
648
|
+
}
|
|
649
|
+
interface ParenthesizedTypeNode extends BaseNode {
|
|
650
|
+
type: "ParenthesizedTypeNode";
|
|
651
|
+
typeAnnotation: TypeNode;
|
|
652
|
+
}
|
|
653
|
+
interface TypeofTypeNode extends BaseNode {
|
|
654
|
+
type: "TypeofTypeNode";
|
|
655
|
+
expression: Expression;
|
|
656
|
+
}
|
|
657
|
+
interface VariadicTypeNode extends BaseNode {
|
|
658
|
+
type: "VariadicTypeNode";
|
|
659
|
+
typeAnnotation: TypeNode;
|
|
660
|
+
}
|
|
661
|
+
type Node = Program | Block | Statement | Expression | TypeNode | FunctionBody | FunctionParameter | FunctionName | IfClause | TypedIdentifier | GenericTypeParameter | FunctionSignature | TypePredicateNode | TableField | SpreadElement | FunctionTypeParameter | TableTypeProperty | BindingTarget | ObjectPatternProperty | ArrayPatternElement;
|
|
662
|
+
|
|
663
|
+
declare class ParseError extends Error {
|
|
664
|
+
line: number;
|
|
665
|
+
column: number;
|
|
666
|
+
constructor(message: string, line: number, column: number);
|
|
667
|
+
}
|
|
668
|
+
interface ParserOptions {
|
|
669
|
+
/** When true, `parseProgram` records syntax errors in `.errors` and
|
|
670
|
+
* synchronizes to the next statement boundary instead of throwing on the
|
|
671
|
+
* first one. The returned AST has an `ErrorStatement` wherever a statement
|
|
672
|
+
* could not be parsed. */
|
|
673
|
+
recover?: boolean;
|
|
674
|
+
}
|
|
675
|
+
declare function parse(source: string): Program;
|
|
676
|
+
declare function parseTokens(tokens: Token[]): Program;
|
|
677
|
+
declare function parseExpressionFromSource(raw: string): Expression;
|
|
678
|
+
interface RecoverResult {
|
|
679
|
+
program: Program;
|
|
680
|
+
errors: ParseError[];
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Like `parse`, but never throws on a syntax error: it records every error,
|
|
684
|
+
* synchronizes to the next statement boundary, and returns a best-effort AST
|
|
685
|
+
* (with `ErrorStatement` nodes where statements were skipped). A lexer error
|
|
686
|
+
* still can't produce a partial token stream, so it comes back as the sole
|
|
687
|
+
* entry in `errors` alongside an empty program.
|
|
688
|
+
*
|
|
689
|
+
* This is the entry point a language server should use for open documents.
|
|
690
|
+
*/
|
|
691
|
+
declare function parseWithRecovery(source: string): RecoverResult;
|
|
692
|
+
|
|
693
|
+
type BindingId = number;
|
|
694
|
+
type BindingKind = "local" | "param" | "self" | "for-numeric" | "for-generic" | "global";
|
|
695
|
+
/** A node that can serve as a binding's "declared here" site. */
|
|
696
|
+
type DeclarationNode = Identifier | TypedIdentifier | FunctionParameter | IdentifierPattern;
|
|
697
|
+
interface Binding {
|
|
698
|
+
readonly id: BindingId;
|
|
699
|
+
/** Name at the point this binding was created. Rename passes update
|
|
700
|
+
* this and every node in `references` (+ `declarationNode`) together —
|
|
701
|
+
* this field is just what analysis saw, not a source of truth after a
|
|
702
|
+
* rename pass has run. */
|
|
703
|
+
name: string;
|
|
704
|
+
readonly kind: BindingKind;
|
|
705
|
+
/** Absent for a `global` binding that was never assigned to in this
|
|
706
|
+
* file (e.g. only ever read, or a pre-registered builtin). */
|
|
707
|
+
declarationNode?: DeclarationNode;
|
|
708
|
+
/** Every Identifier *usage* resolved to this binding (does not include
|
|
709
|
+
* `declarationNode` itself). */
|
|
710
|
+
readonly references: Identifier[];
|
|
711
|
+
/** True for globals pre-registered via `analyzeScopes`'s
|
|
712
|
+
* `builtinGlobals` option (e.g. `game`, `script`, `print`). Such
|
|
713
|
+
* bindings are never given a `declarationNode` from assignment
|
|
714
|
+
* inference, since they're not really "defined" in this file. */
|
|
715
|
+
isBuiltin?: boolean;
|
|
716
|
+
/** True for a `const` binding — reassigning it is an error. */
|
|
717
|
+
isConst?: boolean;
|
|
718
|
+
}
|
|
719
|
+
interface ScopeDiagnostic {
|
|
720
|
+
/** the offending node (redeclaration site, or assignment target) */
|
|
721
|
+
node: {
|
|
722
|
+
line: {
|
|
723
|
+
start: number;
|
|
724
|
+
end: number;
|
|
725
|
+
};
|
|
726
|
+
column: {
|
|
727
|
+
start: number;
|
|
728
|
+
end: number;
|
|
729
|
+
};
|
|
730
|
+
};
|
|
731
|
+
message: string;
|
|
732
|
+
kind: "redeclare" | "const-assign";
|
|
733
|
+
}
|
|
734
|
+
interface ScopeAnalysis {
|
|
735
|
+
/** Every Identifier that appears in a variable *usage* position (i.e.
|
|
736
|
+
* every node also reachable through some `Binding.references`, plus
|
|
737
|
+
* `FunctionDeclarationStatement.target.base`), mapped to its binding.
|
|
738
|
+
* Property names, method names, table field names, and type-position
|
|
739
|
+
* identifiers are never entered here — they aren't variable refs. */
|
|
740
|
+
readonly bindingOf: Map<Identifier | IdentifierPattern, BindingId>;
|
|
741
|
+
readonly bindings: Map<BindingId, Binding>;
|
|
742
|
+
/** Redeclaration-in-same-scope and assignment-to-const errors. */
|
|
743
|
+
readonly diagnostics: ScopeDiagnostic[];
|
|
744
|
+
/** Convenience: every global binding's id, keyed by name. Global
|
|
745
|
+
* bindings have no lexical scope, so this is the closest thing to
|
|
746
|
+
* "the" scope for them — and later a multi-file language server can
|
|
747
|
+
* swap this map out for a project-wide registry without changing
|
|
748
|
+
* anything else about this shape. */
|
|
749
|
+
readonly globalsByName: Map<string, BindingId>;
|
|
750
|
+
}
|
|
751
|
+
interface AnalyzeScopesOptions {
|
|
752
|
+
/** Names to pre-register as global bindings with `isBuiltin: true`
|
|
753
|
+
* before the walk starts (e.g. Roblox/Luau standard globals:
|
|
754
|
+
* `game`, `script`, `workspace`, `print`, `pairs`, ...). Referencing
|
|
755
|
+
* one of these does not count as "defining" it, so `declarationNode`
|
|
756
|
+
* is left unset even though the binding exists up front. */
|
|
757
|
+
builtinGlobals?: readonly string[];
|
|
758
|
+
}
|
|
759
|
+
declare function getBinding(analysis: ScopeAnalysis, id: Identifier | IdentifierPattern): Binding | undefined;
|
|
760
|
+
declare function isGlobal(binding: Binding): boolean;
|
|
761
|
+
/** True if a global binding was never assigned to anywhere in this file
|
|
762
|
+
* (and isn't a pre-registered builtin) — i.e. it's read-only and
|
|
763
|
+
* undeclared, which is almost always a typo rather than an intentional
|
|
764
|
+
* implicit global. Handy for a "possibly undefined global" diagnostic. */
|
|
765
|
+
declare function isUnassignedGlobal(binding: Binding): boolean;
|
|
766
|
+
declare function analyzeScopes(program: Program, options?: AnalyzeScopesOptions): ScopeAnalysis;
|
|
767
|
+
|
|
768
|
+
type Type = AnyType | UnknownType | NeverType | PrimitiveType | LiteralType | ArrayType | TupleType | ObjectType | FunctionType | UnionType | IntersectionType | TypeParamType | GenericRefType | KeyofType | IndexedAccessType | ConditionalType | InferType | MappedType | TemplateLiteralType | DifferenceType;
|
|
769
|
+
/** `any` — opts out of checking. Assignable to and from everything. */
|
|
770
|
+
interface AnyType {
|
|
771
|
+
kind: "any";
|
|
772
|
+
}
|
|
773
|
+
/** `unknown` — top type. Everything is assignable to it; it is assignable to nothing but itself. */
|
|
774
|
+
interface UnknownType {
|
|
775
|
+
kind: "unknown";
|
|
776
|
+
}
|
|
777
|
+
/** `never` — bottom type. Assignable to everything; nothing (but never) is assignable to it. */
|
|
778
|
+
interface NeverType {
|
|
779
|
+
kind: "never";
|
|
780
|
+
}
|
|
781
|
+
type PrimitiveName = "nil" | "boolean" | "number" | "string" | "thread" | "buffer";
|
|
782
|
+
interface PrimitiveType {
|
|
783
|
+
kind: "primitive";
|
|
784
|
+
name: PrimitiveName;
|
|
785
|
+
}
|
|
786
|
+
/** `"foo"`, `42`, `true` — a single-valued type. `base` is the primitive it widens to. */
|
|
787
|
+
interface LiteralType {
|
|
788
|
+
kind: "literal";
|
|
789
|
+
base: "boolean" | "number" | "string";
|
|
790
|
+
value: string | number | boolean;
|
|
791
|
+
}
|
|
792
|
+
/** `T[]` */
|
|
793
|
+
interface ArrayType {
|
|
794
|
+
kind: "array";
|
|
795
|
+
element: Type;
|
|
796
|
+
}
|
|
797
|
+
/** `[A, B, C]` — fixed length.
|
|
798
|
+
*
|
|
799
|
+
* `isPack` marks the other thing this shape is used for: a *type pack*, the
|
|
800
|
+
* several values a Lua function returns (`(number, string)`). The two are
|
|
801
|
+
* structurally identical but behave differently in an expression list — a
|
|
802
|
+
* pack spreads across several names, a tuple is one value — so they have to
|
|
803
|
+
* be told apart. */
|
|
804
|
+
interface TupleType {
|
|
805
|
+
kind: "tuple";
|
|
806
|
+
elements: Type[];
|
|
807
|
+
isPack?: boolean;
|
|
808
|
+
}
|
|
809
|
+
interface ObjectProperty {
|
|
810
|
+
type: Type;
|
|
811
|
+
optional: boolean;
|
|
812
|
+
readonly?: boolean;
|
|
813
|
+
}
|
|
814
|
+
interface ObjectType {
|
|
815
|
+
kind: "object";
|
|
816
|
+
properties: Map<string, ObjectProperty>;
|
|
817
|
+
/** `{ [K]: V }` catch-all, if present. */
|
|
818
|
+
indexer?: {
|
|
819
|
+
key: Type;
|
|
820
|
+
value: Type;
|
|
821
|
+
};
|
|
822
|
+
/** `object` was produced by `as const` — literal members are kept narrow
|
|
823
|
+
* and every property is `readonly`. */
|
|
824
|
+
frozen?: boolean;
|
|
825
|
+
/** The alias this object was resolved from — display only, ignored by
|
|
826
|
+
* `isAssignable` (the type is structural). Dropped on `widen`/`substitute`. */
|
|
827
|
+
name?: string;
|
|
828
|
+
}
|
|
829
|
+
interface FunctionParam {
|
|
830
|
+
name?: string;
|
|
831
|
+
type: Type;
|
|
832
|
+
optional?: boolean;
|
|
833
|
+
}
|
|
834
|
+
/** A TS-style type guard: `function f(v: unknown): v is string` narrows `v` at
|
|
835
|
+
* every call site used as a condition. `asserts` variants narrow the *rest of
|
|
836
|
+
* the enclosing block* instead of a branch (`assert(x)`), and a missing `type`
|
|
837
|
+
* means a bare truthiness assertion (`asserts v`). */
|
|
838
|
+
interface TypePredicate {
|
|
839
|
+
/** Index into `params` of the parameter this guard talks about. */
|
|
840
|
+
param: number;
|
|
841
|
+
/** The type the parameter is narrowed to; absent = narrow to truthy. */
|
|
842
|
+
type?: Type;
|
|
843
|
+
asserts: boolean;
|
|
844
|
+
}
|
|
845
|
+
interface FunctionType {
|
|
846
|
+
kind: "function";
|
|
847
|
+
params: FunctionParam[];
|
|
848
|
+
varargs?: Type;
|
|
849
|
+
/** A tuple when the function returns multiple values. */
|
|
850
|
+
returns: Type;
|
|
851
|
+
/** Names of the function's own generic parameters (`function f<T>(...)`).
|
|
852
|
+
* `params` / `returns` may contain `typeParam` nodes for these. */
|
|
853
|
+
typeParams?: string[];
|
|
854
|
+
/** Set when the function was declared with an `x is T` / `asserts x` return. */
|
|
855
|
+
predicate?: TypePredicate;
|
|
856
|
+
}
|
|
857
|
+
/** A bound generic parameter (`T` inside `function f<T>(...)` or
|
|
858
|
+
* `type Box<T> = ...`). Resolved away by `substitute` at instantiation.
|
|
859
|
+
* `constraint` is the `<T extends C>` upper bound, used for member access on a
|
|
860
|
+
* bare `T` and as the fallback when `T` can't be inferred. */
|
|
861
|
+
interface TypeParamType {
|
|
862
|
+
kind: "typeParam";
|
|
863
|
+
name: string;
|
|
864
|
+
constraint?: Type;
|
|
865
|
+
/** Declared `<const T>`: the call site infers the argument at its
|
|
866
|
+
* narrowest rather than widening it. */
|
|
867
|
+
isConst?: boolean;
|
|
868
|
+
}
|
|
869
|
+
declare function typeParam(name: string, constraint?: Type, isConst?: boolean): TypeParamType;
|
|
870
|
+
interface UnionType {
|
|
871
|
+
kind: "union";
|
|
872
|
+
types: Type[];
|
|
873
|
+
}
|
|
874
|
+
interface IntersectionType {
|
|
875
|
+
kind: "intersection";
|
|
876
|
+
types: Type[];
|
|
877
|
+
/** The alias this was resolved from — display only, exactly like
|
|
878
|
+
* `ObjectType.name`. A class hierarchy written as `type Part = BasePart &
|
|
879
|
+
* { ... }` is unreadable without it. */
|
|
880
|
+
name?: string;
|
|
881
|
+
}
|
|
882
|
+
/** An unresolved reference: an in-scope generic parameter, or a named type
|
|
883
|
+
* that couldn't be resolved to an alias in this pass. */
|
|
884
|
+
interface GenericRefType {
|
|
885
|
+
kind: "genericRef";
|
|
886
|
+
name: string;
|
|
887
|
+
typeArguments: Type[];
|
|
888
|
+
}
|
|
889
|
+
/** `keyof T`. */
|
|
890
|
+
interface KeyofType {
|
|
891
|
+
kind: "keyof";
|
|
892
|
+
target: Type;
|
|
893
|
+
}
|
|
894
|
+
/** `T[K]`. */
|
|
895
|
+
interface IndexedAccessType {
|
|
896
|
+
kind: "indexedAccess";
|
|
897
|
+
objectType: Type;
|
|
898
|
+
indexType: Type;
|
|
899
|
+
}
|
|
900
|
+
/** `C extends E ? A : B`. */
|
|
901
|
+
interface ConditionalType {
|
|
902
|
+
kind: "conditional";
|
|
903
|
+
checkType: Type;
|
|
904
|
+
extendsType: Type;
|
|
905
|
+
trueType: Type;
|
|
906
|
+
falseType: Type;
|
|
907
|
+
/** Names bound by `infer` inside `extendsType`. */
|
|
908
|
+
inferVars: string[];
|
|
909
|
+
/** Set when `checkType` is a *naked* type parameter, to that parameter's
|
|
910
|
+
* name. Such a conditional distributes over a union, and inside each
|
|
911
|
+
* branch the parameter denotes the single member being tested — the
|
|
912
|
+
* property `Exclude<T, U>` relies on. */
|
|
913
|
+
distributeParam?: string;
|
|
914
|
+
}
|
|
915
|
+
/** `infer U`, valid only inside a conditional's `extends` clause. */
|
|
916
|
+
interface InferType {
|
|
917
|
+
kind: "infer";
|
|
918
|
+
name: string;
|
|
919
|
+
}
|
|
920
|
+
/** `A - B` — every value of `A` that is not a `B`.
|
|
921
|
+
*
|
|
922
|
+
* Only kept when `A` is *opaque*: `unknown`, or a type parameter or nominal
|
|
923
|
+
* reference not yet resolved. For a union the subtraction is performed by
|
|
924
|
+
* dropping members, and for a concrete type such as `string` it is discarded
|
|
925
|
+
* (`string - "a"` supports exactly the same operations as `string`, and
|
|
926
|
+
* TypeScript likewise does not track it). For `unknown`, though, the
|
|
927
|
+
* subtraction is the *only* thing known about the value, so throwing it away
|
|
928
|
+
* loses the whole result of the test:
|
|
929
|
+
*
|
|
930
|
+
* let a: unknown
|
|
931
|
+
* if a == 1 then -- a: 1
|
|
932
|
+
* else -- a: unknown - 1
|
|
933
|
+
* end
|
|
934
|
+
*/
|
|
935
|
+
interface DifferenceType {
|
|
936
|
+
kind: "difference";
|
|
937
|
+
base: Type;
|
|
938
|
+
excluded: Type;
|
|
939
|
+
}
|
|
940
|
+
/** `` `on${string}` `` — literal chunks interleaved with interpolated types
|
|
941
|
+
* (`quasis.length === types.length + 1`). Reduced to a union of string
|
|
942
|
+
* literals when every interpolation is one; otherwise it stays a *pattern*
|
|
943
|
+
* and `isAssignable` matches literal strings against it. */
|
|
944
|
+
interface TemplateLiteralType {
|
|
945
|
+
kind: "templateLiteral";
|
|
946
|
+
quasis: string[];
|
|
947
|
+
types: Type[];
|
|
948
|
+
}
|
|
949
|
+
/** `{ [K in C]: V }`. `optional` / `readonly`: `true` adds the modifier,
|
|
950
|
+
* `false` strips it, `undefined` inherits it from the source property. */
|
|
951
|
+
interface MappedType {
|
|
952
|
+
kind: "mapped";
|
|
953
|
+
parameter: string;
|
|
954
|
+
constraint: Type;
|
|
955
|
+
nameType?: Type;
|
|
956
|
+
template: Type;
|
|
957
|
+
optional?: boolean;
|
|
958
|
+
readonly?: boolean;
|
|
959
|
+
/** The `T` of `[K in keyof T]`, kept so a homomorphic mapped type can carry
|
|
960
|
+
* each source property's own `?` / `readonly` across. */
|
|
961
|
+
source?: Type;
|
|
962
|
+
}
|
|
963
|
+
declare const anyType: AnyType;
|
|
964
|
+
declare const unknownType: UnknownType;
|
|
965
|
+
declare const neverType: NeverType;
|
|
966
|
+
declare const nilType: PrimitiveType;
|
|
967
|
+
declare const booleanType: PrimitiveType;
|
|
968
|
+
declare const numberType: PrimitiveType;
|
|
969
|
+
declare const stringType: PrimitiveType;
|
|
970
|
+
declare const threadType: PrimitiveType;
|
|
971
|
+
declare const bufferType: PrimitiveType;
|
|
972
|
+
declare function primitive(name: PrimitiveName): PrimitiveType;
|
|
973
|
+
declare function literal(value: string | number | boolean): LiteralType;
|
|
974
|
+
declare function arrayOf(element: Type): ArrayType;
|
|
975
|
+
declare function tuple(elements: Type[], isPack?: boolean): TupleType;
|
|
976
|
+
declare function objectType(entries: Iterable<[string, ObjectProperty]>, indexer?: ObjectType["indexer"], frozen?: boolean): ObjectType;
|
|
977
|
+
declare function fn(params: FunctionParam[], returns: Type, varargs?: Type, typeParams?: string[], predicate?: TypePredicate): FunctionType;
|
|
978
|
+
declare function substitute(t: Type, subst: Map<string, Type>): Type;
|
|
979
|
+
/** Infer generic bindings by structurally matching a (possibly generic)
|
|
980
|
+
* `param` type against a concrete `arg` type. Accumulates into `out`. */
|
|
981
|
+
declare function unify(param: Type, arg: Type, vars: Set<string>, out: Map<string, Type>): void;
|
|
982
|
+
declare function union(types: Type[]): Type;
|
|
983
|
+
declare function intersection(types: Type[]): Type;
|
|
984
|
+
/** `base - excluded`, simplified as far as the base allows. */
|
|
985
|
+
declare function difference(base: Type, excluded: Type): Type;
|
|
986
|
+
/** `T | nil` — the type of an optional property or parameter. */
|
|
987
|
+
declare function optional(t: Type): Type;
|
|
988
|
+
/** Widens literal types to their primitive base (the default for a plain
|
|
989
|
+
* `local x = "foo"` binding, unless `as const` says otherwise). Recurses
|
|
990
|
+
* into arrays/tuples/objects/unions. */
|
|
991
|
+
declare function widen(t: Type): Type;
|
|
992
|
+
declare function setAliasExpander(fn: ((t: GenericRefType) => Type) | undefined): void;
|
|
993
|
+
declare function isAssignable(rawA: Type, rawB: Type): boolean;
|
|
994
|
+
declare function equalTypes(a: Type, b: Type): boolean;
|
|
995
|
+
/** Keep the parts of `t` compatible with `filter` — TypeScript's
|
|
996
|
+
* `getNarrowedType`. Per union member: a member already assignable to the
|
|
997
|
+
* filter survives as-is; a member the filter is assignable to is *replaced*
|
|
998
|
+
* by the filter (so `string` narrowed by `"a"` becomes `"a"`, not `string`);
|
|
999
|
+
* anything else is dropped. `any` / `unknown` narrow straight to the filter. */
|
|
1000
|
+
declare function narrowTo(t: Type, filter: Type): Type;
|
|
1001
|
+
/** Remove the parts of `t` assignable to `exclude` (the `else` branch).
|
|
1002
|
+
* `boolean` minus a `true`/`false` literal leaves the other literal — the
|
|
1003
|
+
* only primitive here with a finite, enumerable domain. */
|
|
1004
|
+
declare function narrowExclude(t: Type, exclude: Type): Type;
|
|
1005
|
+
/** `nil | false` — every falsy value in Luau. Built literally rather than via
|
|
1006
|
+
* `union()`, which would format its members for deduping and so touch caches
|
|
1007
|
+
* declared further down this module. */
|
|
1008
|
+
declare const falsyType: Type;
|
|
1009
|
+
/** Can a value of this type ever be truthy? */
|
|
1010
|
+
declare function isPossiblyTruthy(t: Type): boolean;
|
|
1011
|
+
/** Can a value of this type ever be falsy? */
|
|
1012
|
+
declare function isPossiblyFalsy(t: Type): boolean;
|
|
1013
|
+
/** Keep only what can be truthy — drops `nil` and the `false` literal, and
|
|
1014
|
+
* narrows a bare `boolean` to `true`. */
|
|
1015
|
+
declare function narrowTruthy(t: Type): Type;
|
|
1016
|
+
/** Keep only what can be falsy — `nil` and `false`. */
|
|
1017
|
+
declare function narrowFalsy(t: Type): Type;
|
|
1018
|
+
declare function containsTypeParam(t: Type, seen?: Set<Type>, bound?: Set<string>): boolean;
|
|
1019
|
+
/** Structurally match `arg` against `pattern`, binding every `infer` name it
|
|
1020
|
+
* contains into `out`. This is what turns `T extends (...unknown) -> infer R`
|
|
1021
|
+
* into `R = <the return type>`. Returns false when the shapes cannot match at
|
|
1022
|
+
* all; a `true` result still needs the usual assignability check. */
|
|
1023
|
+
declare function matchInfer(arg: Type, pattern: Type, out: Map<string, Type>): boolean;
|
|
1024
|
+
/** Does a concrete string match a template literal *pattern*? Each
|
|
1025
|
+
* interpolation is matched against the widest thing it could stand for:
|
|
1026
|
+
* `string` swallows any run, `number` a numeric run, and a literal union only
|
|
1027
|
+
* its own members. Anchored at both ends, like TypeScript. */
|
|
1028
|
+
declare function templateMatches(value: string, pattern: TemplateLiteralType): boolean;
|
|
1029
|
+
/** Do these two types share any value? The compatibility test behind
|
|
1030
|
+
* discriminant filtering and `narrowTo`. */
|
|
1031
|
+
declare function overlaps(a: Type, b: Type): boolean;
|
|
1032
|
+
declare function formatType(t: Type): string;
|
|
1033
|
+
|
|
1034
|
+
interface TypeDiagnostic {
|
|
1035
|
+
node: Expression | Statement;
|
|
1036
|
+
message: string;
|
|
1037
|
+
}
|
|
1038
|
+
interface TypeAnalysis {
|
|
1039
|
+
/** Inferred type of every expression node. */
|
|
1040
|
+
readonly typeOf: Map<Expression, Type>;
|
|
1041
|
+
/** Declared (or first-inferred) type of every value binding. */
|
|
1042
|
+
readonly bindingType: Map<BindingId, Type>;
|
|
1043
|
+
/** Type of a specific variable *reference*, after flow narrowing at that
|
|
1044
|
+
* point. For an un-narrowed reference this equals `bindingType`. */
|
|
1045
|
+
readonly narrowedTypeOf: Map<Identifier, Type>;
|
|
1046
|
+
/** Top-level type aliases, resolved. */
|
|
1047
|
+
readonly aliases: Map<string, Type>;
|
|
1048
|
+
readonly diagnostics: TypeDiagnostic[];
|
|
1049
|
+
}
|
|
1050
|
+
interface AnalyzeTypesOptions {
|
|
1051
|
+
/** Types for pre-registered globals (`analyzeScopes`'s `builtinGlobals`).
|
|
1052
|
+
* Anything not listed is treated as `any`. Overrides `libs`. */
|
|
1053
|
+
globalTypes?: Record<string, Type>;
|
|
1054
|
+
/** Extra named types available to annotations (e.g. Roblox classes). */
|
|
1055
|
+
libTypes?: Record<string, Type>;
|
|
1056
|
+
/** Parsed definitions files (`.d.luaut`): their `type` aliases become
|
|
1057
|
+
* available to annotations and their `declare` statements seed global
|
|
1058
|
+
* types. See `robloxLib`. */
|
|
1059
|
+
libs?: readonly Program[];
|
|
1060
|
+
/** Emit assignability diagnostics (default: true). */
|
|
1061
|
+
diagnostics?: boolean;
|
|
1062
|
+
}
|
|
1063
|
+
declare function analyzeTypes(program: Program, scopes: ScopeAnalysis, options?: AnalyzeTypesOptions): TypeAnalysis;
|
|
1064
|
+
|
|
1065
|
+
/** Absolute path to the shipped `luau.d.luaut`. */
|
|
1066
|
+
declare const luauDefsPath: string;
|
|
1067
|
+
/** Raw source of the core definitions. */
|
|
1068
|
+
declare const luauDefs: string;
|
|
1069
|
+
/** Parsed core Luau definitions. */
|
|
1070
|
+
declare const luauLib: Program;
|
|
1071
|
+
|
|
1072
|
+
/** Absolute path to the shipped `roblox.d.luaut`. */
|
|
1073
|
+
declare const robloxDefsPath: string;
|
|
1074
|
+
/** Raw source of the baseline definitions. */
|
|
1075
|
+
declare const robloxDefs: string;
|
|
1076
|
+
/** Parsed baseline definitions — pass as `analyzeTypes(..., { libs: [robloxLib] })`. */
|
|
1077
|
+
declare const robloxLib: Program;
|
|
1078
|
+
|
|
1079
|
+
/** Core Luau plus the Roblox baseline, in the order `analyzeTypes` expects.
|
|
1080
|
+
*
|
|
1081
|
+
* The analyzer has no built-in knowledge of `type` / `typeof` — they are
|
|
1082
|
+
* ordinary overload sets declared in these files, and narrowing is derived
|
|
1083
|
+
* from them. Pass this (or your own list) or those built-ins narrow nothing:
|
|
1084
|
+
*
|
|
1085
|
+
* analyzeTypes(program, scopes, { libs: defaultLibs })
|
|
1086
|
+
*/
|
|
1087
|
+
declare const defaultLibs: readonly Program[];
|
|
1088
|
+
|
|
1089
|
+
declare const luautparser: {
|
|
1090
|
+
readonly tokenize: typeof tokenize;
|
|
1091
|
+
readonly parseTokens: typeof parseTokens;
|
|
1092
|
+
readonly parse: typeof parse;
|
|
1093
|
+
readonly parseExpressionFromSource: typeof parseExpressionFromSource;
|
|
1094
|
+
readonly parseWithRecovery: typeof parseWithRecovery;
|
|
1095
|
+
readonly analyzeScopes: typeof analyzeScopes;
|
|
1096
|
+
readonly getBinding: typeof getBinding;
|
|
1097
|
+
readonly isGlobal: typeof isGlobal;
|
|
1098
|
+
readonly isUnassignedGlobal: typeof isUnassignedGlobal;
|
|
1099
|
+
readonly analyzeTypes: typeof analyzeTypes;
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
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 CallExpression, type CallStatement, type CompoundAssignmentStatement, type ConditionalType, type ConditionalTypeNode, type ContinueStatement, type DeclareStatement, type DifferenceType, type DifferenceTypeNode, type DoStatement, type EOFToken, type ErrorStatement, type ExportDefaultStatement, type ExportStatement, type ExportTypeAliasStatement, type Expression, 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 MappedType, type MappedTypeNode, type MemberExpression, type MethodCallExpression, type NeverType, type NilLiteral, type Node, type NumberLiteral, type NumericForStatement, type ObjectPattern, type ObjectPatternProperty, type ObjectProperty, type ObjectType, type OperatorToken, Operators, type ParenthesizedExpression, type ParenthesizedTypeNode, ParseError, type ParserOptions, type PrimitiveName, type PrimitiveType, type Program, type PunctuatorToken, Punctuators, type RecoverResult, type RepeatStatement, type ReturnStatement, type SatisfiesExpression, type ScopeAnalysis, type ScopeDiagnostic, type SpreadElement, type Statement, type StringLiteral, type TableExpression, type TableField, type TableTypeNode, type TableTypeProperty, type TemplateLiteralType, type TemplateLiteralTypeNode, type Token, type TupleType, type TupleTypeNode, type Type, type TypeAliasStatement, type TypeAnalysis, type TypeAssertionExpression, type TypeDiagnostic, type TypeLiteralBoolean, type TypeLiteralNumber, type TypeLiteralString, type TypeNode, type TypePackNode, type TypeParamType, type TypePredicate, type TypePredicateNode, type TypeReference, type TypedIdentifier, type TypeofTypeNode, type UnaryExpression, UnaryOperators, type UnionType, type UnionTypeNode, type UnknownType, type VarargExpression, type VariableDeclaration, type VariadicTypeNode, type WhileStatement, analyzeScopes, analyzeTypes, anyType, arrayOf, booleanType, bufferType, containsTypeParam, luautparser as default, defaultLibs, difference, equalTypes, falsyType, fn, formatType, getBinding, intersection, isAssignable, isGlobal, isPossiblyFalsy, isPossiblyTruthy, isUnassignedGlobal, literal, luauDefs, luauDefsPath, luauLib, luautparser, matchInfer, narrowExclude, narrowFalsy, narrowTo, narrowTruthy, neverType, nilType, numberType, objectType, optional, overlaps, parse, parseExpressionFromSource, parseTokens, parseWithRecovery, primitive, robloxDefs, robloxDefsPath, robloxLib, setAliasExpander, stringType, substitute, templateMatches, threadType, tokenize, tuple, typeParam, unify, union, unknownType, widen };
|