Skip to content

Commit c6159e1

Browse files
andreiraduPerryvw
authored andcommitted
-added support for class expressions (#236)
* -added support for class expressions * -minor refactor * -test for base class method calling when using class expression
1 parent 3cb7c4f commit c6159e1

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

src/TSHelper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class TSHelper {
2828
return statements.some(statement => statement.kind === kind);
2929
}
3030

31-
public static getExtendedType(node: ts.ClassDeclaration, checker: ts.TypeChecker): ts.Type | undefined {
31+
public static getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined {
3232
if (node && node.heritageClauses) {
3333
for (const clause of node.heritageClauses) {
3434
if (clause.token === ts.SyntaxKind.ExtendsKeyword) {

src/Transpiler.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,11 @@ export abstract class LuaTranspiler {
807807
return this.transpileSpreadElement(node as ts.SpreadElement);
808808
case ts.SyntaxKind.NonNullExpression:
809809
return this.transpileExpression((node as ts.NonNullExpression).expression);
810+
case ts.SyntaxKind.ClassExpression:
811+
this.namespace.push("");
812+
const classDeclaration = this.transpileClass(node as ts.ClassExpression, "_");
813+
this.namespace.pop();
814+
return `(function() ${classDeclaration}; return _ end)()`;
810815
case ts.SyntaxKind.Block:
811816
this.pushIndent();
812817
const ret = "do \n" + this.transpileBlock(node as ts.Block) + "end\n";
@@ -1615,13 +1620,12 @@ export abstract class LuaTranspiler {
16151620
}
16161621

16171622
// Transpile a class declaration
1618-
public transpileClass(node: ts.ClassDeclaration): string {
1619-
if (!node.name) {
1623+
public transpileClass(node: ts.ClassLikeDeclarationBase, nameOverride?: string): string {
1624+
let className = node.name ? this.transpileIdentifier(node.name) : nameOverride;
1625+
if (!className) {
16201626
throw TSTLErrors.MissingClassName(node);
16211627
}
16221628

1623-
let className = this.transpileIdentifier(node.name);
1624-
16251629
const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(node), this.checker);
16261630

16271631
// Find out if this class is extension of existing class
@@ -1667,7 +1671,7 @@ export abstract class LuaTranspiler {
16671671
}
16681672

16691673
if (!isExtension && !isMetaExtension) {
1670-
result += this.transpileClassCreationMethods(node, instanceFields, extendsType);
1674+
result += this.transpileClassCreationMethods(node, className, instanceFields, extendsType);
16711675
} else {
16721676
for (const f of instanceFields) {
16731677
// Get identifier
@@ -1716,10 +1720,9 @@ export abstract class LuaTranspiler {
17161720
return result;
17171721
}
17181722

1719-
public transpileClassCreationMethods(node: ts.ClassDeclaration, instanceFields: ts.PropertyDeclaration[],
1723+
public transpileClassCreationMethods(node: ts.ClassLikeDeclarationBase, className: string,
1724+
instanceFields: ts.PropertyDeclaration[],
17201725
extendsType: ts.Type): string {
1721-
const className = this.transpileIdentifier(node.name);
1722-
17231726
let noClassOr = false;
17241727
if (extendsType) {
17251728
const decorators = tsHelper.getCustomDecorators(extendsType, this.checker);

test/unit/class.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,4 +466,47 @@ export class ClassTests {
466466
// Assert
467467
Expect(result).toBe(10);
468468
}
469+
@Test("classExpression")
470+
public classExpression(): void {
471+
const lua = util.transpileString(
472+
`class a {
473+
public method() {
474+
return "instance of a";
475+
}
476+
}
477+
b = class extends a {
478+
public method() {
479+
return "instance of b";
480+
}
481+
}
482+
let inst = new b(6);
483+
return inst.method();`
484+
);
485+
486+
// Execute
487+
const result = util.executeLua(lua);
488+
489+
// Assert
490+
Expect(result).toBe("instance of b");
491+
}
492+
@Test("classExpressionBaseClassMethod")
493+
public classExpressionBaseClassMethod(): void {
494+
const lua = util.transpileString(
495+
`class a {
496+
public method() {
497+
return 42;
498+
}
499+
}
500+
b = class extends a {
501+
}
502+
let inst = new b();
503+
return inst.method();`
504+
);
505+
506+
// Execute
507+
const result = util.executeLua(lua);
508+
509+
// Assert
510+
Expect(result).toBe(42);
511+
}
469512
}

0 commit comments

Comments
 (0)