From 5d6f81242a6ef368cc5ee78cd0b553f5a16dd903 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 8 Feb 2024 22:35:34 +0100 Subject: [PATCH] Only use super descriptor functions when dealing with propery getters/setters --- src/transformation/visitors/access.ts | 23 ++++++------ .../visitors/binary-expression/assignments.ts | 33 +++++++++-------- test/unit/classes/classes.spec.ts | 36 +++++++++++++++++++ 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index f0f33d871..8004d9f2d 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -182,16 +182,19 @@ export function transformPropertyAccessExpressionWithCapture( }; } if (node.expression.kind === SyntaxKind.SuperKeyword) { - return { - expression: transformLuaLibFunction( - context, - LuaLibFeature.DescriptorGet, - node, - lua.createIdentifier("self"), - table, - lua.createStringLiteral(property) - ), - }; + const symbol = context.checker.getSymbolAtLocation(node); + if (symbol && symbol.flags & ts.SymbolFlags.GetAccessor) { + return { + expression: transformLuaLibFunction( + context, + LuaLibFeature.DescriptorGet, + node, + lua.createIdentifier("self"), + table, + lua.createStringLiteral(property) + ), + }; + } } return { expression: lua.createTableIndexExpression(table, lua.createStringLiteral(property), node) }; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 87b2ff4d4..3e246c3f8 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -78,21 +78,24 @@ export function transformAssignment( if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { if (lhs.expression.kind === SyntaxKind.SuperKeyword) { - return [ - lua.createExpressionStatement( - transformLuaLibFunction( - context, - LuaLibFeature.DescriptorSet, - parent, - lua.createIdentifier("self"), - context.transformExpression(lhs.expression), - ts.isPropertyAccessExpression(lhs) - ? lua.createStringLiteral(lhs.name.text) - : context.transformExpression(lhs.argumentExpression), - right - ) - ), - ]; + const symbol = context.checker.getSymbolAtLocation(lhs); + if (symbol && symbol.flags & ts.SymbolFlags.SetAccessor) { + return [ + lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.DescriptorSet, + parent, + lua.createIdentifier("self"), + context.transformExpression(lhs.expression), + ts.isPropertyAccessExpression(lhs) + ? lua.createStringLiteral(lhs.name.text) + : context.transformExpression(lhs.argumentExpression), + right + ) + ), + ]; + } } } diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index a93177c88..25399c833 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -852,3 +852,39 @@ test("Calling static inherited functions works (#1504)", () => { return B.Get(); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1537 +test("get inherted __index member from super (DotA 2 inheritance) (#1537)", () => { + util.testFunction` + // Inherit 'connected' class + class C extends Connected { + bar() { + return super.foo(); + } + } + + return new C().bar();` + .setTsHeader( + `interface I { + foo(): string; + } + + // Hacky interface/class merging + interface Connected extends I {} + class Connected {} + + declare function setmetatable(this: void, t: any, mt: any); + + const A = { + foo() { + return "foo"; + } + }; + + // Connect class 'Connected' to 'traditional' class A + setmetatable(Connected.prototype, { + __index: A + });` + ) + .expectToEqual("foo"); +});