Skip to content

Commit 86960df

Browse files
committed
Refactor standard transformers to a single plugin
1 parent b71e956 commit 86960df

34 files changed

Lines changed: 315 additions & 435 deletions

src/transformation/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import * as tstl from "../LuaAST";
33
import { LuaLibFeature } from "../LuaLib";
44
import { getOrUpdate } from "../utils";
55
import { ObjectVisitor, TransformationContext, TransformerPlugin, VisitorMap } from "./context";
6-
import { standardPlugins } from "./transformers";
76
import { TranspileError } from "./utils/errors";
87
import { getUsedLuaLibFeatures } from "./utils/lualib";
8+
import { standardPlugin } from "./transformers";
99

1010
export { TransformerPlugin } from "./context";
1111

@@ -21,7 +21,7 @@ const transpileErrorDiagnostic = (error: TranspileError): ts.Diagnostic => ({
2121

2222
export function createVisitorMap(customPlugins: TransformerPlugin[]): VisitorMap {
2323
const visitorMap: VisitorMap = new Map();
24-
for (const plugin of [...standardPlugins, ...customPlugins]) {
24+
for (const plugin of [standardPlugin, ...customPlugins]) {
2525
for (const [syntaxKindKey, visitor] of Object.entries(plugin.visitors)) {
2626
if (!visitor) continue;
2727

src/transformation/transformers/access.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../LuaAST";
33
import { transformBuiltinPropertyAccessExpression } from "../builtins";
4-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../context";
4+
import { FunctionVisitor, TransformationContext } from "../context";
55
import { AnnotationKind, getTypeAnnotations } from "../utils/annotations";
66
import { createExpressionPlusOne } from "../utils/lua-ast";
77
import { isArrayType, isNumberType, isStringType } from "../utils/typescript";
8+
import { tryGetConstEnumValue } from "./enum";
9+
import { transformLuaTableElementAccessExpression, transformLuaTablePropertyAccessExpression } from "./lua-table";
810

911
export function transformElementAccessArgument(
1012
context: TransformationContext,
11-
expression: ts.ElementAccessExpression
13+
node: ts.ElementAccessExpression
1214
): tstl.Expression {
13-
const index = context.transformExpression(expression.argumentExpression);
15+
const index = context.transformExpression(node.argumentExpression);
1416

15-
const type = context.checker.getTypeAtLocation(expression.expression);
16-
const argumentType = context.checker.getTypeAtLocation(expression.argumentExpression);
17+
const type = context.checker.getTypeAtLocation(node.expression);
18+
const argumentType = context.checker.getTypeAtLocation(node.argumentExpression);
1719
if (isNumberType(context, argumentType) && isArrayType(context, type)) {
1820
return createExpressionPlusOne(index);
1921
}
2022

2123
return index;
2224
}
2325

24-
const transformElementAccessExpression: FunctionVisitor<ts.ElementAccessExpression> = (expression, context) => {
26+
export const transformElementAccessExpression: FunctionVisitor<ts.ElementAccessExpression> = (expression, context) => {
27+
transformLuaTableElementAccessExpression(context, expression);
28+
29+
const constEnumValue = tryGetConstEnumValue(context, expression);
30+
if (constEnumValue) {
31+
return constEnumValue;
32+
}
33+
2534
let table = context.transformExpression(expression.expression);
2635
if (tstl.isTableExpression(table)) {
2736
table = tstl.createParenthesizedExpression(table);
@@ -41,7 +50,20 @@ const transformElementAccessExpression: FunctionVisitor<ts.ElementAccessExpressi
4150
return tstl.createTableIndexExpression(table, transformElementAccessArgument(context, expression), expression);
4251
};
4352

44-
const transformPropertyAccessExpression: FunctionVisitor<ts.PropertyAccessExpression> = (expression, context) => {
53+
export const transformPropertyAccessExpression: FunctionVisitor<ts.PropertyAccessExpression> = (
54+
expression,
55+
context
56+
) => {
57+
const constEnumValue = tryGetConstEnumValue(context, expression);
58+
if (constEnumValue) {
59+
return constEnumValue;
60+
}
61+
62+
const luaTableResult = transformLuaTablePropertyAccessExpression(context, expression);
63+
if (luaTableResult) {
64+
return luaTableResult;
65+
}
66+
4567
const builtinResult = transformBuiltinPropertyAccessExpression(context, expression);
4668
if (builtinResult) {
4769
return builtinResult;
@@ -73,17 +95,9 @@ const transformPropertyAccessExpression: FunctionVisitor<ts.PropertyAccessExpres
7395
return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression);
7496
};
7597

76-
const transformQualifiedName: FunctionVisitor<ts.QualifiedName> = (node, context) => {
98+
export const transformQualifiedName: FunctionVisitor<ts.QualifiedName> = (node, context) => {
7799
const right = tstl.createStringLiteral(node.right.text, node.right);
78100
const left = context.transformExpression(node.left);
79101

80102
return tstl.createTableIndexExpression(left, right, node);
81103
};
82-
83-
export const accessPlugin: TransformerPlugin = {
84-
visitors: {
85-
[ts.SyntaxKind.PropertyAccessExpression]: transformPropertyAccessExpression,
86-
[ts.SyntaxKind.ElementAccessExpression]: transformElementAccessExpression,
87-
[ts.SyntaxKind.QualifiedName]: transformQualifiedName,
88-
},
89-
};

src/transformation/transformers/binary-expression/index.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../../LuaAST";
3-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../../context";
3+
import { FunctionVisitor, TransformationContext } from "../../context";
44
import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations";
55
import { InvalidInstanceOfExtension, InvalidInstanceOfLuaTable, UnsupportedKind } from "../../utils/errors";
66
import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast";
77
import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib";
88
import { isStandardLibraryType, isStringType } from "../../utils/typescript";
9+
import { transformTypeOfBinaryExpression } from "../typeof";
910
import { transformAssignmentExpression, transformAssignmentStatement } from "./assignments";
1011
import { transformBinaryBitOperation } from "./bit";
1112
import {
@@ -105,7 +106,12 @@ export function transformBinaryOperation(
105106
}
106107
}
107108

108-
const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression> = (node, context) => {
109+
export const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression> = (node, context) => {
110+
const typeOfResult = transformTypeOfBinaryExpression(context, node);
111+
if (typeOfResult) {
112+
return typeOfResult;
113+
}
114+
109115
const operator = node.operatorToken.kind;
110116

111117
// Check if this is an assignment token, then handle accordingly
@@ -204,7 +210,10 @@ const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression> = (node, c
204210
}
205211
};
206212

207-
const transformExpressionStatement: FunctionVisitor<ts.ExpressionStatement> = (node, context) => {
213+
export function transformBinaryExpressionStatement(
214+
context: TransformationContext,
215+
node: ts.ExpressionStatement
216+
): tstl.Statement[] | tstl.Statement | undefined {
208217
const { expression } = node;
209218
if (ts.isBinaryExpression(expression)) {
210219
const operator = expression.operatorToken.kind;
@@ -229,13 +238,4 @@ const transformExpressionStatement: FunctionVisitor<ts.ExpressionStatement> = (n
229238
return tstl.createDoStatement(statements, expression);
230239
}
231240
}
232-
233-
return context.superTransformStatements(node);
234-
};
235-
236-
export const binaryExpressionPlugin: TransformerPlugin = {
237-
visitors: {
238-
[ts.SyntaxKind.BinaryExpression]: transformBinaryExpression,
239-
[ts.SyntaxKind.ExpressionStatement]: { priority: 1, transform: transformExpressionStatement },
240-
},
241-
};
241+
}

src/transformation/transformers/block.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../LuaAST";
3-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../context";
3+
import { FunctionVisitor, TransformationContext } from "../context";
44
import { performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope";
55

66
export function transformBlockOrStatement(context: TransformationContext, statement: ts.Statement): tstl.Statement[] {
@@ -18,15 +18,9 @@ export function transformScopeBlock(
1818
return [tstl.createBlock(statements, node), scope];
1919
}
2020

21-
const transformBlock: FunctionVisitor<ts.Block> = (node, context) => {
21+
export const transformBlock: FunctionVisitor<ts.Block> = (node, context) => {
2222
pushScope(context, ScopeType.Block);
2323
const statements = performHoisting(context, context.transformStatements(node.statements));
2424
popScope(context);
2525
return tstl.createDoStatement(statements, node);
2626
};
27-
28-
export const blockPlugin: TransformerPlugin = {
29-
visitors: {
30-
[ts.SyntaxKind.Block]: transformBlock,
31-
},
32-
};
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as ts from "typescript";
22
import { LuaTarget } from "../../CompilerOptions";
33
import * as tstl from "../../LuaAST";
4-
import { FunctionVisitor, TransformerPlugin } from "../context";
4+
import { FunctionVisitor } from "../context";
55
import { UndefinedScope, UnsupportedForTarget } from "../utils/errors";
66
import { findScope, ScopeType } from "../utils/scope";
77

8-
const transformBreakStatement: FunctionVisitor<ts.BreakStatement> = (breakStatement, context) => {
8+
export const transformBreakStatement: FunctionVisitor<ts.BreakStatement> = (breakStatement, context) => {
99
const breakableScope = findScope(context, ScopeType.Loop | ScopeType.Switch);
1010
if (breakableScope === undefined) {
1111
throw UndefinedScope();
@@ -18,7 +18,7 @@ const transformBreakStatement: FunctionVisitor<ts.BreakStatement> = (breakStatem
1818
}
1919
};
2020

21-
const transformContinueStatement: FunctionVisitor<ts.ContinueStatement> = (statement, context) => {
21+
export const transformContinueStatement: FunctionVisitor<ts.ContinueStatement> = (statement, context) => {
2222
if (context.luaTarget === LuaTarget.Lua51) {
2323
throw UnsupportedForTarget("Continue statement", LuaTarget.Lua51, statement);
2424
}
@@ -31,10 +31,3 @@ const transformContinueStatement: FunctionVisitor<ts.ContinueStatement> = (state
3131
scope.loopContinued = true;
3232
return tstl.createGotoStatement(`__continue${scope.id}`, statement);
3333
};
34-
35-
export const breakContinuePlugin: TransformerPlugin = {
36-
visitors: {
37-
[ts.SyntaxKind.BreakStatement]: transformBreakStatement,
38-
[ts.SyntaxKind.ContinueStatement]: transformContinueStatement,
39-
},
40-
};

src/transformation/transformers/call.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../LuaAST";
33
import { transformBuiltinCallExpression } from "../builtins";
4-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../context";
4+
import { FunctionVisitor, TransformationContext } from "../context";
55
import { isInTupleReturnFunction, isTupleReturnCall, isVarArgType } from "../utils/annotations";
66
import { validateAssignment } from "../utils/assignment-validation";
77
import { UnsupportedKind } from "../utils/errors";
@@ -12,6 +12,7 @@ import { isValidLuaIdentifier, luaKeywords } from "../utils/safe-names";
1212
import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript";
1313
import { transformElementAccessArgument } from "./access";
1414
import { transformIdentifier } from "./identifier";
15+
import { transformLuaTableCallExpression } from "./lua-table";
1516

1617
export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression };
1718

@@ -138,7 +139,12 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre
138139
}
139140
}
140141

141-
const transformCallExpression: FunctionVisitor<ts.CallExpression> = (node, context) => {
142+
export const transformCallExpression: FunctionVisitor<ts.CallExpression> = (node, context) => {
143+
const luaTableResult = transformLuaTableCallExpression(context, node);
144+
if (luaTableResult) {
145+
return luaTableResult;
146+
}
147+
142148
const isTupleReturn = isTupleReturnCall(context, node);
143149
const isTupleReturnForward =
144150
node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node);
@@ -193,7 +199,7 @@ const transformCallExpression: FunctionVisitor<ts.CallExpression> = (node, conte
193199
};
194200

195201
// TODO: Currently it's also used as an array member
196-
const transformSpreadElement: FunctionVisitor<ts.SpreadElement> = (node, context) => {
202+
export const transformSpreadElement: FunctionVisitor<ts.SpreadElement> = (node, context) => {
197203
const innerExpression = context.transformExpression(node.expression);
198204
if (isTupleReturnCall(context, node.expression)) {
199205
return innerExpression;
@@ -210,10 +216,3 @@ const transformSpreadElement: FunctionVisitor<ts.SpreadElement> = (node, context
210216

211217
return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression);
212218
};
213-
214-
export const callPlugin: TransformerPlugin = {
215-
visitors: {
216-
[ts.SyntaxKind.CallExpression]: transformCallExpression,
217-
[ts.SyntaxKind.SpreadElement]: transformSpreadElement,
218-
},
219-
};

src/transformation/transformers/class/index.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../../LuaAST";
33
import { getOrUpdate, isNonNull } from "../../../utils";
4-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../../context";
4+
import { FunctionVisitor, TransformationContext } from "../../context";
55
import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations";
66
import {
77
ForbiddenLuaTableNonDeclaration,
@@ -38,10 +38,10 @@ import { isGetAccessorOverride, transformAccessorDeclaration } from "./members/a
3838
import { createConstructorName, transformConstructorDeclaration } from "./members/constructor";
3939
import { transformClassInstanceFields } from "./members/fields";
4040
import { transformMethodDeclaration } from "./members/method";
41-
import { checkForLuaLibType, transformNewExpression } from "./new";
41+
import { checkForLuaLibType } from "./new";
4242
import { getExtendedType, getExtendedTypeNode, isStaticNode } from "./utils";
4343

44-
function transformClassAsExpression(
44+
export function transformClassAsExpression(
4545
expression: ts.ClassLikeDeclaration,
4646
context: TransformationContext,
4747
isDefaultExport = false
@@ -64,7 +64,7 @@ function transformClassAsExpression(
6464

6565
const classStacks = new WeakMap<TransformationContext, ts.ClassLikeDeclaration[]>();
6666

67-
function transformClassDeclaration(
67+
export function transformClassDeclaration(
6868
classDeclaration: ts.ClassLikeDeclaration,
6969
context: TransformationContext,
7070
nameOverride?: tstl.Identifier
@@ -331,7 +331,7 @@ function transformClassDeclaration(
331331
return result;
332332
}
333333

334-
const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (expression, context) => {
334+
export const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (expression, context) => {
335335
const classStack = getOrUpdate(classStacks, context, () => []);
336336
const classDeclaration = classStack[classStack.length - 1];
337337
const typeNode = getExtendedTypeNode(context, classDeclaration);
@@ -366,14 +366,4 @@ const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (expressio
366366
return tstl.createTableIndexExpression(baseClassName, tstl.createStringLiteral("prototype"));
367367
};
368368

369-
const transformThisExpression: FunctionVisitor<ts.ThisExpression> = node => createSelfIdentifier(node);
370-
371-
export const classPlugin: TransformerPlugin = {
372-
visitors: {
373-
[ts.SyntaxKind.ClassExpression]: transformClassAsExpression,
374-
[ts.SyntaxKind.ClassDeclaration]: transformClassDeclaration,
375-
[ts.SyntaxKind.SuperKeyword]: transformSuperExpression,
376-
[ts.SyntaxKind.ThisKeyword]: transformThisExpression,
377-
[ts.SyntaxKind.NewExpression]: transformNewExpression,
378-
},
379-
};
369+
export const transformThisExpression: FunctionVisitor<ts.ThisExpression> = node => createSelfIdentifier(node);

src/transformation/transformers/class/new.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations";
55
import { InvalidAnnotationArgumentNumber, InvalidNewExpressionOnExtension } from "../../utils/errors";
66
import { importLuaLibFeature, LuaLibFeature } from "../../utils/lualib";
77
import { transformArguments } from "../call";
8+
import { transformLuaTableNewExpression } from "../lua-table";
89

910
const builtinErrorTypeNames = new Set([
1011
"Error",
@@ -47,6 +48,11 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type
4748
}
4849

4950
export const transformNewExpression: FunctionVisitor<ts.NewExpression> = (node, context) => {
51+
const luaTableResult = transformLuaTableNewExpression(context, node);
52+
if (luaTableResult) {
53+
return luaTableResult;
54+
}
55+
5056
const name = context.transformExpression(node.expression);
5157
const signature = context.checker.getResolvedSignature(node);
5258
const params = node.arguments

src/transformation/transformers/conditional.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as ts from "typescript";
22
import * as tstl from "../../LuaAST";
3-
import { FunctionVisitor, TransformationContext, TransformerPlugin } from "../context";
3+
import { FunctionVisitor, TransformationContext } from "../context";
44
import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope";
55
import { transformBlockOrStatement } from "./block";
66

@@ -56,7 +56,7 @@ function transformProtectedConditionalExpression(
5656
return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression);
5757
}
5858

59-
const transformConditionalExpression: FunctionVisitor<ts.ConditionalExpression> = (expression, context) => {
59+
export const transformConditionalExpression: FunctionVisitor<ts.ConditionalExpression> = (expression, context) => {
6060
if (canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue))) {
6161
return transformProtectedConditionalExpression(context, expression);
6262
}
@@ -70,7 +70,7 @@ const transformConditionalExpression: FunctionVisitor<ts.ConditionalExpression>
7070
return tstl.createBinaryExpression(conditionAnd, val2, tstl.SyntaxKind.OrOperator, expression);
7171
};
7272

73-
function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): tstl.IfStatement {
73+
export function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): tstl.IfStatement {
7474
pushScope(context, ScopeType.Conditional);
7575
const condition = context.transformExpression(statement.expression);
7676
const statements = performHoisting(context, transformBlockOrStatement(context, statement.thenStatement));
@@ -95,10 +95,3 @@ function transformIfStatement(statement: ts.IfStatement, context: Transformation
9595

9696
return tstl.createIfStatement(condition, ifBlock);
9797
}
98-
99-
export const conditionalPlugin: TransformerPlugin = {
100-
visitors: {
101-
[ts.SyntaxKind.ConditionalExpression]: transformConditionalExpression,
102-
[ts.SyntaxKind.IfStatement]: transformIfStatement,
103-
},
104-
};

0 commit comments

Comments
 (0)