Skip to content

Commit 03beabb

Browse files
authored
Classes update (#383)
* update to class transpilation - classes separated into static and instance tables - fixed issues with super calls - renamed new and constructor to avoid name collisions - added errors for extensions being used in inappropriate ways * added cloneIdentifier ...and using it to prevent the same nodes being referenced from different places in the lua ast * reverted ____new back to new and added new and self to banned identifier list * spacing sanity * fixed bug introduced in merge
1 parent ed87cb6 commit 03beabb

19 files changed

+472
-196
lines changed

src/LuaAST.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,10 @@ export function createIdentifier(
813813
return expression;
814814
}
815815

816+
export function cloneIdentifier(identifier: Identifier): Identifier {
817+
return createIdentifier(identifier.text, undefined, identifier.symbolId);
818+
}
819+
816820
export function createAnnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier {
817821
const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier;
818822
expression.text = "____";

src/LuaTransformer.ts

Lines changed: 236 additions & 131 deletions
Large diffs are not rendered by default.

src/TSTLErrors.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,19 @@ export class TSTLErrors {
2525
new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node);
2626

2727
public static InvalidExtensionMetaExtension = (node: ts.Node) =>
28-
new TranspileError(`Cannot use both '!Extension' and '!MetaExtension' decorators on the same class.`, node);
28+
new TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node);
2929

3030
public static InvalidNewExpressionOnExtension = (node: ts.Node) =>
31-
new TranspileError(`Cannot construct classes with decorator '!Extension' or '!MetaExtension'.`, node);
31+
new TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node);
32+
33+
public static InvalidExtendsExtension = (node: ts.Node) =>
34+
new TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node);
35+
36+
public static InvalidExportsExtension = (node: ts.Node) =>
37+
new TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node);
38+
39+
public static InvalidInstanceOfExtension = (node: ts.Node) =>
40+
new TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node);
3241

3342
public static InvalidPropertyCall = (node: ts.Node) =>
3443
new TranspileError(`Tried to transpile a non-property call as property call.`, node);

src/lualib/InstanceOf.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
interface LuaClass {
2-
__index: LuaClass;
3-
__base: LuaClass;
2+
____super?: LuaClass;
43
}
54

6-
function __TS__InstanceOf(obj: LuaClass, classTbl: LuaClass): boolean {
7-
while (obj !== undefined) {
8-
if (obj.__index === classTbl) {
9-
return true;
5+
interface LuaObject {
6+
constructor: LuaClass;
7+
}
8+
9+
function __TS__InstanceOf(obj: LuaObject, classTbl: LuaClass): boolean {
10+
if (obj !== undefined) {
11+
let luaClass = obj.constructor;
12+
while (luaClass !== undefined) {
13+
if (luaClass === classTbl) {
14+
return true;
15+
}
16+
luaClass = luaClass.____super;
1017
}
11-
obj = obj.__base;
1218
}
1319
return false;
1420
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
MyClass.myFunction = function(self)
1+
MyClass.prototype.myFunction = function(self)
22
end;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
TestClass.myFunction = function(self)
1+
TestClass.prototype.myFunction = function(self)
22
end;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
RenamedTestClass.myFunction = function(self)
1+
RenamedTestClass.prototype.myFunction = function(self)
22
end;
3-
RenamedMyClass.myFunction = function(self)
3+
RenamedMyClass.prototype.myFunction = function(self)
44
end;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
MyClass.test = "test";
22
MyClass.testP = "testP";
3-
MyClass.myFunction = function(self)
3+
MyClass.prototype.myFunction = function(self)
44
end;
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
ClassB = ClassB or {};
22
ClassB.__index = ClassB;
3-
ClassB.new = function(construct, ...)
4-
local self = setmetatable({}, ClassB);
5-
if construct and ClassB.constructor then
6-
ClassB.constructor(self, ...);
7-
end
3+
ClassB.prototype = ClassB.prototype or {};
4+
ClassB.prototype.__index = ClassB.prototype;
5+
ClassB.prototype.constructor = ClassB;
6+
ClassB.new = function(...)
7+
local self = setmetatable({}, ClassB.prototype);
8+
self:____constructor(...);
89
return self;
910
end;
10-
ClassB.constructor = function(self)
11+
ClassB.prototype.____constructor = function(self)
1112
end;
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
MyClass = MyClass or {};
22
MyClass.__index = MyClass;
3-
MyClass.new = function(construct, ...)
4-
local self = setmetatable({}, MyClass);
5-
if construct and MyClass.constructor then
6-
MyClass.constructor(self, ...);
7-
end
3+
MyClass.prototype = MyClass.prototype or {};
4+
MyClass.prototype.__index = MyClass.prototype;
5+
MyClass.prototype.constructor = MyClass;
6+
MyClass.new = function(...)
7+
local self = setmetatable({}, MyClass.prototype);
8+
self:____constructor(...);
89
return self;
910
end;
10-
MyClass.constructor = function(self)
11+
MyClass.prototype.____constructor = function(self)
1112
end;
12-
MyClass.get__field = function(self)
13+
MyClass.prototype.get__field = function(self)
1314
return self._field + 4;
1415
end;
15-
MyClass.set__field = function(self, v)
16+
MyClass.prototype.set__field = function(self, v)
1617
self._field = v * 2;
1718
end;
18-
local instance = MyClass.new(true);
19+
local instance = MyClass.new();
1920
instance:set__field(4);
2021
local b = instance:get__field();
2122
local c = (4 + instance:get__field()) * 3;

0 commit comments

Comments
 (0)