From 4899d68f87693f911d4233d65fd6830e9de904a8 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 3 Jun 2018 17:02:35 +0200 Subject: [PATCH 1/4] call functions on object literals with a dot --- src/Transpiler.ts | 3 ++- test/translation/lua/dotColonFunctionCalls.lua | 3 +++ test/translation/ts/dotColonFunctionCalls.ts | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/translation/lua/dotColonFunctionCalls.lua create mode 100644 test/translation/ts/dotColonFunctionCalls.ts diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 3cda3f54e..d2841ec48 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -917,7 +917,8 @@ export class LuaTranspiler { return this.transpileArrayCallExpression(node); } - if (expType.symbol && (expType.symbol.flags & ts.SymbolFlags.Namespace)) { + if (expType.symbol && ((expType.symbol.flags & ts.SymbolFlags.Namespace) + || (expType.symbol.flags & ts.SymbolFlags.TypeLiteral))) { // Don't replace . with : for namespaces callPath = this.transpileExpression(node.expression); params = this.transpileArguments(node.arguments); diff --git a/test/translation/lua/dotColonFunctionCalls.lua b/test/translation/lua/dotColonFunctionCalls.lua new file mode 100644 index 000000000..5061eae73 --- /dev/null +++ b/test/translation/lua/dotColonFunctionCalls.lua @@ -0,0 +1,3 @@ +classInstance:colonMethod() +interfaceInstance:colonMethod() +wrapperObj.dotMethod() diff --git a/test/translation/ts/dotColonFunctionCalls.ts b/test/translation/ts/dotColonFunctionCalls.ts new file mode 100644 index 000000000..12ccd68fc --- /dev/null +++ b/test/translation/ts/dotColonFunctionCalls.ts @@ -0,0 +1,16 @@ +declare class TestClass { + public colonMethod(): void; +} + +declare interface TestInterface { + colonMethod(): void; +} + +declare var wrapperObj: { dotMethod: () => void }; + +declare const classInstance: TestClass; +declare const interfaceInstance: TestInterface; + +classInstance.colonMethod(); +interfaceInstance.colonMethod(); +wrapperObj.dotMethod(); From 543f7a9ad8ab0aa6b566fc289c8eeba269f0a8d8 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 4 Jun 2018 21:38:22 +0200 Subject: [PATCH 2/4] Try transpiling lambda properties as dot methods instead of colon methods --- src/Transpiler.ts | 7 +++++-- test/translation/lua/dotColonFunctionCalls.lua | 5 ++++- test/translation/ts/dotColonFunctionCalls.ts | 12 ++++++++++-- test/unit/assignments.spec.ts | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index d2841ec48..94b7018a3 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -917,9 +917,12 @@ export class LuaTranspiler { return this.transpileArrayCallExpression(node); } - if (expType.symbol && ((expType.symbol.flags & ts.SymbolFlags.Namespace) - || (expType.symbol.flags & ts.SymbolFlags.TypeLiteral))) { + const expType2 = this.checker.getTypeAtLocation(node.expression); + if (expType.symbol && // Don't replace . with : for namespaces + ((expType.symbol.flags & ts.SymbolFlags.Namespace) + // If function is defined as property with lambda type use . instead of : + || (expType2.symbol.flags & ts.SymbolFlags.TypeLiteral))) { callPath = this.transpileExpression(node.expression); params = this.transpileArguments(node.arguments); return `${callPath}(${params})`; diff --git a/test/translation/lua/dotColonFunctionCalls.lua b/test/translation/lua/dotColonFunctionCalls.lua index 5061eae73..a70d2d0f2 100644 --- a/test/translation/lua/dotColonFunctionCalls.lua +++ b/test/translation/lua/dotColonFunctionCalls.lua @@ -1,3 +1,6 @@ classInstance:colonMethod() +classInstance.dotMethod() interfaceInstance:colonMethod() -wrapperObj.dotMethod() +interfaceInstance.dotMethod() +TestNameSpace.dotMethod() +TestNameSpace.dotMethod2() diff --git a/test/translation/ts/dotColonFunctionCalls.ts b/test/translation/ts/dotColonFunctionCalls.ts index 12ccd68fc..19990cd7a 100644 --- a/test/translation/ts/dotColonFunctionCalls.ts +++ b/test/translation/ts/dotColonFunctionCalls.ts @@ -1,16 +1,24 @@ declare class TestClass { + public dotMethod: () => void; public colonMethod(): void; } declare interface TestInterface { + dotMethod: () => void; colonMethod(): void; } -declare var wrapperObj: { dotMethod: () => void }; +declare namespace TestNameSpace { + var dotMethod: () => void; + function dotMethod2(): void; +} declare const classInstance: TestClass; declare const interfaceInstance: TestInterface; classInstance.colonMethod(); +classInstance.dotMethod(); interfaceInstance.colonMethod(); -wrapperObj.dotMethod(); +interfaceInstance.dotMethod(); +TestNameSpace.dotMethod(); +TestNameSpace.dotMethod2(); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index cfb8d6110..2ee62ea8c 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1,4 +1,4 @@ -import { Expect, Test, TestCase, FocusTest } from "alsatian"; +import { Expect, Test, TestCase } from "alsatian"; import { TranspileError } from "../../src/Transpiler"; import * as util from "../src/util"; From 2e39d11ee1f3231f780a531723d3f3578fe45569 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 5 Jun 2018 22:31:40 +0200 Subject: [PATCH 3/4] Cleaned up prototype code --- src/Transpiler.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 94b7018a3..5bcd49b5c 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -895,9 +895,10 @@ export class LuaTranspiler { let params; let callPath; if (ts.isPropertyAccessExpression(node.expression)) { - const expType = this.checker.getTypeAtLocation(node.expression.expression); + // If the function being called is of type owner.func, get the type of owner + const ownerType = this.checker.getTypeAtLocation(node.expression.expression); - if (expType.symbol && expType.symbol.escapedName === "Math") { + if (ownerType.symbol && ownerType.symbol.escapedName === "Math") { params = this.transpileArguments(node.arguments); return this.transpileMathExpression(node.expression.name) + `(${params})`; } @@ -907,22 +908,22 @@ export class LuaTranspiler { return this.transpileStringExpression(node.expression.name) + `(${params})`; } - switch (expType.flags) { + switch (ownerType.flags) { case ts.TypeFlags.String: case ts.TypeFlags.StringLiteral: return this.transpileStringCallExpression(node); } - if (tsHelper.isArrayType(expType, this.checker)) { + if (tsHelper.isArrayType(ownerType, this.checker)) { return this.transpileArrayCallExpression(node); } - const expType2 = this.checker.getTypeAtLocation(node.expression); - if (expType.symbol && - // Don't replace . with : for namespaces - ((expType.symbol.flags & ts.SymbolFlags.Namespace) + // Get the type of the function + const functionType = this.checker.getTypeAtLocation(node.expression); + // Don't replace . with : for namespaces + if ((ownerType.symbol && (ownerType.symbol.flags & ts.SymbolFlags.Namespace)) // If function is defined as property with lambda type use . instead of : - || (expType2.symbol.flags & ts.SymbolFlags.TypeLiteral))) { + || (functionType.symbol && (functionType.symbol.flags & ts.SymbolFlags.TypeLiteral))) { callPath = this.transpileExpression(node.expression); params = this.transpileArguments(node.arguments); return `${callPath}(${params})`; From 2b0f59b432db871c8b07fb0639ea3200dedfef69 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 6 Jun 2018 22:07:43 +0200 Subject: [PATCH 4/4] Added unit tests for dot methods --- test/unit/expressions.spec.ts | 98 +++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 311de04d6..95c4ff9cd 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -288,6 +288,104 @@ export class ExpressionTests { Expect(result).toBe(expected); } + @Test("Class method call") + public classMethod() { + const returnValue = 4; + const source = `class TestClass { + public classMethod(): number { return ${returnValue}; } + } + + const classInstance = new TestClass(); + return classInstance.classMethod();`; + + // Transpile + const lua = util.transpileString(source); + + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(returnValue); + } + + @Test("Class dot method call void") + public classDotMethod() { + const returnValue = 4; + const source = `class TestClass { + public dotMethod: () => number = () => ${returnValue}; + } + + const classInstance = new TestClass(); + return classInstance.dotMethod();`; + + // Transpile + const lua = util.transpileString(source); + + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(returnValue); + } + + @Test("Class dot method call with parameter") + public classDotMethod2() { + const returnValue = 4; + const source = `class TestClass { + public dotMethod: (x: number) => number = x => 3 * x; + } + + const classInstance = new TestClass(); + return classInstance.dotMethod(${returnValue});`; + + // Transpile + const lua = util.transpileString(source); + + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(3 * returnValue); + } + + @Test("Class static dot method") + public classDotMethodStatic() { + const returnValue = 4; + const source = `class TestClass { + public static dotMethod: () => number = () => ${returnValue}; + } + + return TestClass.dotMethod();`; + + // Transpile + const lua = util.transpileString(source); + + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(returnValue); + } + + @Test("Class static dot method with parameter") + public classDotMethodStaticWithParameter() { + const returnValue = 4; + const source = `class TestClass { + public static dotMethod: (x: number) => number = x => 3 * x; + } + + return TestClass.dotMethod(${returnValue});`; + + // Transpile + const lua = util.transpileString(source); + + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(3 * returnValue); + } + // ==================================== // Test expected errors // ====================================