Skip to content

Commit ac5cfd1

Browse files
authored
Merge pull request #176 from Perryvw/feature/glua-target
Bunch of bugfixes
2 parents 5eeecbd + 2f917a7 commit ac5cfd1

15 files changed

+169
-28
lines changed

src/Compiler.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ function emitFilesAndReportErrors(program: ts.Program): number {
155155
}
156156

157157
export function createTranspiler(checker: ts.TypeChecker,
158-
options: ts.CompilerOptions,
158+
options: CompilerOptions,
159159
sourceFile: ts.SourceFile): LuaTranspiler {
160160
let luaTargetTranspiler: LuaTranspiler;
161-
switch (options.luaTarget) {
161+
const target = options.luaTarget ? options.luaTarget.toLowerCase() : "";
162+
switch (target) {
162163
case LuaTarget.Lua51:
163164
luaTargetTranspiler = new LuaTranspiler51(checker, options, sourceFile);
164165
break;

src/Errors.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export class TSTLErrors {
3434
public static InvalidExtensionMetaExtension = (node: ts.Node) =>
3535
new TranspileError(`Cannot use both '!Extension' and '!MetaExtension' decorators on the same class.`, node)
3636

37+
public static InvalidNewExpressionOnExtension = (node: ts.Node) =>
38+
new TranspileError(`Cannot construct classes with decorator '!Extension' or '!MetaExtension'.`, node)
39+
3740
public static InvalidPropertyCall = (node: ts.Node) =>
3841
new TranspileError(`Tried to transpile a non-property call as property call.`, node)
3942

src/Transpiler.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export enum LuaTarget {
1515
Lua51 = "5.1",
1616
Lua52 = "5.2",
1717
Lua53 = "5.3",
18-
LuaJIT = "JIT",
18+
LuaJIT = "jit",
1919
}
2020

2121
export enum LuaLibFeature {
22+
ArrayConcat = "ArrayConcat",
2223
ArrayEvery = "ArrayEvery",
2324
ArrayFilter = "ArrayFilter",
2425
ArrayForEach = "ArrayForEach",
@@ -315,14 +316,25 @@ export abstract class LuaTranspiler {
315316

316317
const imports = node.importClause.namedBindings;
317318

319+
const requireKeyword = "require";
320+
318321
if (ts.isNamedImports(imports)) {
319322
const fileImportTable = path.basename(importPathWithoutQuotes) + this.importCount;
320323
const resolvedImportPath = this.getImportPath(importPathWithoutQuotes);
321324

322-
let result = `local ${fileImportTable} = require(${resolvedImportPath})\n`;
325+
let result = `local ${fileImportTable} = ${requireKeyword}(${resolvedImportPath})\n`;
323326
this.importCount++;
324327

325-
imports.elements.forEach(element => {
328+
const filteredElements = imports.elements.filter(e => {
329+
const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker);
330+
return !decorators.has(DecoratorKind.Extension) && !decorators.has(DecoratorKind.MetaExtension);
331+
});
332+
333+
if (filteredElements.length === 0) {
334+
return "";
335+
}
336+
337+
filteredElements.forEach(element => {
326338
const nameText = this.transpileIdentifier(element.name);
327339
if (element.propertyName) {
328340
const propertyText = this.transpileIdentifier(element.propertyName);
@@ -335,7 +347,7 @@ export abstract class LuaTranspiler {
335347
return result;
336348
} else if (ts.isNamespaceImport(imports)) {
337349
const resolvedImportPath = this.getImportPath(importPathWithoutQuotes);
338-
return `local ${this.transpileIdentifier(imports.name)} = require(${resolvedImportPath})\n`;
350+
return `local ${this.transpileIdentifier(imports.name)} = ${requireKeyword}(${resolvedImportPath})\n`;
339351
} else {
340352
throw TSTLErrors.UnsupportedImportType(imports);
341353
}
@@ -786,7 +798,9 @@ export abstract class LuaTranspiler {
786798
case ts.SyntaxKind.TypeOfExpression:
787799
return this.transpileTypeOfExpression(node as ts.TypeOfExpression);
788800
case ts.SyntaxKind.EmptyStatement:
789-
return "";
801+
return "";
802+
case ts.SyntaxKind.SpreadElement:
803+
return this.transpileSpreadElement(node as ts.SpreadElement);
790804
default:
791805
throw TSTLErrors.UnsupportedKind("expression", node.kind, node);
792806
}
@@ -1029,6 +1043,10 @@ export abstract class LuaTranspiler {
10291043

10301044
this.checkForLuaLibType(type);
10311045

1046+
if (classDecorators.has(DecoratorKind.Extension) || classDecorators.has(DecoratorKind.MetaExtension)) {
1047+
throw TSTLErrors.InvalidNewExpressionOnExtension(node);
1048+
}
1049+
10321050
if (classDecorators.has(DecoratorKind.CustomConstructor)) {
10331051
const customDecorator = classDecorators.get(DecoratorKind.CustomConstructor);
10341052
if (!customDecorator.args[0]) {
@@ -1186,6 +1204,8 @@ export abstract class LuaTranspiler {
11861204
const caller = this.transpileExpression(expression.expression);
11871205
const expressionName = this.transpileIdentifier(expression.name);
11881206
switch (expressionName) {
1207+
case "concat":
1208+
return this.transpileLuaLibFunction(LuaLibFeature.ArrayConcat, caller, params);
11891209
case "push":
11901210
return this.transpileLuaLibFunction(LuaLibFeature.ArrayPush, caller, params);
11911211
case "pop":
@@ -1236,6 +1256,10 @@ export abstract class LuaTranspiler {
12361256
public transpilePropertyAccessExpression(node: ts.PropertyAccessExpression): string {
12371257
const property = node.name.text;
12381258

1259+
if (tsHelper.hasGetAccessor(node, this.checker)) {
1260+
return this.transpileGetAccessor(node);
1261+
}
1262+
12391263
// Check for primitive types to override
12401264
const type = this.checker.getTypeAtLocation(node.expression);
12411265
switch (type.flags) {
@@ -1245,8 +1269,6 @@ export abstract class LuaTranspiler {
12451269
case ts.TypeFlags.Object:
12461270
if (tsHelper.isArrayType(type, this.checker)) {
12471271
return this.transpileArrayProperty(node);
1248-
} else if (tsHelper.hasGetAccessor(node, this.checker)) {
1249-
return this.transpileGetAccessor(node);
12501272
}
12511273
}
12521274

@@ -1366,6 +1388,10 @@ export abstract class LuaTranspiler {
13661388
return escapedText;
13671389
}
13681390

1391+
public transpileSpreadElement(node: ts.SpreadElement): string {
1392+
return "unpack(" + this.transpileExpression(node.expression) + ")";
1393+
}
1394+
13691395
public transpileArrayBindingElement(name: ts.ArrayBindingElement): string {
13701396
if (ts.isOmittedExpression(name)) {
13711397
return "__";
@@ -1566,13 +1592,6 @@ export abstract class LuaTranspiler {
15661592

15671593
let result = "";
15681594

1569-
if (!isExtension && !isMetaExtension) {
1570-
result += this.transpileClassCreationMethods(node, instanceFields, extendsType);
1571-
} else {
1572-
// export empty table
1573-
this.pushExport(className, node, true);
1574-
}
1575-
15761595
// Overwrite the original className with the class we are overriding for extensions
15771596
if (isMetaExtension) {
15781597
if (!extendsType) {
@@ -1592,6 +1611,20 @@ export abstract class LuaTranspiler {
15921611
}
15931612
}
15941613

1614+
if (!isExtension && !isMetaExtension) {
1615+
result += this.transpileClassCreationMethods(node, instanceFields, extendsType);
1616+
} else {
1617+
for (const f of instanceFields) {
1618+
// Get identifier
1619+
const fieldIdentifier = f.name as ts.Identifier;
1620+
const fieldName = this.transpileIdentifier(fieldIdentifier);
1621+
1622+
const value = this.transpileExpression(f.initializer);
1623+
1624+
result += this.indent + `${className}.${fieldName} = ${value}\n`;
1625+
}
1626+
}
1627+
15951628
// Add static declarations
15961629
for (const field of staticFields) {
15971630
const fieldName = this.transpileIdentifier(field.name as ts.Identifier);

src/lualib/ArrayConcat.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
declare function pcall(func: () => any): any;
2+
declare function type(val: any): string;
3+
4+
function __TS__ArrayConcat(arr1: any[], ...args: any[]): any[] {
5+
const out: any[] = [];
6+
for (const val of arr1) {
7+
out[out.length] = val;
8+
}
9+
for (const arg of args) {
10+
// Hack because we don't have an isArray function
11+
if (pcall(() => (arg as any[]).length) && type(arg) !== "string") {
12+
const argAsArray = (arg as any[]);
13+
for (const val of argAsArray) {
14+
out[out.length] = val;
15+
}
16+
} else {
17+
out[out.length] = arg;
18+
}
19+
}
20+
21+
return out;
22+
}

src/targets/Transpiler.52.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,9 @@ export class LuaTranspiler52 extends LuaTranspiler51 {
6363
public transpileDestructingAssignmentValue(node: ts.Expression): string {
6464
return `table.unpack(${this.transpileExpression(node)})`;
6565
}
66+
67+
/** @override */
68+
public transpileSpreadElement(node: ts.SpreadElement): string {
69+
return "table.unpack(" + this.transpileExpression(node.expression) + ")";
70+
}
6671
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MyClass.test = "test"
2+
MyClass.testP = "testP"
3+
function MyClass.myFunction(self)
4+
end
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/** !Extension */
22
class MyClass {
3-
myFunction() {}
4-
}
3+
public myFunction() {}
4+
}

test/translation/ts/classExtension2.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ class TestClass {
44

55
/** !Extension */
66
class MyClass extends TestClass {
7-
myFunction() {}
7+
public myFunction() {}
88
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/** !Extension RenamedTestClass */
22
class TestClass {
3-
myFunction() {}
3+
public myFunction() {}
44
}
55

66
/** !Extension RenamedMyClass */
77
class MyClass extends TestClass {
8-
myFunction() {}
8+
public myFunction() {}
99
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/** !Extension */
2+
class MyClass {
3+
public test: string = "test";
4+
private testP: string = "testP";
5+
public myFunction() {}
6+
}

0 commit comments

Comments
 (0)