Skip to content

Commit 4464228

Browse files
committed
AST Node TypeGuards
1 parent 34b6151 commit 4464228

File tree

1 file changed

+138
-13
lines changed

1 file changed

+138
-13
lines changed

src/LuaAST.ts

Lines changed: 138 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export enum SyntaxKind {
1717
RepeatStatement,
1818
ForStatement,
1919
ForInStatement,
20-
FunctionStatement,
2120
GotoStatement,
2221
LabelStatement,
2322
ReturnStatement,
2423
BreakStatement,
24+
ExpressionStatement,
2525
// Expression
2626
StringLiteral,
2727
NumericLiteral,
@@ -96,6 +96,8 @@ export type BinaryOperator =
9696
SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator |
9797
SyntaxKind.BitwiseLeftShiftOperator | SyntaxKind.BitwiseNotOperator;
9898

99+
export type Operator = UnaryOperator | BinaryOperator;
100+
99101
// TODO For future sourcemap support?
100102
export interface TextRange {
101103
pos: number;
@@ -143,6 +145,10 @@ export interface Block extends Node {
143145
statements?: Statement[];
144146
}
145147

148+
export function isBlock(node: Node): node is Block {
149+
return node.kind === SyntaxKind.Block;
150+
}
151+
146152
export function createBlock(statements?: Statement[], parent?: Node, tsOriginal?: ts.Node): Block {
147153
const block = createNode(SyntaxKind.Block, parent, tsOriginal) as Block;
148154
setParent(statements, block);
@@ -159,6 +165,10 @@ export interface DoStatement extends Statement {
159165
statements?: Statement[];
160166
}
161167

168+
export function isDoStatement(node: Node): node is DoStatement {
169+
return node.kind === SyntaxKind.DoStatement;
170+
}
171+
162172
export function createDoStatement(statements?: Statement[], parent?: Node, tsOriginal?: ts.Node): DoStatement {
163173
const statement = createNode(SyntaxKind.Block, parent, tsOriginal) as DoStatement;
164174
setParent(statements, statement);
@@ -173,6 +183,10 @@ export interface VariableDeclarationStatement extends Statement {
173183
right?: Expression[];
174184
}
175185

186+
export function isVariableDeclarationStatement(node: Node): node is VariableDeclarationStatement {
187+
return node.kind === SyntaxKind.VariableDeclarationStatement;
188+
}
189+
176190
export function createVariableDeclarationStatement(
177191
left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[],
178192
right?: Expression | Expression[],
@@ -203,6 +217,10 @@ export interface VariableAssignmentStatement extends Statement {
203217
right: Expression[];
204218
}
205219

220+
export function isVariableAssignmentStatement(node: Node): node is VariableAssignmentStatement {
221+
return node.kind === SyntaxKind.VariableAssignmentStatement;
222+
}
223+
206224
export function createVariableAssignmentStatement(
207225
left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[],
208226
right: Expression | Expression[],
@@ -233,6 +251,10 @@ export interface IfStatement extends Statement {
233251
elseBlock?: Block | IfStatement;
234252
}
235253

254+
export function isIfStatement(node: Node): node is IfStatement {
255+
return node.kind === SyntaxKind.IfStatement;
256+
}
257+
236258
export function createIfStatement(
237259
condtion: Expression,
238260
ifBlock: Block,
@@ -254,35 +276,50 @@ export interface IterationStatement extends Statement {
254276
body: Block;
255277
}
256278

279+
export function isIterationStatement(node: Node): node is WhileStatement {
280+
return node.kind === SyntaxKind.WhileStatement ||
281+
node.kind === SyntaxKind.RepeatStatement ||
282+
node.kind === SyntaxKind.ForStatement ||
283+
node.kind === SyntaxKind.ForInStatement;
284+
}
285+
257286
export interface WhileStatement extends IterationStatement {
258287
kind: SyntaxKind.WhileStatement;
259-
expression: Expression;
288+
condtion: Expression;
289+
}
290+
291+
export function isWhileStatement(node: Node): node is WhileStatement {
292+
return node.kind === SyntaxKind.WhileStatement;
260293
}
261294

262295
export function createWhileStatement(
263-
body: Block, expression: Expression, parent?: Node, tsOriginal?: ts.Node): WhileStatement {
296+
body: Block, condtion: Expression, parent?: Node, tsOriginal?: ts.Node): WhileStatement {
264297

265298
const statement = createNode(SyntaxKind.WhileStatement, parent, tsOriginal) as WhileStatement;
266299
setParent(body, statement);
267300
statement.body = body;
268-
setParent(expression, statement);
269-
statement.expression = expression;
301+
setParent(condtion, statement);
302+
statement.condtion = condtion;
270303
return statement;
271304
}
272305

273306
export interface RepeatStatement extends IterationStatement {
274307
kind: SyntaxKind.RepeatStatement;
275-
expression: Expression;
308+
condtion: Expression;
309+
}
310+
311+
export function isRepeatStatement(node: Node): node is RepeatStatement {
312+
return node.kind === SyntaxKind.RepeatStatement;
276313
}
277314

278315
export function createRepeatStatement(
279-
body: Block, expression: Expression, parent?: Node, tsOriginal?: ts.Node): RepeatStatement {
316+
body: Block, condtion: Expression, parent?: Node, tsOriginal?: ts.Node): RepeatStatement {
280317

281318
const statement = createNode(SyntaxKind.RepeatStatement, parent, tsOriginal) as RepeatStatement;
282319
setParent(body, statement);
283320
statement.body = body;
284-
setParent(expression, statement);
285-
statement.expression = expression;
321+
setParent(condtion, statement);
322+
statement.condtion = condtion;
286323
return statement;
287324
}
288325

@@ -295,6 +332,10 @@ export interface ForStatement extends IterationStatement {
295332
stepExpression?: Expression;
296333
}
297334

335+
export function isForStatement(node: Node): node is ForStatement {
336+
return node.kind === SyntaxKind.ForStatement;
337+
}
338+
298339
export function createForStatement(
299340
body: Block,
300341
controlVariable: Identifier,
@@ -324,6 +365,10 @@ export interface ForInStatement extends IterationStatement {
324365
expressions: Expression[];
325366
}
326367

368+
export function isForInStatement(node: Node): node is ForInStatement {
369+
return node.kind === SyntaxKind.ForInStatement;
370+
}
371+
327372
export function createForInStatement(
328373
body: Block,
329374
names: Identifier[],
@@ -346,6 +391,10 @@ export interface GotoStatement extends Statement {
346391
label: string; // or identifier ?
347392
}
348393

394+
export function isGotoStatement(node: Node): node is GotoStatement {
395+
return node.kind === SyntaxKind.GotoStatement;
396+
}
397+
349398
export function createGotoStatement(label: string, parent?: Node, tsOriginal?: ts.Node): GotoStatement {
350399
const statement = createNode(SyntaxKind.GotoStatement, parent, tsOriginal) as GotoStatement;
351400
statement.label = label;
@@ -357,6 +406,10 @@ export interface LabelStatement extends Statement {
357406
name: string; // or identifier ?
358407
}
359408

409+
export function isLabelStatement(node: Node): node is LabelStatement {
410+
return node.kind === SyntaxKind.LabelStatement;
411+
}
412+
360413
export function createLabelStatement(name: string, parent?: Node, tsOriginal?: ts.Node): LabelStatement {
361414
const statement = createNode(SyntaxKind.LabelStatement, parent, tsOriginal) as LabelStatement;
362415
statement.name = name;
@@ -368,6 +421,10 @@ export interface ReturnStatement extends Statement {
368421
expressions?: Expression[];
369422
}
370423

424+
export function isReturnStatement(node: Node): node is ReturnStatement {
425+
return node.kind === SyntaxKind.ReturnStatement;
426+
}
427+
371428
export function createReturnStatement(
372429
expressions?: Expression[], parent?: Node, tsOriginal?: ts.Node): ReturnStatement {
373430

@@ -381,19 +438,27 @@ export interface BreakStatement extends Statement {
381438
kind: SyntaxKind.BreakStatement;
382439
}
383440

441+
export function isBreakStatement(node: Node): node is BreakStatement {
442+
return node.kind === SyntaxKind.BreakStatement;
443+
}
444+
384445
export function createBreakStatement(parent?: Node, tsOriginal?: ts.Node): BreakStatement {
385446
return createNode(SyntaxKind.BreakStatement, parent, tsOriginal) as BreakStatement;
386447
}
387448

388-
// TODO used for export function calls, or shoudl export function calls inherit from both expression and statement?
389449
export interface ExpressionStatement extends Statement {
450+
kind: SyntaxKind.ExpressionStatement;
390451
expression: Expression;
391452
}
392453

454+
export function isExpressionStatement(node: Node): node is ExpressionStatement {
455+
return node.kind === SyntaxKind.ExpressionStatement;
456+
}
457+
393458
export function createExpressionStatement(
394459
expressions: Expression, parent?: Node, tsOriginal?: ts.Node): ExpressionStatement {
395460

396-
const statement = createNode(SyntaxKind.ReturnStatement, parent, tsOriginal) as ExpressionStatement;
461+
const statement = createNode(SyntaxKind.ExpressionStatement, parent, tsOriginal) as ExpressionStatement;
397462
setParent(expressions, statement);
398463
statement.expression = expressions;
399464
return statement;
@@ -409,6 +474,10 @@ export interface NilLiteral extends Expression {
409474
kind: SyntaxKind.NilKeyword;
410475
}
411476

477+
export function isNilLiteral(node: Node): node is NilLiteral {
478+
return node.kind === SyntaxKind.NilKeyword;
479+
}
480+
412481
export function createNilLiteral(parent?: Node, tsOriginal?: ts.Node): NilLiteral {
413482
return createNode(SyntaxKind.NilKeyword, parent, tsOriginal) as NilLiteral;
414483
}
@@ -417,6 +486,10 @@ export interface BooleanLiteral extends Expression {
417486
kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword;
418487
}
419488

489+
export function isBooleanLiteral(node: Node): node is BooleanLiteral {
490+
return node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword;
491+
}
492+
420493
export function createBooleanLiteral(value: boolean, parent?: Node, tsOriginal?: ts.Node): BooleanLiteral {
421494
if (value) {
422495
return createNode(SyntaxKind.TrueKeyword, parent, tsOriginal) as BooleanLiteral;
@@ -430,6 +503,10 @@ export interface DotsLiteral extends Expression {
430503
kind: SyntaxKind.DotsKeyword;
431504
}
432505

506+
export function isDotsLiteral(node: Node): node is DotsLiteral {
507+
return node.kind === SyntaxKind.DotsKeyword;
508+
}
509+
433510
export function createDotsLiteral(parent?: Node, tsOriginal?: ts.Node): DotsLiteral {
434511
return createNode(SyntaxKind.DotsKeyword, parent, tsOriginal) as DotsLiteral;
435512
}
@@ -444,6 +521,10 @@ export interface NumericLiteral extends Expression {
444521
value: number;
445522
}
446523

524+
export function isNumericLiteral(node: Node): node is NumericLiteral {
525+
return node.kind === SyntaxKind.NumericLiteral;
526+
}
527+
447528
export function createNumericLiteral(value: number, parent?: Node, tsOriginal?: ts.Node): NumericLiteral {
448529
const expression = createNode(SyntaxKind.NumericLiteral, parent, tsOriginal) as NumericLiteral;
449530
expression.value = value;
@@ -455,6 +536,10 @@ export interface StringLiteral extends Expression {
455536
value: string;
456537
}
457538

539+
export function isStringLiteral(node: Node): node is StringLiteral {
540+
return node.kind === SyntaxKind.StringLiteral;
541+
}
542+
458543
export function createStringLiteral(value: string, parent?: Node, tsOriginal?: ts.Node): StringLiteral {
459544
const expression = createNode(SyntaxKind.StringLiteral, parent, tsOriginal) as StringLiteral;
460545
expression.value = value;
@@ -470,13 +555,17 @@ export function createStringLiteral(value: string, parent?: Node, tsOriginal?: t
470555
//
471556
// We should probably create helper functions to create the different export function declarations
472557
export interface FunctionExpression extends Expression {
473-
kind: SyntaxKind.FunctionStatement;
558+
kind: SyntaxKind.FunctionExpression;
474559
params?: Identifier[];
475560
dots?: DotsLiteral;
476561
restParamName?: Identifier;
477562
body: Block;
478563
}
479564

565+
export function isFunctionExpression(node: Node): node is FunctionExpression {
566+
return node.kind === SyntaxKind.FunctionExpression;
567+
}
568+
480569
export function createFunctionExpression(
481570
body: Block,
482571
params?: Identifier[],
@@ -503,6 +592,10 @@ export interface TableFieldExpression extends Expression {
503592
key?: Expression;
504593
}
505594

595+
export function isTableFieldExpression(node: Node): node is TableFieldExpression {
596+
return node.kind === SyntaxKind.TableFieldExpression;
597+
}
598+
506599
export function createTableFieldExpression(
507600
value: Expression, key?: Expression, parent?: Node, tsOriginal?: ts.Node): TableFieldExpression {
508601

@@ -519,6 +612,10 @@ export interface TableExpression extends Expression {
519612
fields?: TableFieldExpression[];
520613
}
521614

615+
export function isTableExpression(node: Node): node is TableExpression {
616+
return node.kind === SyntaxKind.TableExpression;
617+
}
618+
522619
export function createTableExpression(
523620
fields?: TableFieldExpression[], parent?: Node, tsOriginal?: ts.Node): TableExpression {
524621

@@ -534,6 +631,10 @@ export interface UnaryExpression extends Expression {
534631
operator: UnaryOperator;
535632
}
536633

634+
export function isUnaryExpression(node: Node): node is UnaryExpression {
635+
return node.kind === SyntaxKind.UnaryExpression;
636+
}
637+
537638
export function createUnaryExpression(
538639
operand: Expression, operator: UnaryOperator, parent?: Node, tsOriginal?: ts.Node): UnaryExpression {
539640

@@ -551,6 +652,10 @@ export interface BinaryExpression extends Expression {
551652
right: Expression;
552653
}
553654

655+
export function isBinaryExpression(node: Node): node is BinaryExpression {
656+
return node.kind === SyntaxKind.BinaryExpression;
657+
}
658+
554659
export function createBinaryExpression(
555660
left: Expression,
556661
right: Expression,
@@ -572,6 +677,10 @@ export interface ParenthesizedExpression extends Expression {
572677
innerEpxression: Expression;
573678
}
574679

680+
export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression {
681+
return node.kind === SyntaxKind.ParenthesizedExpression;
682+
}
683+
575684
export function createParenthesizedExpression(
576685
innerExpression: Expression, parent?: Node, tsOriginal?: ts.Node): ParenthesizedExpression {
577686

@@ -588,6 +697,10 @@ export interface CallExpression extends Expression {
588697
params?: Expression[];
589698
}
590699

700+
export function isCallExpression(node: Node): node is CallExpression {
701+
return node.kind === SyntaxKind.CallExpression;
702+
}
703+
591704
export function createCallExpression(
592705
expression: Expression, params?: Expression[], parent?: Node, tsOriginal?: ts.Node): CallExpression {
593706

@@ -606,6 +719,10 @@ export interface MethodCallExpression extends Expression {
606719
params?: Expression[];
607720
}
608721

722+
export function isMethodCallExpression(node: Node): node is MethodCallExpression {
723+
return node.kind === SyntaxKind.MethodCallExpression;
724+
}
725+
609726
export function createMethodCallExpression(
610727
prefixExpression: Expression,
611728
name: Identifier,
@@ -628,6 +745,10 @@ export interface Identifier extends Expression {
628745
text: string;
629746
}
630747

748+
export function isIdentifier(node: Node): node is Identifier {
749+
return node.kind === SyntaxKind.Identifier;
750+
}
751+
631752
export function createIdentifier(text: string, parent?: Node, tsOriginal?: ts.Node): Identifier {
632753
const expression = createNode(SyntaxKind.Identifier, parent, tsOriginal) as Identifier;
633754
expression.text = text;
@@ -641,6 +762,10 @@ export interface TableIndexExpression extends Expression {
641762
// TODO maybe add soemthing to handle dot vs [] access
642763
}
643764

765+
export function isTableIndexExpression(node: Node): node is TableIndexExpression {
766+
return node.kind === SyntaxKind.TableIndexExpression;
767+
}
768+
644769
export function createTableIndexExpression(
645770
table: Expression, index: Expression, parent?: Node, tsOriginal?: ts.Node): TableIndexExpression {
646771

@@ -652,4 +777,4 @@ export function createTableIndexExpression(
652777
return expression;
653778
}
654779

655-
type IdentifierOrTableIndexExpression = Identifier | TableIndexExpression;
780+
export type IdentifierOrTableIndexExpression = Identifier | TableIndexExpression;

0 commit comments

Comments
 (0)