From 8388918857f34572f79d5edc83d03f489bff5885 Mon Sep 17 00:00:00 2001 From: Lolleko Date: Thu, 7 Jun 2018 14:50:52 +0200 Subject: [PATCH 1/5] Intial Split --- src/Compiler.ts | 38 +++++++- src/Transpiler.ts | 164 +++++++++------------------------- src/targets/Transpiler.51.ts | 7 ++ src/targets/Transpiler.52.ts | 7 ++ src/targets/Transpiler.53.ts | 43 +++++++++ src/targets/Transpiler.JIT.ts | 51 +++++++++++ test/src/util.ts | 9 +- test/unit/expressions.spec.ts | 2 +- 8 files changed, 191 insertions(+), 130 deletions(-) create mode 100644 src/targets/Transpiler.51.ts create mode 100644 src/targets/Transpiler.52.ts create mode 100644 src/targets/Transpiler.53.ts create mode 100644 src/targets/Transpiler.JIT.ts diff --git a/src/Compiler.ts b/src/Compiler.ts index d6b419025..c2be90e9d 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -5,10 +5,18 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, parseCommandLine } from "./CommandLineParser"; -import { LuaTranspiler, TranspileError } from "./Transpiler"; +import { LuaTranspiler51 } from "./targets/Transpiler.51"; +import { LuaTranspiler52 } from "./targets/Transpiler.52"; +import { LuaTranspiler53 } from "./targets/Transpiler.53"; +import { LuaTranspilerJIT } from "./targets/Transpiler.JIT"; +import { LuaTarget, LuaTranspiler, TranspileError } from "./Transpiler"; import { TSHelper as tsEx } from "./TSHelper"; export function compile(fileNames: string[], options: CompilerOptions): void { + if (!options.luaTarget) { + options.luaTarget = LuaTarget.LuaJIT; + } + const program = ts.createProgram(fileNames, options); const checker = program.getTypeChecker(); @@ -41,7 +49,7 @@ export function compile(fileNames: string[], options: CompilerOptions): void { const rootDir = options.rootDir; // Transpile AST - const lua = LuaTranspiler.transpileSourceFile(sourceFile, checker, options); + const lua = transpileSourceFile(checker, options, sourceFile); let outPath = sourceFile.fileName; if (options.outDir !== options.rootDir) { @@ -90,6 +98,32 @@ export function compile(fileNames: string[], options: CompilerOptions): void { ); } +export function transpileSourceFile(checker: ts.TypeChecker, + options: ts.CompilerOptions, + sourceFile: ts.SourceFile): string { + let luaTargetTranspiler: LuaTranspiler; + switch (options.luaTarget) { + case LuaTarget.LuaJIT: + luaTargetTranspiler = new LuaTranspilerJIT(checker, options, sourceFile); + break; + case LuaTarget.Lua51: + luaTargetTranspiler = new LuaTranspiler51(checker, options, sourceFile); + break; + case LuaTarget.Lua52: + luaTargetTranspiler = new LuaTranspiler52(checker, options, sourceFile); + break; + case LuaTarget.Lua53: + luaTargetTranspiler = new LuaTranspiler53(checker, options, sourceFile); + break; + default: + throw Error("LEL"); + } + + const lua = luaTargetTranspiler.transpileSourceFile(); + + return lua; +} + export function execCommandLine(argv?: string[]) { argv = argv ? argv : process.argv.slice(2); const commandLine = parseCommandLine(argv); diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 0d28ebba2..d49e7ac6e 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -18,6 +18,8 @@ export class TranspileError extends Error { } export enum LuaTarget { + Lua51 = "5.1", + Lua52 = "5.2", Lua53 = "5.3", LuaJIT = "JIT", } @@ -25,33 +27,6 @@ export enum LuaTarget { export class LuaTranspiler { public static AvailableLuaTargets = [LuaTarget.LuaJIT, LuaTarget.Lua53]; - // Transpile a source file - public static transpileSourceFile(node: ts.SourceFile, - checker: ts.TypeChecker, - options: CompilerOptions): string { - const transpiler = new LuaTranspiler(checker, options, node); - - let header = ""; - if (options.addHeader) { - header = "-- Generated by TypescriptToLua v" + packageJSON.version + "\n" + - "-- https://github.com/Perryvw/TypescriptToLua\n"; - } - let result = header; - if (!options.dontRequireLuaLib) { - // require helper functions - result += `require("typescript_lualib")\n`; - } - if (transpiler.isModule) { - // Shadow exports if it already exists - result += "local exports = exports or {}\n"; - } - result += transpiler.transpileBlock(node); - if (transpiler.isModule) { - result += "return exports\n"; - } - return result; - } - public indent: string; public checker: ts.TypeChecker; public options: ts.CompilerOptions; @@ -130,6 +105,29 @@ export class LuaTranspiler { return `"${relativePath.replace(new RegExp("\\\\|\/", "g"), ".")}"`; } + // Transpile a source file + public transpileSourceFile(): string { + let header = ""; + if (this.options.addHeader) { + header = "-- Generated by TypescriptToLua v" + packageJSON.version + "\n" + + "-- https://github.com/Perryvw/TypescriptToLua\n"; + } + let result = header; + if (!this.options.dontRequireLuaLib) { + // require helper functions + result += `require("typescript_lualib")\n`; + } + if (this.isModule) { + // Shadow exports if it already exists + result += "local exports = exports or {}\n"; + } + result += this.transpileBlock(this.sourceFile); + if (this.isModule) { + result += "return exports\n"; + } + return result; + } + // Transpile a block public transpileBlock(node: ts.Node): string { let result = ""; @@ -655,102 +653,18 @@ export class LuaTranspiler { let result = ""; // Transpile Bitops - if (this.options.luaTarget === LuaTarget.LuaJIT) { - switch (node.operatorToken.kind) { - case ts.SyntaxKind.AmpersandToken: - result = `bit.band(${lhs},${rhs})`; - break; - case ts.SyntaxKind.AmpersandEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, - `bit.band(${lhs},${rhs})`); - } - result = `${lhs}=bit.band(${lhs},${rhs})`; - break; - case ts.SyntaxKind.BarToken: - result = `bit.bor(${lhs},${rhs})`; - break; - case ts.SyntaxKind.BarEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, - `bit.bor(${lhs},${rhs})`); - } - result = `${lhs}=bit.bor(${lhs},${rhs})`; - break; - case ts.SyntaxKind.LessThanLessThanToken: - result = `bit.lshift(${lhs},${rhs})`; - break; - case ts.SyntaxKind.LessThanLessThanEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, - `bit.lshift(${lhs},${rhs})`); - } - result = `${lhs}=bit.lshift(${lhs},${rhs})`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanToken: - result = `bit.arshift(${lhs},${rhs})`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, - `bit.arshift(${lhs},${rhs})`); - } - result = `${lhs}=bit.arshift(${lhs},${rhs})`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - result = `bit.rshift(${lhs},${rhs})`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, - `bit.rshift(${lhs},${rhs})`); - } - result = `${lhs}=bit.rshift(${lhs},${rhs})`; - break; - } - } else { - switch (node.operatorToken.kind) { - case ts.SyntaxKind.AmpersandToken: - result = `${lhs}&${rhs}`; - break; - case ts.SyntaxKind.AmpersandEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}&${rhs}`); - } - result = `${lhs}=${lhs}&${rhs}`; - break; - case ts.SyntaxKind.BarToken: - result = `${lhs}|${rhs}`; - break; - case ts.SyntaxKind.BarEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}|${rhs}`); - } - result = `${lhs}=${lhs}|${rhs}`; - break; - case ts.SyntaxKind.LessThanLessThanToken: - result = `${lhs}<<${rhs}`; - break; - case ts.SyntaxKind.LessThanLessThanEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}<<${rhs}`); - } - result = `${lhs}=${lhs}<<${rhs}`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanToken: - result = `${lhs}>>${rhs}`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: - if (tsHelper.hasSetAccessor(node.left, this.checker)) { - return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}>>${rhs}`); - } - result = `${lhs}=${lhs}>>${rhs}`; - break; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - throw new TranspileError("Bitwise operator >>> not supported", node); - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - throw new TranspileError("Bitwise operator >>> not supported", node); - } + switch (node.operatorToken.kind) { + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.AmpersandEqualsToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.BarEqualsToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.LessThanLessThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + result = this.transpileBitOperation(node, lhs, rhs); } // Transpile operators @@ -862,6 +776,10 @@ export class LuaTranspiler { } } + public transpileBitOperation(node: ts.BinaryExpression, lhs: string, rhs: string): string { + throw new TranspileError(`Bit Oeprations are not supported in Lua ${this.options.target}`, node); + } + public transpileTemplateExpression(node: ts.TemplateExpression) { const parts = [`"${node.head.text}"`]; node.templateSpans.forEach(span => { diff --git a/src/targets/Transpiler.51.ts b/src/targets/Transpiler.51.ts new file mode 100644 index 000000000..05162471b --- /dev/null +++ b/src/targets/Transpiler.51.ts @@ -0,0 +1,7 @@ +import { LuaTranspiler, TranspileError } from "../Transpiler"; +import { TSHelper as tsHelper } from "../TSHelper"; + +import * as ts from "typescript"; + +export class LuaTranspiler51 extends LuaTranspiler { +} diff --git a/src/targets/Transpiler.52.ts b/src/targets/Transpiler.52.ts new file mode 100644 index 000000000..066f13839 --- /dev/null +++ b/src/targets/Transpiler.52.ts @@ -0,0 +1,7 @@ +import { LuaTranspiler, TranspileError } from "../Transpiler"; +import { TSHelper as tsHelper } from "../TSHelper"; + +import * as ts from "typescript"; + +export class LuaTranspiler52 extends LuaTranspiler { +} diff --git a/src/targets/Transpiler.53.ts b/src/targets/Transpiler.53.ts new file mode 100644 index 000000000..1767c299f --- /dev/null +++ b/src/targets/Transpiler.53.ts @@ -0,0 +1,43 @@ +import { LuaTranspiler, TranspileError } from "../Transpiler"; +import { TSHelper as tsHelper } from "../TSHelper"; + +import * as ts from "typescript"; + +export class LuaTranspiler53 extends LuaTranspiler { + public transpileBitOperation(node: ts.BinaryExpression, lhs: string, rhs: string): string { + switch (node.operatorToken.kind) { + case ts.SyntaxKind.AmpersandToken: + return `${lhs}&${rhs}`; + case ts.SyntaxKind.AmpersandEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}&${rhs}`); + } + return `${lhs}=${lhs}&${rhs}`; + case ts.SyntaxKind.BarToken: + return `${lhs}|${rhs}`; + case ts.SyntaxKind.BarEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}|${rhs}`); + } + return `${lhs}=${lhs}|${rhs}`; + case ts.SyntaxKind.LessThanLessThanToken: + return `${lhs}<<${rhs}`; + case ts.SyntaxKind.LessThanLessThanEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}<<${rhs}`); + } + return `${lhs}=${lhs}<<${rhs}`; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + return `${lhs}>>${rhs}`; + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}>>${rhs}`); + } + return `${lhs}=${lhs}>>${rhs}`; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + throw new TranspileError("Bitwise operator >>> not supported in Lua 5.3", node); + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + throw new TranspileError("Bitwise operator >>> not supported in Lua 5.3", node); + } + } +} diff --git a/src/targets/Transpiler.JIT.ts b/src/targets/Transpiler.JIT.ts new file mode 100644 index 000000000..29dab3827 --- /dev/null +++ b/src/targets/Transpiler.JIT.ts @@ -0,0 +1,51 @@ +import { LuaTranspiler } from "../Transpiler"; +import { TSHelper as tsHelper } from "../TSHelper"; + +import * as ts from "typescript"; + +export class LuaTranspilerJIT extends LuaTranspiler { + public transpileBitOperation(node: ts.BinaryExpression, lhs: string, rhs: string): string { + switch (node.operatorToken.kind) { + case ts.SyntaxKind.AmpersandToken: + return `bit.band(${lhs},${rhs})`; + case ts.SyntaxKind.AmpersandEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, + `bit.band(${lhs},${rhs})`); + } + return `${lhs}=bit.band(${lhs},${rhs})`; + case ts.SyntaxKind.BarToken: + return `bit.bor(${lhs},${rhs})`; + case ts.SyntaxKind.BarEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, + `bit.bor(${lhs},${rhs})`); + } + return `${lhs}=bit.bor(${lhs},${rhs})`; + case ts.SyntaxKind.LessThanLessThanToken: + return `bit.lshift(${lhs},${rhs})`; + case ts.SyntaxKind.LessThanLessThanEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, + `bit.lshift(${lhs},${rhs})`); + } + return `${lhs}=bit.lshift(${lhs},${rhs})`; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + return `bit.arshift(${lhs},${rhs})`; + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, + `bit.arshift(${lhs},${rhs})`); + } + return `${lhs}=bit.arshift(${lhs},${rhs})`; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return `bit.rshift(${lhs},${rhs})`; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + if (tsHelper.hasSetAccessor(node.left, this.checker)) { + return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, + `bit.rshift(${lhs},${rhs})`); + } + return `${lhs}=bit.rshift(${lhs},${rhs})`; + } + } +} diff --git a/test/src/util.ts b/test/src/util.ts index f12ac47b4..1ed9f7388 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -5,6 +5,7 @@ import { Expect } from "alsatian"; import { LuaTarget, LuaTranspiler, TranspileError } from "../../src/Transpiler"; import { CompilerOptions } from "../../src/CommandLineParser"; +import { transpileSourceFile } from "../../src/Compiler"; import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; @@ -40,9 +41,9 @@ export function transpileString(str: string, options: CompilerOptions = { dontRe }; const program = ts.createProgram(["file.ts"], options, compilerHost); - const result = LuaTranspiler.transpileSourceFile(program.getSourceFile("file.ts"), - program.getTypeChecker(), - options); + const result = transpileSourceFile(program.getTypeChecker(), + options, + program.getSourceFile("file.ts")); return result.trim(); } @@ -55,7 +56,7 @@ export function transpileFile(filePath: string): string { diagnostics.forEach(diagnostic => console.log(`${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`)); const options: ts.CompilerOptions = { dontRequireLuaLib: true }; - const result = LuaTranspiler.transpileSourceFile(program.getSourceFile(filePath), checker, options); + const result = transpileSourceFile(checker, options, program.getSourceFile(filePath)); return result.trim(); } diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 95c4ff9cd..9b2988d17 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -126,7 +126,7 @@ export class ExpressionTests { @Test("Unsupported bitop 5.3") public bitOperatorOverride53Unsupported(input: string) { Expect(() => util.transpileString(input, { luaTarget: "5.3", dontRequireLuaLib: true })) - .toThrowError(Error, "Bitwise operator >>> not supported"); + .toThrowError(Error, "Bitwise operator >>> not supported in Lua 5.3"); } @TestCase("1+1", "1+1") From 31c50b32f5bc080eae27c67a906c5e15d6b56e11 Mon Sep 17 00:00:00 2001 From: Lolleko Date: Thu, 7 Jun 2018 15:24:39 +0200 Subject: [PATCH 2/5] Redeclared LuaTranspiler as abstract --- src/Compiler.ts | 15 +++++++-------- src/Transpiler.ts | 2 +- test/src/util.ts | 16 ++++++++-------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Compiler.ts b/src/Compiler.ts index c2be90e9d..510ba8a4c 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -49,7 +49,7 @@ export function compile(fileNames: string[], options: CompilerOptions): void { const rootDir = options.rootDir; // Transpile AST - const lua = transpileSourceFile(checker, options, sourceFile); + const lua = createTranspiler(checker, options, sourceFile).transpileSourceFile(); let outPath = sourceFile.fileName; if (options.outDir !== options.rootDir) { @@ -98,9 +98,9 @@ export function compile(fileNames: string[], options: CompilerOptions): void { ); } -export function transpileSourceFile(checker: ts.TypeChecker, - options: ts.CompilerOptions, - sourceFile: ts.SourceFile): string { +export function createTranspiler(checker: ts.TypeChecker, + options: ts.CompilerOptions, + sourceFile: ts.SourceFile): LuaTranspiler { let luaTargetTranspiler: LuaTranspiler; switch (options.luaTarget) { case LuaTarget.LuaJIT: @@ -116,12 +116,11 @@ export function transpileSourceFile(checker: ts.TypeChecker, luaTargetTranspiler = new LuaTranspiler53(checker, options, sourceFile); break; default: - throw Error("LEL"); + // should not happen + throw Error("No luaTarget Specified please ensure a target is set!"); } - const lua = luaTargetTranspiler.transpileSourceFile(); - - return lua; + return luaTargetTranspiler; } export function execCommandLine(argv?: string[]) { diff --git a/src/Transpiler.ts b/src/Transpiler.ts index d49e7ac6e..dc3d485c4 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -24,7 +24,7 @@ export enum LuaTarget { LuaJIT = "JIT", } -export class LuaTranspiler { +export abstract class LuaTranspiler { public static AvailableLuaTargets = [LuaTarget.LuaJIT, LuaTarget.Lua53]; public indent: string; diff --git a/test/src/util.ts b/test/src/util.ts index 1ed9f7388..ea7f9ebc8 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -5,7 +5,7 @@ import { Expect } from "alsatian"; import { LuaTarget, LuaTranspiler, TranspileError } from "../../src/Transpiler"; import { CompilerOptions } from "../../src/CommandLineParser"; -import { transpileSourceFile } from "../../src/Compiler"; +import { createTranspiler } from "../../src/Compiler"; import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; @@ -41,9 +41,9 @@ export function transpileString(str: string, options: CompilerOptions = { dontRe }; const program = ts.createProgram(["file.ts"], options, compilerHost); - const result = transpileSourceFile(program.getTypeChecker(), - options, - program.getSourceFile("file.ts")); + const result = createTranspiler(program.getTypeChecker(), + options, + program.getSourceFile("file.ts")).transpileSourceFile(); return result.trim(); } @@ -56,7 +56,7 @@ export function transpileFile(filePath: string): string { diagnostics.forEach(diagnostic => console.log(`${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`)); const options: ts.CompilerOptions = { dontRequireLuaLib: true }; - const result = transpileSourceFile(checker, options, program.getSourceFile(filePath)); + const result = createTranspiler(checker, options, program.getSourceFile(filePath)).transpileSourceFile(); return result.trim(); } @@ -105,9 +105,9 @@ export function expectCodeEqual(code1: string, code2: string) { // Get a mock transpiler to use for testing export function makeTestTranspiler(target: LuaTarget = LuaTarget.Lua53) { - return new LuaTranspiler({} as ts.TypeChecker, - { dontRequireLuaLib: true, luaTarget: target } as any, - { statements: [] } as any as ts.SourceFile); + return createTranspiler({} as ts.TypeChecker, + { dontRequireLuaLib: true, luaTarget: target } as any, + { statements: [] } as any as ts.SourceFile); } const tslualib = fs.readFileSync("dist/lualib/typescript.lua") + "\n"; From 9edd0eabdb679322b56b48f26dbfd8ab06049dcd Mon Sep 17 00:00:00 2001 From: Lolleko Date: Thu, 7 Jun 2018 19:52:43 +0200 Subject: [PATCH 3/5] Moved version specific string functions --- src/Transpiler.ts | 16 ++++++---------- src/targets/Transpiler.53.ts | 8 ++++++++ test/unit/expressions.spec.ts | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index dc3d485c4..2d8db7a27 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -933,19 +933,15 @@ export abstract class LuaTranspiler { } } - // Transpile a String._ property - public transpileStringExpression(identifier: ts.Identifier): string { - const translation = { + public getValidStringProperties(): {[js: string]: string} { + return { fromCharCode: "string.char", - fromCodePoint: "utf8.char", }; + } - if (identifier.escapedText as string === "fromCodePoint" && this.options.luaTarget !== LuaTarget.Lua53) { - throw new TranspileError( - `Unsupported string property ${identifier.escapedText} is only supported for lua 5.3.`, - identifier - ); - } + // Transpile a String._ property + public transpileStringExpression(identifier: ts.Identifier): string { + const translation = this.getValidStringProperties(); if (translation[identifier.escapedText as string]) { return `${translation[identifier.escapedText as string]}`; diff --git a/src/targets/Transpiler.53.ts b/src/targets/Transpiler.53.ts index 1767c299f..543ff3a2f 100644 --- a/src/targets/Transpiler.53.ts +++ b/src/targets/Transpiler.53.ts @@ -40,4 +40,12 @@ export class LuaTranspiler53 extends LuaTranspiler { throw new TranspileError("Bitwise operator >>> not supported in Lua 5.3", node); } } + + public getValidStringProperties(): {[js: string]: string} { + return { + fromCharCode: "string.char", + fromCodePoint: "utf8.char", + }; + } + } diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 9b2988d17..887028ab9 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -422,7 +422,7 @@ export class ExpressionTests { const identifier = ts.createIdentifier("fromCodePoint"); Expect(() => transpiler.transpileStringExpression(identifier)) - .toThrowError(Error, "Unsupported string property fromCodePoint is only supported for lua 5.3."); + .toThrowError(Error, "Unsupported string property fromCodePoint."); } @Test("Unknown string expression error") From 6b5ae1659b78a21f45d00d207b29d37144e9f0e4 Mon Sep 17 00:00:00 2001 From: Lolleko Date: Thu, 7 Jun 2018 19:56:12 +0200 Subject: [PATCH 4/5] Improved error message for string properties --- src/Transpiler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 2d8db7a27..5857eb43a 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -946,7 +946,9 @@ export abstract class LuaTranspiler { if (translation[identifier.escapedText as string]) { return `${translation[identifier.escapedText as string]}`; } else { - throw new TranspileError(`Unsupported string property ${identifier.escapedText}.`, identifier); + throw new TranspileError(`Unsupported string property ${identifier.escapedText}, ` + + `is not supported in Lua ${this.options.luaTarget}.`, + identifier); } } From ae4621d64b8e81c57f13177267b1979f78e350ed Mon Sep 17 00:00:00 2001 From: Lolleko Date: Fri, 8 Jun 2018 00:16:55 +0200 Subject: [PATCH 5/5] Changed inheritance & fixed tests --- src/targets/Transpiler.52.ts | 5 +++-- src/targets/Transpiler.53.ts | 6 +++--- src/targets/Transpiler.JIT.ts | 4 ++-- test/unit/expressions.spec.ts | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/targets/Transpiler.52.ts b/src/targets/Transpiler.52.ts index 066f13839..3aff85cef 100644 --- a/src/targets/Transpiler.52.ts +++ b/src/targets/Transpiler.52.ts @@ -1,7 +1,8 @@ -import { LuaTranspiler, TranspileError } from "../Transpiler"; import { TSHelper as tsHelper } from "../TSHelper"; +import { LuaTranspiler51 } from "./Transpiler.51"; import * as ts from "typescript"; -export class LuaTranspiler52 extends LuaTranspiler { +export class LuaTranspiler52 extends LuaTranspiler51 { + } diff --git a/src/targets/Transpiler.53.ts b/src/targets/Transpiler.53.ts index 543ff3a2f..99885f883 100644 --- a/src/targets/Transpiler.53.ts +++ b/src/targets/Transpiler.53.ts @@ -1,9 +1,10 @@ -import { LuaTranspiler, TranspileError } from "../Transpiler"; +import { TranspileError } from "../Transpiler"; import { TSHelper as tsHelper } from "../TSHelper"; +import { LuaTranspiler52 } from "./Transpiler.52"; import * as ts from "typescript"; -export class LuaTranspiler53 extends LuaTranspiler { +export class LuaTranspiler53 extends LuaTranspiler52 { public transpileBitOperation(node: ts.BinaryExpression, lhs: string, rhs: string): string { switch (node.operatorToken.kind) { case ts.SyntaxKind.AmpersandToken: @@ -40,7 +41,6 @@ export class LuaTranspiler53 extends LuaTranspiler { throw new TranspileError("Bitwise operator >>> not supported in Lua 5.3", node); } } - public getValidStringProperties(): {[js: string]: string} { return { fromCharCode: "string.char", diff --git a/src/targets/Transpiler.JIT.ts b/src/targets/Transpiler.JIT.ts index 29dab3827..d80aa4234 100644 --- a/src/targets/Transpiler.JIT.ts +++ b/src/targets/Transpiler.JIT.ts @@ -1,9 +1,9 @@ -import { LuaTranspiler } from "../Transpiler"; import { TSHelper as tsHelper } from "../TSHelper"; +import { LuaTranspiler52 } from "./Transpiler.52"; import * as ts from "typescript"; -export class LuaTranspilerJIT extends LuaTranspiler { +export class LuaTranspilerJIT extends LuaTranspiler52 { public transpileBitOperation(node: ts.BinaryExpression, lhs: string, rhs: string): string { switch (node.operatorToken.kind) { case ts.SyntaxKind.AmpersandToken: diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 887028ab9..e9792dbaf 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -422,7 +422,7 @@ export class ExpressionTests { const identifier = ts.createIdentifier("fromCodePoint"); Expect(() => transpiler.transpileStringExpression(identifier)) - .toThrowError(Error, "Unsupported string property fromCodePoint."); + .toThrowError(Error, "Unsupported string property fromCodePoint, is not supported in Lua JIT."); } @Test("Unknown string expression error") @@ -431,7 +431,7 @@ export class ExpressionTests { const identifier = ts.createIdentifier("abcd"); Expect(() => transpiler.transpileStringExpression(identifier)) - .toThrowError(Error, "Unsupported string property abcd."); + .toThrowError(Error, "Unsupported string property abcd, is not supported in Lua JIT."); } @Test("Unsupported array function error")