X Tutup
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
73 changes: 49 additions & 24 deletions src/LuaTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3027,12 +3027,7 @@ export class LuaTransformer {
indexExpression = tstl.createStringLiteral(expression.left.name.text);
} else {
// Element access
indexExpression = this.transformExpression(expression.left.argumentExpression);
const argType = this.checker.getTypeAtLocation(expression.left.expression);
if (tsHelper.isArrayType(argType, this.checker, this.program)) {
// Array access needs a +1
indexExpression = this.expressionPlusOne(indexExpression);
}
indexExpression = this.transformElementAccessArgument(expression.left);
}

const args = [objExpression, indexExpression, this.transformExpression(expression.right)];
Expand Down Expand Up @@ -3831,7 +3826,10 @@ export class LuaTransformer {
);
} else {
const parameters = this.transformArguments(node.arguments, signature);
const table = this.transformExpression(node.expression.expression);
let table = this.transformExpression(node.expression.expression);
if (tstl.isTableExpression(table)) {
table = tstl.createParenthesizedExpression(table);
}
const signatureDeclaration = signature && signature.getDeclaration();
if (
!signatureDeclaration ||
Expand Down Expand Up @@ -3868,7 +3866,10 @@ export class LuaTransformer {
return this.transformContextualCallExpression(node, parameters);
} else {
// No context
const expression = this.transformExpression(node.expression);
let expression = this.transformExpression(node.expression);
if (tstl.isTableExpression(expression)) {
expression = tstl.createParenthesizedExpression(expression);
}
return tstl.createCallExpression(expression, parameters);
}
}
Expand All @@ -3885,7 +3886,10 @@ export class LuaTransformer {
tsHelper.isValidLuaIdentifier(left.name.text)
) {
// table:name()
const table = this.transformExpression(left.expression);
let table = this.transformExpression(left.expression);
if (tstl.isTableExpression(table)) {
table = tstl.createParenthesizedExpression(table);
}
return tstl.createMethodCallExpression(
table,
this.transformIdentifier(left.name),
Expand All @@ -3900,10 +3904,9 @@ export class LuaTransformer {

// Cache left-side if it has effects
//(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)()
const argumentExpression = ts.isElementAccessExpression(left)
? left.argumentExpression
: ts.createStringLiteral(left.name.text);
const argument = this.transformExpression(argumentExpression);
const argument = ts.isElementAccessExpression(left)
? this.transformElementAccessArgument(left)
: tstl.createStringLiteral(left.name.text);
const selfIdentifier = tstl.createIdentifier("____TS_self");
const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context);
const index = tstl.createTableIndexExpression(selfIdentifier, argument);
Expand Down Expand Up @@ -3993,7 +3996,10 @@ export class LuaTransformer {
}
}

const callPath = this.transformExpression(expression.expression);
let callPath = this.transformExpression(expression.expression);
if (tstl.isTableExpression(callPath)) {
callPath = tstl.createParenthesizedExpression(callPath);
}
return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression);
}

Expand Down Expand Up @@ -4097,7 +4103,10 @@ export class LuaTransformer {
protected transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression {
switch (node.name.escapedText) {
case "length":
const expression = this.transformExpression(node.expression);
let expression = this.transformExpression(node.expression);
if (ts.isTemplateExpression(node.expression)) {
expression = tstl.createParenthesizedExpression(expression);
}
return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node);
default:
throw TSTLErrors.UnsupportedProperty("string", node.name.escapedText as string, node);
Expand All @@ -4108,7 +4117,10 @@ export class LuaTransformer {
protected transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined {
switch (node.name.escapedText) {
case "length":
const expression = this.transformExpression(node.expression);
let expression = this.transformExpression(node.expression);
if (tstl.isTableExpression(expression)) {
expression = tstl.createParenthesizedExpression(expression);
}
return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node);
default:
return undefined;
Expand All @@ -4125,27 +4137,40 @@ export class LuaTransformer {
}
}

public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult {
const table = this.transformExpression(expression.expression);
protected transformElementAccessArgument(expression: ts.ElementAccessExpression): tstl.Expression {
const index = this.transformExpression(expression.argumentExpression);
const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression);
const type = this.checker.getTypeAtLocation(expression.expression);
if (tsHelper.isNumberType(argumentType) && tsHelper.isArrayType(type, this.checker, this.program)) {
return this.expressionPlusOne(index);
} else {
return index;
}
}

public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult {
let table = this.transformExpression(expression.expression);
if (tstl.isTableExpression(table)) {
table = tstl.createParenthesizedExpression(table);
}

const constEnumValue = this.tryGetConstEnumValue(expression);
if (constEnumValue) {
return constEnumValue;
}

const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression);
const type = this.checker.getTypeAtLocation(expression.expression);
if (tsHelper.isArrayType(type, this.checker, this.program)) {
return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), expression);
} else if (tsHelper.isStringType(type)) {
if (tsHelper.isNumberType(argumentType) && tsHelper.isStringType(type)) {
const index = this.transformExpression(expression.argumentExpression);
return tstl.createCallExpression(
tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")),
[table, this.expressionPlusOne(index), this.expressionPlusOne(index)],
expression
);
} else {
return tstl.createTableIndexExpression(table, index, expression);
}

return tstl.createTableIndexExpression(table, this.transformElementAccessArgument(expression), expression);
}

private tryGetConstEnumValue(
Expand Down Expand Up @@ -4278,7 +4303,7 @@ export class LuaTransformer {
case "upper":
// Allow lua's string instance methods
let stringVariable = this.transformExpression(expression.expression);
if (ts.isStringLiteral(expression.expression)) {
if (ts.isStringLiteralLike(expression.expression)) {
// "foo":method() needs to be ("foo"):method()
stringVariable = tstl.createParenthesizedExpression(stringVariable);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lualib/ArrayIndexOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function __TS__ArrayIndexOf<T>(this: void, arr: T[], searchElement: T, fromIndex
return -1;
}

let k;
let k: number;
if (n >= 0) {
k = n;
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/lualib/ArraySplice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function __TS__ArraySplice<T>(this: void, list: T[], start: number, deleteCount: number, ...items: T[]): T[] {
const len = list.length;

let actualStart;
let actualStart: number;

if (start < 0) {
actualStart = Math.max(len + start, 0);
Expand Down
16 changes: 16 additions & 0 deletions test/unit/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,19 @@ test("OmittedExpression in Array Binding Assignment Statement", () => {

expect(result).toBe(4);
});

test("array access call", () => {
const code = `
const arr = [() => "foo", () => "bar"];
return arr[1]();`;
expect(util.transpileAndExecute(code)).toBe("bar");
});

test.each([`["foo", "bar"].length`, `["foo", "bar"][0]`, `[() => "foo", () => "bar"][0]()`])(
"array literal property access (%p)",
expression => {
const code = `return ${expression}`;
const expectResult = eval(expression);
expect(util.transpileAndExecute(code)).toBe(expectResult);
}
);
9 changes: 9 additions & 0 deletions test/unit/objectLiteral.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,12 @@ test("undefined as object key", () => {
return foo.undefined;`;
expect(util.transpileAndExecute(code)).toBe("foo");
});

test.each([`({x: "foobar"}.x)`, `({x: "foobar"}["x"])`, `({x: () => "foobar"}.x())`, `({x: () => "foobar"}["x"]())`])(
"object literal property access (%p)",
expression => {
const code = `return ${expression}`;
const expectResult = eval(expression);
expect(util.transpileAndExecute(code)).toBe(expectResult);
}
);
9 changes: 9 additions & 0 deletions test/unit/string.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,12 @@ test.each(padCases)("string.padEnd (%p)", ({ inp, maxLength, fillString }) => {

expect(result).toBe(inp.padEnd(maxLength, fillString));
});

test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`foo${'bar'}`.repeat(2)"])(
"string literal property access (%p)",
expression => {
const code = `return ${expression}`;
const expectResult = eval(expression);
expect(util.transpileAndExecute(code)).toBe(expectResult);
}
);
X Tutup