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
25 changes: 25 additions & 0 deletions src/transpilation/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function getTransformers(

...(transformersFromOptions.after ?? []),
...(customTransformers.after ?? []),
stripParenthesisExpressionsTransformer,
luaTransformer,
],
};
Expand All @@ -53,6 +54,30 @@ export const noImplicitSelfTransformer: ts.TransformerFactory<ts.SourceFile | ts
: transformSourceFile(node);
};

export const stripParenthesisExpressionsTransformer: ts.TransformerFactory<ts.SourceFile> = context => sourceFile => {
// Remove parenthesis expressions before transforming to Lua, so transpiler is not hindered by extra ParenthesizedExpression nodes
function unwrapParentheses(node: ts.Expression) {
while (ts.isParenthesizedExpression(node)) {
node = node.expression;
}
return node;
}
function visit(node: ts.Node): ts.Node {
// For now only call expressions strip their expressions of parentheses, there could be more cases where this is required
if (ts.isCallExpression(node)) {
return ts.factory.updateCallExpression(
node,
unwrapParentheses(node.expression),
node.typeArguments,
node.arguments
);
}

return ts.visitEachChild(node, visit, context);
}
return ts.visitNode(sourceFile, visit);
};

function loadTransformersFromOptions(program: ts.Program, diagnostics: ts.Diagnostic[]): ts.CustomTransformers {
const customTransformers: Required<ts.CustomTransformers> = {
before: [],
Expand Down
38 changes: 38 additions & 0 deletions test/unit/classes/classes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -761,3 +761,41 @@ test("constructor class name available with constructor", () => {
.setReturnExport("className")
.expectToEqual("MyClass");
});

// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959
test("methods accessed via this index pass correct context", () => {
util.testModule`
class Example {
baz = 3;
foo() {
this["bar"]()
}

bar() {
return this.baz;
}
}

const inst = new Example();
export const result = inst.foo();
`.expectToMatchJsResult();
});

// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959
test.each(['(this["bar"])', '((((this["bar"]))))'])("methods in parentheses pass correct context %s", callPath => {
util.testModule`
class Example {
baz = 3;
foo() {
${callPath}()
}

bar() {
return this.baz;
}
}

const inst = new Example();
export const result = inst.foo();
`.expectToMatchJsResult();
});