From 014689f88282875fc2b5dafb227f45eba5177d47 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 3 May 2019 22:41:26 +0200 Subject: [PATCH 1/4] Fixed bug where elseBlock statement did not get parent assigned correctly --- src/LuaAST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index d9983979e..8f015bc3f 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -310,7 +310,7 @@ export function createIfStatement( statement.condition = condition; setParent(ifBlock, statement); statement.ifBlock = ifBlock; - setParent(ifBlock, statement); + setParent(elseBlock, statement); statement.elseBlock = elseBlock; return statement; } From 85f20f595d759cf7a53b0610d6a07174b0123cf1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 3 May 2019 22:44:02 +0200 Subject: [PATCH 2/4] Improved printer interface --- src/LuaPrinter.ts | 100 ++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 40b05d8a2..e83404200 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,6 +1,6 @@ import * as path from "path"; -import {SourceNode, SourceMapGenerator, RawSourceMap, SourceMapConsumer} from "source-map"; +import {SourceNode, SourceMapGenerator} from "source-map"; import * as tstl from "./LuaAST"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -145,19 +145,19 @@ export class LuaPrinter { return this.concatNodes(header, fileBlockNode); } - private pushIndent(): void { + protected pushIndent(): void { this.currentIndent = this.currentIndent + " "; } - private popIndent(): void { + protected popIndent(): void { this.currentIndent = this.currentIndent.slice(4); } - private indent(input: SourceChunk = ""): SourceChunk { + protected indent(input: SourceChunk = ""): SourceChunk { return this.concatNodes(this.currentIndent, input); } - private createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { + protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { const originalPos = tstl.getOriginalPos(node); return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined @@ -166,12 +166,12 @@ export class LuaPrinter { : new SourceNode(null, null, this.sourceFile, chunks); } - private concatNodes(...chunks: SourceChunk[]): SourceNode { + protected concatNodes(...chunks: SourceChunk[]): SourceNode { // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, this.sourceFile, chunks); } - private printBlock(block: tstl.Block): SourceNode { + protected printBlock(block: tstl.Block): SourceNode { return this.createSourceNode(block, this.printStatementArray(block.statements)); } @@ -196,7 +196,7 @@ export class LuaPrinter { return result || false; } - private printStatementArray(statements: tstl.Statement[]): SourceChunk[] { + protected printStatementArray(statements: tstl.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; statements = this.removeDeadAndEmptyStatements(statements); statements.forEach( @@ -216,7 +216,7 @@ export class LuaPrinter { return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } - private printStatement(statement: tstl.Statement): SourceNode { + public printStatement(statement: tstl.Statement): SourceNode { switch (statement.kind) { case tstl.SyntaxKind.DoStatement: return this.printDoStatement(statement as tstl.DoStatement); @@ -249,7 +249,7 @@ export class LuaPrinter { } } - private printDoStatement(statement: tstl.DoStatement): SourceNode { + public printDoStatement(statement: tstl.DoStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("do\n")); @@ -261,7 +261,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { + public printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("local ")); @@ -282,7 +282,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { + public printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent()); @@ -305,9 +305,12 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - private printIfStatement(statement: tstl.IfStatement, isElseIf?: boolean): SourceNode { + public printIfStatement(statement: tstl.IfStatement): SourceNode { const chunks: SourceChunk[] = []; + const isElseIf = statement.parent !== undefined + && tstl.isIfStatement(statement.parent); + const prefix = isElseIf ? "elseif" : "if"; chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n"); @@ -318,7 +321,7 @@ export class LuaPrinter { if (statement.elseBlock) { if (tstl.isIfStatement(statement.elseBlock)) { - chunks.push(this.printIfStatement(statement.elseBlock, true)); + chunks.push(this.printIfStatement(statement.elseBlock)); } else { chunks.push(this.indent("else\n")); this.pushIndent(); @@ -333,7 +336,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printWhileStatement(statement: tstl.WhileStatement): SourceNode { + public printWhileStatement(statement: tstl.WhileStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n"); @@ -347,7 +350,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { + public printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent(`repeat\n`)); @@ -361,7 +364,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printForStatement(statement: tstl.ForStatement): SourceNode { + public printForStatement(statement: tstl.ForStatement): SourceNode { const ctrlVar = this.printExpression(statement.controlVariable); const ctrlVarInit = this.printExpression(statement.controlVariableInitializer); const limit = this.printExpression(statement.limitExpression); @@ -384,7 +387,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printForInStatement(statement: tstl.ForInStatement): SourceNode { + public printForInStatement(statement: tstl.ForInStatement): SourceNode { const names = statement.names.map(i => this.printIdentifier(i)).join(", "); const expressions = statement.expressions.map(e => this.printExpression(e)).join(", "); @@ -400,15 +403,15 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - private printGotoStatement(statement: tstl.GotoStatement): SourceNode { + public printGotoStatement(statement: tstl.GotoStatement): SourceNode { return this.createSourceNode(statement, [this.indent("goto "), statement.label]); } - private printLabelStatement(statement: tstl.LabelStatement): SourceNode { + public printLabelStatement(statement: tstl.LabelStatement): SourceNode { return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]); } - private printReturnStatement(statement: tstl.ReturnStatement): SourceNode { + public printReturnStatement(statement: tstl.ReturnStatement): SourceNode { if (!statement.expressions || statement.expressions.length === 0) { return this.createSourceNode(statement, this.indent("return")); } @@ -420,16 +423,16 @@ export class LuaPrinter { return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } - private printBreakStatement(statement: tstl.BreakStatement): SourceNode { + public printBreakStatement(statement: tstl.BreakStatement): SourceNode { return this.createSourceNode(statement, this.indent("break")); } - private printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { + public printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { return this.concatNodes(this.indent(), this.printExpression(statement.expression)); } // Expressions - private printExpression(expression: tstl.Expression): SourceNode { + public printExpression(expression: tstl.Expression): SourceNode { switch (expression.kind) { case tstl.SyntaxKind.StringLiteral: return this.printStringLiteral(expression as tstl.StringLiteral); @@ -467,23 +470,23 @@ export class LuaPrinter { } } - private printStringLiteral(expression: tstl.StringLiteral): SourceNode { + public printStringLiteral(expression: tstl.StringLiteral): SourceNode { return this.createSourceNode(expression, `"${expression.value}"`); } - private printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { + public printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { return this.createSourceNode(expression, String(expression.value)); } - private printNilLiteral(expression: tstl.NilLiteral): SourceNode { + public printNilLiteral(expression: tstl.NilLiteral): SourceNode { return this.createSourceNode(expression, "nil"); } - private printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { + public printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { return this.createSourceNode(expression, "..."); } - private printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { + public printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { if (expression.kind === tstl.SyntaxKind.TrueKeyword) { return this.createSourceNode(expression, "true"); } else { @@ -503,7 +506,7 @@ export class LuaPrinter { return this.joinChunks(", ", parameterChunks); } - private printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { + public printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("function("); @@ -531,7 +534,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { + public printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { const expression = statement.right[0]; const chunks: SourceChunk[] = []; @@ -549,7 +552,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { + public printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { const chunks: SourceChunk[] = []; const value = this.printExpression(expression.value); @@ -567,7 +570,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printTableExpression(expression: tstl.TableExpression): SourceNode { + public printTableExpression(expression: tstl.TableExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("{"); @@ -591,7 +594,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { + public printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); @@ -600,7 +603,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { + public printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.left)); @@ -610,11 +613,11 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { + public printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { return this.createSourceNode(expression, ["(", this.printExpression(expression.innerExpression), ")"]); } - private printCallExpression(expression: tstl.CallExpression): SourceNode { + public printCallExpression(expression: tstl.CallExpression): SourceNode { const chunks = []; const parameterChunks = expression.params !== undefined @@ -626,7 +629,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { + public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { const prefix = this.printExpression(expression.prefixExpression); const parameterChunks = expression.params !== undefined @@ -638,11 +641,11 @@ export class LuaPrinter { return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"); } - private printIdentifier(expression: tstl.Identifier): SourceNode { + public printIdentifier(expression: tstl.Identifier): SourceNode { return this.createSourceNode(expression, expression.text); } - private printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { + public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.table)); @@ -654,15 +657,12 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printOperator(kind: tstl.Operator): string { - return LuaPrinter.operatorMap[kind]; - } - - private isEmptyStatement(statement: tstl.Statement): boolean { - return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + public printOperator(kind: tstl.Operator): SourceNode { + // tslint:disable-next-line:no-null-keyword + return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } - private removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { + protected removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { const aliveStatements = []; for (const statement of statements) { if (!this.isEmptyStatement(statement)) { @@ -675,7 +675,11 @@ export class LuaPrinter { return aliveStatements; } - private joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { + protected isEmptyStatement(statement: tstl.Statement): boolean { + return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + } + + protected joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { const result = []; for (let i = 0; i < chunks.length; i++) { result.push(chunks[i]); From 32530bc76218ac6039b67cc5b1688bb7f3394b10 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 4 May 2019 14:34:52 +0200 Subject: [PATCH 3/4] Cleaned up transformer a little --- src/LuaTransformer.ts | 226 ++++++++++++++++++++++-------------------- 1 file changed, 116 insertions(+), 110 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 75392d1ad..75bce8b4f 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -603,13 +603,13 @@ export class LuaTransformer { // Transform get accessors statement.members.filter(ts.isGetAccessor).forEach(getAccessor => { - const transformResult = this.transformGetAccessorDeclaration(getAccessor, className, statement); + const transformResult = this.transformGetAccessorDeclaration(getAccessor, className); result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform set accessors statement.members.filter(ts.isSetAccessor).forEach(setAccessor => { - const transformResult = this.transformSetAccessorDeclaration(setAccessor, className, statement); + const transformResult = this.transformSetAccessorDeclaration(setAccessor, className); result.push(...this.statementVisitResultToArray(transformResult)); }); @@ -642,7 +642,7 @@ export class LuaTransformer { return result; } - public createClassCreationMethods( + private createClassCreationMethods( statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, extendsType?: ts.Type @@ -1018,7 +1018,7 @@ export class LuaTransformer { ); } - public transformConstructorDeclaration( + private transformConstructorDeclaration( statement: ts.ConstructorDeclaration, className: tstl.Identifier, instanceFields: ts.PropertyDeclaration[], @@ -1111,8 +1111,7 @@ export class LuaTransformer { public transformGetAccessorDeclaration( getAccessor: ts.GetAccessorDeclaration, - className: tstl.Identifier, - classDeclaration: ts.ClassLikeDeclaration + className: tstl.Identifier ): StatementVisitResult { if (getAccessor.body === undefined) { @@ -1148,8 +1147,7 @@ export class LuaTransformer { public transformSetAccessorDeclaration( setAccessor: ts.SetAccessorDeclaration, - className: tstl.Identifier, - classDeclaration: ts.ClassLikeDeclaration + className: tstl.Identifier ): StatementVisitResult { if (setAccessor.body === undefined) { @@ -1296,7 +1294,9 @@ export class LuaTransformer { parameters.forEach(binding => { if (ts.isObjectBindingPattern(binding.name) || ts.isArrayBindingPattern(binding.name)) { const identifier = tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`); - bindingPatternDeclarations.push(...this.transformBindingPattern(binding.name, identifier)); + bindingPatternDeclarations.push(...this.statementVisitResultToArray( + this.transformBindingPattern(binding.name, identifier) + )); } }); @@ -1325,12 +1325,13 @@ export class LuaTransformer { return tstl.createIfStatement(nilCondition, ifBlock, undefined, declaration); } - public * transformBindingPattern( + public transformBindingPattern( pattern: ts.BindingPattern, table: tstl.Identifier, propertyAccessStack: ts.PropertyName[] = [] - ): IterableIterator + ): StatementVisitResult { + const result: tstl.Statement[] = []; const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (let index = 0; index < pattern.elements.length; index++) { const element = pattern.elements[index]; @@ -1343,7 +1344,9 @@ export class LuaTransformer { if (propertyName !== undefined) { propertyAccessStack.push(propertyName); } - yield* this.transformBindingPattern(element.name, table, propertyAccessStack); + result.push(...this.statementVisitResultToArray( + this.transformBindingPattern(element.name, table, propertyAccessStack) + )); } else { // Disallow ellipsis destructure if (element.dotDotDotToken) { @@ -1368,12 +1371,12 @@ export class LuaTransformer { const expression = isObjectBindingPattern ? tstl.createTableIndexExpression(tableExpression, tstl.createStringLiteral(propertyName.text)) : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); - yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, expression); + result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); if (element.initializer) { const identifier = this.shouldExportIdentifier(variableName) ? this.createExportedIdentifier(variableName) : variableName; - yield tstl.createIfStatement( + result.push(tstl.createIfStatement( tstl.createBinaryExpression( identifier, tstl.createNilLiteral(), @@ -1387,12 +1390,13 @@ export class LuaTransformer { ), ] ) - ); + )); } } } } propertyAccessStack.pop(); + return result; } public transformModuleDeclaration(statement: ts.ModuleDeclaration): StatementVisitResult { @@ -1829,7 +1833,9 @@ export class LuaTransformer { table, this.transformExpression(statement.initializer))); } } - statements.push(...this.transformBindingPattern(statement.name, table)); + statements.push(...this.statementVisitResultToArray( + this.transformBindingPattern(statement.name, table) + )); return statements; } @@ -1984,7 +1990,7 @@ export class LuaTransformer { return tstl.createExpressionStatement(this.expectExpression(this.transformExpression(expression))); } - public transformYield(expression: ts.YieldExpression): ExpressionVisitResult { + public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { return tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("coroutine"), @@ -2108,7 +2114,7 @@ export class LuaTransformer { return tstl.createDoStatement(result, statement); } - public transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { + private transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); @@ -2139,7 +2145,7 @@ export class LuaTransformer { } } - public transformLoopBody( + protected transformLoopBody( loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement ): tstl.Statement[] { @@ -2159,13 +2165,13 @@ export class LuaTransformer { return baseResult; } - public transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { + private transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { return ts.isBlock(statement) ? this.transformStatements(statement.statements) : this.statementVisitResultToArray(this.transformStatement(statement)); } - public transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const arrayExpression = this.expectExpression(this.transformExpression(statement.expression)); // Arrays use numeric for loop (performs better than ipairs) @@ -2205,7 +2211,7 @@ export class LuaTransformer { } } - public transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const luaIterator = this.expectExpression(this.transformExpression(statement.expression)); const type = this.checker.getTypeAtLocation(statement.expression); const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); @@ -2278,7 +2284,7 @@ export class LuaTransformer { } } - public transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const iterable = this.expectExpression(this.transformExpression(statement.expression)); if (ts.isVariableDeclarationList(statement.initializer) && ts.isIdentifier(statement.initializer.declarations[0].name)) { @@ -2500,7 +2506,7 @@ export class LuaTransformer { ); } - public transformEmptyStatement(arg0: ts.EmptyStatement): StatementVisitResult { + public transformEmptyStatement(statement: ts.EmptyStatement): StatementVisitResult { return undefined; } @@ -2564,7 +2570,7 @@ export class LuaTransformer { case ts.SyntaxKind.NonNullExpression: return this.transformExpression((expression as ts.NonNullExpression).expression); case ts.SyntaxKind.YieldExpression: - return this.transformYield(expression as ts.YieldExpression); + return this.transformYieldExpression(expression as ts.YieldExpression); case ts.SyntaxKind.EmptyStatement: return undefined; case ts.SyntaxKind.NotEmittedStatement: @@ -2578,7 +2584,7 @@ export class LuaTransformer { } } - public transformBinaryOperation( + protected transformBinaryOperation( left: tstl.Expression, right: tstl.Expression, operator: ts.BinaryOperator, @@ -2692,7 +2698,7 @@ export class LuaTransformer { ); } - public transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { + private transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { // Validate assignment const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); @@ -2739,7 +2745,7 @@ export class LuaTransformer { } } - public transformAssignmentExpression(expression: ts.BinaryExpression) + private transformAssignmentExpression(expression: ts.BinaryExpression) : tstl.CallExpression | tstl.MethodCallExpression { // Validate assignment @@ -2834,7 +2840,7 @@ export class LuaTransformer { } } - public transformCompoundAssignmentExpression( + private transformCompoundAssignmentExpression( expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, @@ -3009,7 +3015,7 @@ export class LuaTransformer { ); } - public transformCompoundAssignmentStatement( + private transformCompoundAssignmentStatement( node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, @@ -3055,7 +3061,7 @@ export class LuaTransformer { } } - public transformUnaryBitLibOperation( + private transformUnaryBitLibOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator, @@ -3077,7 +3083,7 @@ export class LuaTransformer { ); } - public transformUnaryBitOperation( + private transformUnaryBitOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator @@ -3098,7 +3104,7 @@ export class LuaTransformer { } } - public transformBinaryBitLibOperation( + private transformBinaryBitLibOperation( node: ts.Node, left: tstl.Expression, right: tstl.Expression, @@ -3173,7 +3179,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression); } - private transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { + public transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { const isStrict = this.options.strict === true || this.options.strictNullChecks === true; if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { return this.transformProtectedConditionalExpression(expression); @@ -3264,23 +3270,23 @@ export class LuaTransformer { } } - public transformArrayLiteral(node: ts.ArrayLiteralExpression): ExpressionVisitResult { + public transformArrayLiteral(expression: ts.ArrayLiteralExpression): ExpressionVisitResult { const values: tstl.TableFieldExpression[] = []; - node.elements.forEach(child => { + expression.elements.forEach(child => { const childExpression = this.transformExpression(child); if (childExpression) { values.push(tstl.createTableFieldExpression(childExpression, undefined, child)); } }); - return tstl.createTableExpression(values, node); + return tstl.createTableExpression(values, expression); } - public transformObjectLiteral(node: ts.ObjectLiteralExpression): ExpressionVisitResult { + public transformObjectLiteral(expression: ts.ObjectLiteralExpression): ExpressionVisitResult { const properties: tstl.TableFieldExpression[] = []; // Add all property assignments - node.properties.forEach(element => { + expression.properties.forEach(element => { const name = element.name ? this.transformPropertyName(element.name) : undefined; if (ts.isPropertyAssignment(element)) { const expression = this.expectExpression(this.transformExpression(element.initializer)); @@ -3292,11 +3298,11 @@ export class LuaTransformer { const expression = this.expectExpression(this.transformFunctionExpression(element)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else { - throw TSTLErrors.UnsupportedKind("object literal element", element.kind, node); + throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); } }); - return tstl.createTableExpression(properties, node); + return tstl.createTableExpression(properties, expression); } public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { @@ -3439,35 +3445,35 @@ export class LuaTransformer { return tstl.createTableIndexExpression(baseClassName, tstl.createStringLiteral("prototype")); } - public transformCallExpression(node: ts.CallExpression): ExpressionVisitResult { + public transformCallExpression(expression: ts.CallExpression): ExpressionVisitResult { // Check for calls on primitives to override let parameters: tstl.Expression[] = []; - const isTupleReturn = tsHelper.isTupleReturnCall(node, this.checker); - const isTupleReturnForward = node.parent - && ts.isReturnStatement(node.parent) - && tsHelper.isInTupleReturnFunction(node, this.checker); - const isInDestructingAssignment = tsHelper.isInDestructingAssignment(node); - const isInSpread = node.parent && ts.isSpreadElement(node.parent); - const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); + const isTupleReturn = tsHelper.isTupleReturnCall(expression, this.checker); + const isTupleReturnForward = expression.parent + && ts.isReturnStatement(expression.parent) + && tsHelper.isInTupleReturnFunction(expression, this.checker); + const isInDestructingAssignment = tsHelper.isInDestructingAssignment(expression); + const isInSpread = expression.parent && ts.isSpreadElement(expression.parent); + const returnValueIsUsed = expression.parent && !ts.isExpressionStatement(expression.parent); const wrapResult = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment && !isInSpread && returnValueIsUsed; - if (ts.isPropertyAccessExpression(node.expression)) { - const result = this.expectExpression(this.transformPropertyCall(node)); + if (ts.isPropertyAccessExpression(expression.expression)) { + const result = this.expectExpression(this.transformPropertyCall(expression)); return wrapResult ? this.wrapInTable(result) : result; } - if (ts.isElementAccessExpression(node.expression)) { - const result = this.expectExpression(this.transformElementCall(node)); + if (ts.isElementAccessExpression(expression.expression)) { + const result = this.expectExpression(this.transformElementCall(expression)); return wrapResult ? this.wrapInTable(result) : result; } - const signature = this.checker.getResolvedSignature(node); + const signature = this.checker.getResolvedSignature(expression); // Handle super calls properly - if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { - parameters = this.transformArguments(node.arguments, signature, ts.createThis()); + if (expression.expression.kind === ts.SyntaxKind.SuperKeyword) { + parameters = this.transformArguments(expression.arguments, signature, ts.createThis()); return tstl.createCallExpression( tstl.createTableIndexExpression( @@ -3478,23 +3484,23 @@ export class LuaTransformer { ); } - const callPath = this.expectExpression(this.transformExpression(node.expression)); + const callPath = this.expectExpression(this.transformExpression(expression.expression)); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) { - parameters = this.transformArguments(node.arguments, signature); + parameters = this.transformArguments(expression.arguments, signature); } else { const context = this.isStrict ? ts.createNull() : ts.createIdentifier("_G"); - parameters = this.transformArguments(node.arguments, signature, context); + parameters = this.transformArguments(expression.arguments, signature, context); } - const expressionType = this.checker.getTypeAtLocation(node.expression); + const expressionType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStandardLibraryType(expressionType, "SymbolConstructor", this.program)) { - return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); + return this.transformLuaLibFunction(LuaLibFeature.Symbol, expression, ...parameters); } - const callExpression = tstl.createCallExpression(callPath, parameters, node); + const callExpression = tstl.createCallExpression(callPath, parameters, expression); return wrapResult ? this.wrapInTable(callExpression) : callExpression; } @@ -3686,22 +3692,22 @@ export class LuaTransformer { return parameters; } - public transformPropertyAccessExpression(node: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = node.name.text; + public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { + const property = expression.name.text; // Check for primitive types to override - const type = this.checker.getTypeAtLocation(node.expression); + const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStringType(type)) { - return this.transformStringProperty(node); + return this.transformStringProperty(expression); } else if (tsHelper.isArrayType(type, this.checker, this.program)) { - const arrayPropertyAccess = this.transformArrayProperty(node); + const arrayPropertyAccess = this.transformArrayProperty(expression); if (arrayPropertyAccess) { return arrayPropertyAccess; } } else if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) { - return this.transformConstEnumValue(type, property, node); + return this.transformConstEnumValue(type, property, expression); } this.checkForLuaLibType(type); @@ -3709,23 +3715,23 @@ export class LuaTransformer { const decorators = tsHelper.getCustomDecorators(type, this.checker); // Do not output path for member only enums if (decorators.has(DecoratorKind.CompileMembersOnly)) { - return tstl.createIdentifier(property, node); + return tstl.createIdentifier(property, expression); } // Catch math expressions - if (ts.isIdentifier(node.expression)) { - const ownerType = this.checker.getTypeAtLocation(node.expression); + if (ts.isIdentifier(expression.expression)) { + const ownerType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { - return this.transformMathExpression(node.name); + return this.transformMathExpression(expression.name); } else if (tsHelper.isStandardLibraryType(ownerType, "Symbol", this.program)) { // Pull in Symbol lib this.importLuaLibFeature(LuaLibFeature.Symbol); } } - const callPath = this.expectExpression(this.transformExpression(node.expression)); - return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), node); + const callPath = this.expectExpression(this.transformExpression(expression.expression)); + return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression); } // Transpile a Math._ property @@ -4315,19 +4321,19 @@ export class LuaTransformer { } } - public transformAssertionExpression(node: ts.AssertionExpression): ExpressionVisitResult { + public transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult { this.validateFunctionAssignment( - node, - this.checker.getTypeAtLocation(node.expression), - this.checker.getTypeAtLocation(node.type) + expression, + this.checker.getTypeAtLocation(expression.expression), + this.checker.getTypeAtLocation(expression.type) ); - return this.transformExpression(node.expression); + return this.transformExpression(expression.expression); } - public transformTypeOfExpression(node: ts.TypeOfExpression): ExpressionVisitResult { - const expression = this.expectExpression(this.transformExpression(node.expression)); + public transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult { + const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); const typeFunctionIdentifier = tstl.createIdentifier("type"); - const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [expression]); + const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [innerExpression]); const tableString = tstl.createStringLiteral("table"); const objectString = tstl.createStringLiteral("object"); const condition = tstl.createBinaryExpression(typeCall, tableString, tstl.SyntaxKind.EqualityOperator); @@ -4338,7 +4344,7 @@ export class LuaTransformer { andClause, tstl.cloneNode(typeCall), tstl.SyntaxKind.OrOperator, - node + expression ) ); } @@ -4418,7 +4424,7 @@ export class LuaTransformer { } } - private getIdentifierText(identifier: ts.Identifier): string { + protected getIdentifierText(identifier: ts.Identifier): string { let escapedText = identifier.escapedText as string; const underScoreCharCode = "_".charCodeAt(0); if (escapedText.length >= 3 && escapedText.charCodeAt(0) === underScoreCharCode && @@ -4454,7 +4460,7 @@ export class LuaTransformer { return identifier; } - private isIdentifierExported(identifier: tstl.Identifier): boolean { + protected isIdentifierExported(identifier: tstl.Identifier): boolean { if (!this.isModule && !this.currentNamespace) { return false; } @@ -4489,14 +4495,14 @@ export class LuaTransformer { return false; } - private addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { + protected addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); } return identifier; } - private createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { + protected createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { const exportTable = this.currentNamespace ? this.transformIdentifier(this.currentNamespace.name as ts.Identifier) : this.createExportsIdentifier(); @@ -4506,7 +4512,7 @@ export class LuaTransformer { tstl.createStringLiteral(identifier.text)); } - private transformLuaLibFunction( + protected transformLuaLibFunction( func: LuaLibFeature, tsParent?: ts.Expression, ...params: tstl.Expression[] @@ -4517,7 +4523,7 @@ export class LuaTransformer { return tstl.createCallExpression(functionIdentifier, params, tsParent); } - public checkForLuaLibType(type: ts.Type): void { + protected checkForLuaLibType(type: ts.Type): void { if (type.symbol) { switch (this.checker.getFullyQualifiedName(type.symbol)) { case "Map": @@ -4536,11 +4542,11 @@ export class LuaTransformer { } } - private importLuaLibFeature(feature: LuaLibFeature): void { + protected importLuaLibFeature(feature: LuaLibFeature): void { this.luaLibFeatureSet.add(feature); } - private createImmediatelyInvokedFunctionExpression( + protected createImmediatelyInvokedFunctionExpression( statements: tstl.Statement[], result: tstl.Expression | tstl.Expression[], tsOriginal: ts.Node @@ -4553,7 +4559,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); } - private createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { + protected createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { switch (this.luaTarget) { case LuaTarget.Lua51: case LuaTarget.LuaJIT: @@ -4573,7 +4579,7 @@ export class LuaTransformer { } } - private getAbsoluteImportPath(relativePath: string): string { + protected getAbsoluteImportPath(relativePath: string): string { if (relativePath.charAt(0) !== "." && this.options.baseUrl) { return path.resolve(this.options.baseUrl, relativePath); } @@ -4585,7 +4591,7 @@ export class LuaTransformer { return path.resolve(path.dirname(this.currentSourceFile.fileName), relativePath); } - private getImportPath(relativePath: string, node: ts.Node): string { + protected getImportPath(relativePath: string, node: ts.Node): string { const rootDir = this.options.rootDir ? path.resolve(this.options.rootDir) : path.resolve("."); const absoluteImportPath = path.format(path.parse(this.getAbsoluteImportPath(relativePath))); const absoluteRootDirPath = path.format(path.parse(rootDir)); @@ -4599,7 +4605,7 @@ export class LuaTransformer { } } - private formatPathToLuaPath(filePath: string): string { + protected formatPathToLuaPath(filePath: string): string { filePath = filePath.replace(/\.json$/, ""); if (process.platform === "win32") { // Windows can use backslashes @@ -4612,7 +4618,7 @@ export class LuaTransformer { .replace(/\//g, "."); } - private shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { + protected shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { if (!this.isModule && !this.currentNamespace) { return false; } @@ -4623,15 +4629,15 @@ export class LuaTransformer { } } - private createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { + protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { return tstl.createIdentifier("self", tsOriginal); } - private createExportsIdentifier(): tstl.Identifier { + protected createExportsIdentifier(): tstl.Identifier { return tstl.createIdentifier("____exports"); } - private createLocalOrExportedOrGlobalDeclaration( + protected createLocalOrExportedOrGlobalDeclaration( lhs: tstl.Identifier | tstl.Identifier[], rhs?: tstl.Expression, tsOriginal?: ts.Node, @@ -4737,7 +4743,7 @@ export class LuaTransformer { } } - private validateFunctionAssignment(node: ts.Node, fromType: ts.Type, toType: ts.Type, toName?: string): void { + protected validateFunctionAssignment(node: ts.Node, fromType: ts.Type, toType: ts.Type, toName?: string): void { if (toType === fromType) { return; } @@ -4823,7 +4829,7 @@ export class LuaTransformer { } } - private wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { + protected wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { const returnStatement = tstl.createReturnStatement([expression]); return tstl.createFunctionExpression( tstl.createBlock([returnStatement]), @@ -4834,12 +4840,12 @@ export class LuaTransformer { ); } - private wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { + protected wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { const fields = expressions.map(e => tstl.createTableFieldExpression(e)); return tstl.createParenthesizedExpression(tstl.createTableExpression(fields)); } - private wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { + protected wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { if (tstl.isStringLiteral(expression) || tstl.isNumericLiteral(expression) || (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator)) @@ -4849,14 +4855,14 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); } - private expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { + protected expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { if (tstl.isBinaryExpression(expression)) { expression = tstl.createParenthesizedExpression(expression); } return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } - private getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { + protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { const symbol = this.checker.getSymbolAtLocation(identifier); let symbolId: number | undefined; if (symbol) { @@ -5080,7 +5086,7 @@ export class LuaTransformer { return declaration; } - private statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { + protected statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { if (!Array.isArray(visitResult)) { if (visitResult) { return [visitResult]; @@ -5088,14 +5094,14 @@ export class LuaTransformer { return []; } - return visitResult.filter(s => s !== undefined); + return this.filterUndefined(visitResult); } - private filterUndefined(items: Array): T[] { + protected filterUndefined(items: Array): T[] { return items.filter(i => i !== undefined) as T[]; } - private filterUndefinedAndCast( + protected filterUndefinedAndCast( items: Array, cast: (item: TOriginal) => item is TCast ): TCast[] { const filteredItems = items.filter(i => i !== undefined) as TOriginal[]; @@ -5106,7 +5112,7 @@ export class LuaTransformer { } } - private expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { + protected expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { if (visitResult === undefined) { throw new Error("Expected single visit result expression, but found undefined"); } else { From 786fc45640ce3b9dbb82e2bb8ffa2122591dcd10 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 4 May 2019 17:10:16 +0200 Subject: [PATCH 4/4] Renamed isEmptyStatement to isStatementEmpty --- src/LuaPrinter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e83404200..e3cb3ff5f 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -665,7 +665,7 @@ export class LuaPrinter { protected removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { const aliveStatements = []; for (const statement of statements) { - if (!this.isEmptyStatement(statement)) { + if (!this.isStatementEmpty(statement)) { aliveStatements.push(statement); } if (tstl.isReturnStatement(statement)) { @@ -675,7 +675,7 @@ export class LuaPrinter { return aliveStatements; } - protected isEmptyStatement(statement: tstl.Statement): boolean { + protected isStatementEmpty(statement: tstl.Statement): boolean { return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); }