Skip to content

Commit 9376ea5

Browse files
tomblindPerryvw
authored andcommitted
Fixed referencing named function expressions (#671)
* Fixed referencing named function expressions fixes #669 * checking symbolId against undefined * added some comments
1 parent 781bccf commit 9376ea5

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/LuaTransformer.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,16 +3664,34 @@ export class LuaTransformer {
36643664
flags |= tstl.FunctionExpressionFlags.Inline;
36653665
}
36663666

3667-
const [transformedBody] = this.transformFunctionBody(node.parameters, body, spreadIdentifier);
3667+
const [transformedBody, scope] = this.transformFunctionBody(node.parameters, body, spreadIdentifier);
36683668

3669-
return tstl.createFunctionExpression(
3669+
const functionExpression = tstl.createFunctionExpression(
36703670
tstl.createBlock(transformedBody),
36713671
paramNames,
36723672
dotsLiteral,
36733673
spreadIdentifier,
36743674
flags,
36753675
node
36763676
);
3677+
3678+
//Handle named function expressions which reference themselves
3679+
if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) {
3680+
const symbol = this.checker.getSymbolAtLocation(node.name);
3681+
if (symbol) {
3682+
const symbolId = this.symbolIds.get(symbol);
3683+
//Only wrap if the name is actually referenced inside the function
3684+
if (symbolId !== undefined && scope.referencedSymbols.has(symbolId)) {
3685+
const nameIdentifier = this.transformIdentifier(node.name);
3686+
return this.createImmediatelyInvokedFunctionExpression(
3687+
[tstl.createVariableDeclarationStatement(nameIdentifier, functionExpression)],
3688+
tstl.cloneIdentifier(nameIdentifier)
3689+
);
3690+
}
3691+
}
3692+
}
3693+
3694+
return functionExpression;
36773695
}
36783696

36793697
public transformNewExpression(node: ts.NewExpression): ExpressionVisitResult {
@@ -5111,7 +5129,7 @@ export class LuaTransformer {
51115129
protected createImmediatelyInvokedFunctionExpression(
51125130
statements: tstl.Statement[],
51135131
result: tstl.Expression | tstl.Expression[],
5114-
tsOriginal: ts.Node
5132+
tsOriginal?: ts.Node
51155133
): tstl.CallExpression {
51165134
const body = statements ? statements.slice(0) : [];
51175135
body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result]));

test/unit/functions.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,12 @@ test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => {
610610

611611
expect(util.executeLua(lua)).toBe("ABCD");
612612
});
613+
614+
test("named function expression reference", () => {
615+
const code = `
616+
const y = function x(inp: string) {
617+
return inp + typeof x;
618+
};
619+
return y("foo-");`;
620+
expect(util.transpileAndExecute(code)).toBe("foo-function");
621+
});

0 commit comments

Comments
 (0)