Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 54 additions & 9 deletions src/LuaTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,15 @@ export class LuaTransformer {
);
}

else if (ts.isDeleteExpression(expression)) {
return tstl.createAssignmentStatement(
this.transformExpression(expression.expression) as tstl.IdentifierOrTableIndexExpression,
tstl.createNilLiteral(),
undefined,
expression
);
}

return tstl.createExpressionStatement(this.transformExpression(expression));
}

Expand Down Expand Up @@ -1401,6 +1410,8 @@ export class LuaTransformer {
return this.transformArrayLiteral(expression as ts.ArrayLiteralExpression);
case ts.SyntaxKind.ObjectLiteralExpression:
return this.transformObjectLiteral(expression as ts.ObjectLiteralExpression);
case ts.SyntaxKind.DeleteExpression:
return this.transformDeleteExpression(expression as ts.DeleteExpression);
case ts.SyntaxKind.FunctionExpression:
return this.transformFunctionExpression(expression as ts.ArrowFunction, this.selfIdentifier);
case ts.SyntaxKind.ArrowFunction:
Expand Down Expand Up @@ -1429,6 +1440,10 @@ export class LuaTransformer {
return this.transformAssertionExpression(expression as ts.AssertionExpression);
case ts.SyntaxKind.TypeOfExpression:
return this.transformTypeOfExpression(expression as ts.TypeOfExpression);
case ts.SyntaxKind.SpreadElement:
throw new Error("Not yet implemented");
case ts.SyntaxKind.NonNullExpression:
return this.transformExpression((expression as ts.NonNullExpression).expression);
case ts.SyntaxKind.EmptyStatement:
// TODO move to extra function (consistency)
return undefined;
Expand Down Expand Up @@ -1618,7 +1633,10 @@ export class LuaTransformer {
tstl.createAssignmentStatement(left as tstl.IdentifierOrTableIndexExpression[], tmps),
];
return this.createImmediatelyInvokedFunctionExpression(
statements, tstl.createTableExpression(tmps.map(t => tstl.createTableFieldExpression(t))));
statements,
tstl.createTableExpression(tmps.map(t => tstl.createTableFieldExpression(t))),
expression
);
}

if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) {
Expand Down Expand Up @@ -1660,7 +1678,8 @@ export class LuaTransformer {
const right = this.transformExpression(expression.right);
return this.createImmediatelyInvokedFunctionExpression(
[this.transformAssignment(expression.left, right)],
left
left,
expression
);
}
}
Expand Down Expand Up @@ -1721,7 +1740,8 @@ export class LuaTransformer {
// return ____TS_tmp
return this.createImmediatelyInvokedFunctionExpression(
[objAndIndexDeclaration, tmpDeclaration, assignStatement],
tmp
tmp,
lhs.parent
);

} else if (isPostfix) {
Expand All @@ -1738,7 +1758,11 @@ export class LuaTransformer {
replacementOperator
);
const assignStatement = this.transformAssignment(lhs, operatorExpression);
return this.createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier);
return this.createImmediatelyInvokedFunctionExpression(
[tmpDeclaration, assignStatement],
tmpIdentifier,
lhs.parent
);

} else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) {
// Simple property/element access expressions need to cache in temp to avoid double-evaluation
Expand All @@ -1749,14 +1773,18 @@ export class LuaTransformer {
const operatorExpression = this.transformBinaryOperation(lhs.parent, left, right, replacementOperator);
const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, operatorExpression);
const assignStatement = this.transformAssignment(lhs, tmpIdentifier);
return this.createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier);
return this.createImmediatelyInvokedFunctionExpression(
[tmpDeclaration, assignStatement],
tmpIdentifier,
lhs.parent
);

} else {
// Simple expressions
// ${left} = ${right}; return ${right}
const operatorExpression = this.transformBinaryOperation(lhs.parent, left, right, replacementOperator);
const assignStatement = this.transformAssignment(lhs, operatorExpression);
return this.createImmediatelyInvokedFunctionExpression([assignStatement], left);
return this.createImmediatelyInvokedFunctionExpression([assignStatement], left, lhs.parent);
}
}

Expand Down Expand Up @@ -2030,6 +2058,22 @@ export class LuaTransformer {
return tstl.createTableExpression(properties, undefined, node);
}

public transformDeleteExpression(expression: ts.DeleteExpression): tstl.CallExpression {
const lhs = this.transformExpression(expression.expression) as tstl.IdentifierOrTableIndexExpression;
const assignment = tstl.createAssignmentStatement(
lhs,
tstl.createNilLiteral(),
undefined,
expression
);

return this.createImmediatelyInvokedFunctionExpression(
[assignment],
[tstl.createBooleanLiteral(true)],
expression
);
}

public transformFunctionExpression(
node: ts.FunctionLikeDeclaration,
context: tstl.Identifier | undefined
Expand Down Expand Up @@ -2275,7 +2319,7 @@ export class LuaTransformer {
const selfAssignment = this.createLocalOrGlobalDeclaration(selfIdentifier, context);
const index = tstl.createTableIndexExpression(selfIdentifier, argument);
const callExpression = tstl.createCallExpression(index, parameters);
return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression);
return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node);
} else {
return tstl.createCallExpression(this.transformExpression(node.expression), [context, ...parameters]);
}
Expand Down Expand Up @@ -2792,13 +2836,14 @@ export class LuaTransformer {

public createImmediatelyInvokedFunctionExpression(
statements: tstl.Statement[],
result: tstl.Expression | tstl.Expression[]
result: tstl.Expression | tstl.Expression[],
tsOriginal: ts.Node
): tstl.CallExpression
{
const body = statements ? statements.slice(0) : [];
body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result]));
const iife = tstl.createFunctionExpression(tstl.createBlock(body));
return tstl.createCallExpression(tstl.createParenthesizedExpression(iife));
return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], undefined, tsOriginal);
}

public createUnpackCall(expression: tstl.Expression): tstl.Expression {
Expand Down
39 changes: 39 additions & 0 deletions test/unit/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,43 @@ export class ArrayTests {
const result = util.executeLua(lua);
Expect(result).toBe(expected);
}

@Test("Array delete")
public arrayDelete(): void {
const lua = util.transpileString(
`const myarray = [1,2,3,4];
delete myarray[2];
return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`
);

const result = util.executeLua(lua);

Expect(result).toBe("1,2,nil,4");
}

@Test("Array delete return true")
public arrayDeleteReturnTrue(): void {
const lua = util.transpileString(
`const myarray = [1,2,3,4];
const exists = delete myarray[2];
return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`
);

const result = util.executeLua(lua);

Expect(result).toBe("true:1,2,nil,4");
}

@Test("Array delete return false")
public arrayDeleteReturnFalse(): void {
const lua = util.transpileString(
`const myarray = [1,2,3,4];
const exists = delete myarray[4];
return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`
);

const result = util.executeLua(lua);

Expect(result).toBe("true:1,2,3,4");
}
}
16 changes: 1 addition & 15 deletions test/unit/curry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,10 @@ import * as util from "../src/util";

export class LuaCurryTests {

@Test("currying")
public currying() {
// Transpile
const lua = util.transpileString(
`(x: number) => (y: number) => x + y;`
);
// Assert
Expect(lua).toBe(`function (x)
return function(y)
return x + y
end
end;`);
}

@Test("curryingAdd")
@TestCase(2, 3)
@TestCase(5, 4)
public curryingAdd(x: number, y: number) {
public curryingAdd(x: number, y: number): void {
// Transpile
const lua = util.transpileString(
`let add = (x: number) => (y: number) => x + y;
Expand Down
4 changes: 2 additions & 2 deletions test/unit/expressions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class ExpressionTests {
@TestCase("--i", "i = i - 1;")
@TestCase("!a", "not a;")
@TestCase("-a", "-a;")
@TestCase("delete tbl['test']", "tbl[\"test\"]=nil;")
@TestCase("delete tbl.test", "tbl.test=nil;")
@TestCase("delete tbl['test']", "(function ()\n tbl.test = nil;\n return ;\nend)();")
@TestCase("delete tbl.test", "(function ()\n tbl.test = nil;\n return ;\nend)();")
@Test("Unary expressions basic")
public unaryBasic(input: string, lua: string): void {
Expect(util.transpileString(input)).toBe(lua);
Expand Down
2 changes: 1 addition & 1 deletion test/unit/functions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Expect, Test, TestCase } from "alsatian";
import { Expect, Test, TestCase, FocusTest } from "alsatian";

import * as ts from "typescript";
import * as util from "../src/util";
Expand Down