Skip to content

Commit 826887b

Browse files
committed
Get and set accessors implementation
1 parent acf4ee0 commit 826887b

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

src/TSHelper.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,30 @@ export class TSHelper {
108108
}
109109
return null;
110110
}
111+
112+
public static hasGetAccessor(node: ts.Node, checker: ts.TypeChecker): boolean {
113+
if (ts.isPropertyAccessExpression(node)) {
114+
const name = node.name.escapedText;
115+
const type = checker.getTypeAtLocation(node.expression);
116+
117+
if (type && type.symbol && type.symbol.members) {
118+
const field = type.symbol.members.get(name);
119+
return field && (field.flags & ts.SymbolFlags.GetAccessor) !== 0;
120+
}
121+
}
122+
return false;
123+
}
124+
125+
public static hasSetAccessor(node: ts.Node, checker: ts.TypeChecker): boolean {
126+
if (ts.isPropertyAccessExpression(node)) {
127+
const name = node.name.escapedText;
128+
const type = checker.getTypeAtLocation(node.expression);
129+
130+
if (type && type.symbol && type.symbol.members) {
131+
const field = type.symbol.members.get(name);
132+
return field && (field.flags & ts.SymbolFlags.SetAccessor) !== 0;
133+
}
134+
}
135+
return false;
136+
}
111137
}

src/Transpiler.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,30 +633,50 @@ export class LuaTranspiler {
633633
result = `bit.band(${lhs},${rhs})`;
634634
break;
635635
case ts.SyntaxKind.AmpersandEqualsToken:
636+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
637+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression,
638+
`bit.band(${lhs},${rhs})`);
639+
}
636640
result = `${lhs}=bit.band(${lhs},${rhs})`;
637641
break;
638642
case ts.SyntaxKind.BarToken:
639643
result = `bit.bor(${lhs},${rhs})`;
640644
break;
641645
case ts.SyntaxKind.BarEqualsToken:
646+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
647+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression,
648+
`bit.bor(${lhs},${rhs})`);
649+
}
642650
result = `${lhs}=bit.bor(${lhs},${rhs})`;
643651
break;
644652
case ts.SyntaxKind.LessThanLessThanToken:
645653
result = `bit.lshift(${lhs},${rhs})`;
646654
break;
647655
case ts.SyntaxKind.LessThanLessThanEqualsToken:
656+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
657+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression,
658+
`bit.lshift(${lhs},${rhs})`);
659+
}
648660
result = `${lhs}=bit.lshift(${lhs},${rhs})`;
649661
break;
650662
case ts.SyntaxKind.GreaterThanGreaterThanToken:
651663
result = `bit.arshift(${lhs},${rhs})`;
652664
break;
653665
case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
666+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
667+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression,
668+
`bit.arshift(${lhs},${rhs})`);
669+
}
654670
result = `${lhs}=bit.arshift(${lhs},${rhs})`;
655671
break;
656672
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
657673
result = `bit.rshift(${lhs},${rhs})`;
658674
break;
659675
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
676+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
677+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression,
678+
`bit.rshift(${lhs},${rhs})`);
679+
}
660680
result = `${lhs}=bit.rshift(${lhs},${rhs})`;
661681
break;
662682
}
@@ -666,30 +686,45 @@ export class LuaTranspiler {
666686
result = `${lhs}&${rhs}`;
667687
break;
668688
case ts.SyntaxKind.AmpersandEqualsToken:
689+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
690+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}&${rhs}`);
691+
}
669692
result = `${lhs}=${lhs}&${rhs}`;
670693
break;
671694
case ts.SyntaxKind.BarToken:
672695
result = `${lhs}|${rhs}`;
673696
break;
674697
case ts.SyntaxKind.BarEqualsToken:
698+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
699+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}|${rhs}`);
700+
}
675701
result = `${lhs}=${lhs}|${rhs}`;
676702
break;
677703
case ts.SyntaxKind.LessThanLessThanToken:
678704
result = `${lhs}<<${rhs}`;
679705
break;
680706
case ts.SyntaxKind.LessThanLessThanEqualsToken:
707+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
708+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}<<${rhs}`);
709+
}
681710
result = `${lhs}=${lhs}<<${rhs}`;
682711
break;
683712
case ts.SyntaxKind.GreaterThanGreaterThanToken:
684713
result = `${lhs}>>${rhs}`;
685714
break;
686715
case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
716+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
717+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}>>${rhs}`);
718+
}
687719
result = `${lhs}=${lhs}>>${rhs}`;
688720
break;
689721
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
690722
result = `${lhs}>>>${rhs}`;
691723
break;
692724
case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
725+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
726+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}>>>${rhs}`);
727+
}
693728
result = `${lhs}=${lhs}>>>${rhs}`;
694729
break;
695730
}
@@ -699,15 +734,27 @@ export class LuaTranspiler {
699734
if (result === "") {
700735
switch (node.operatorToken.kind) {
701736
case ts.SyntaxKind.PlusEqualsToken:
737+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
738+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}+${rhs}`);
739+
}
702740
result = `${lhs}=${lhs}+${rhs}`;
703741
break;
704742
case ts.SyntaxKind.MinusEqualsToken:
743+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
744+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}-${rhs}`);
745+
}
705746
result = `${lhs}=${lhs}-${rhs}`;
706747
break;
707748
case ts.SyntaxKind.AsteriskEqualsToken:
749+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
750+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}*${rhs}`);
751+
}
708752
result = `${lhs}=${lhs}*${rhs}`;
709753
break;
710754
case ts.SyntaxKind.SlashEqualsToken:
755+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
756+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, `${lhs}/${rhs}`);
757+
}
711758
result = `${lhs}=${lhs}/${rhs}`;
712759
break;
713760
case ts.SyntaxKind.AmpersandAmpersandToken:
@@ -751,6 +798,9 @@ export class LuaTranspiler {
751798
result = `${lhs}<=${rhs}`;
752799
break;
753800
case ts.SyntaxKind.EqualsToken:
801+
if (tsEx.hasSetAccessor(node.left, this.checker)) {
802+
return this.transpileSetAccessor(node.left as ts.PropertyAccessExpression, rhs);
803+
}
754804
result = `${lhs}=${rhs}`;
755805
break;
756806
case ts.SyntaxKind.EqualsEqualsToken:
@@ -1007,6 +1057,8 @@ export class LuaTranspiler {
10071057
case ts.TypeFlags.Object:
10081058
if (tsEx.isArrayType(type, this.checker)) {
10091059
return this.transpileArrayProperty(node);
1060+
} else if (tsEx.hasGetAccessor(node, this.checker)) {
1061+
return this.transpileGetAccessor(node);
10101062
}
10111063
}
10121064

@@ -1024,6 +1076,18 @@ export class LuaTranspiler {
10241076
return `${callPath}.${property}`;
10251077
}
10261078

1079+
public transpileGetAccessor(node: ts.PropertyAccessExpression): string {
1080+
const name = node.name.escapedText;
1081+
const expression = this.transpileExpression(node.expression);
1082+
return `${expression}.get__${name}()`;
1083+
}
1084+
1085+
public transpileSetAccessor(node: ts.PropertyAccessExpression, value: string): string {
1086+
const name = node.name.escapedText;
1087+
const expression = this.transpileExpression(node.expression);
1088+
return `${expression}.set__${name}(${value})`;
1089+
}
1090+
10271091
// Transpile a Math._ property
10281092
public transpileMathExpression(identifier: ts.Identifier): string {
10291093
const translation = {
@@ -1322,6 +1386,16 @@ export class LuaTranspiler {
13221386
);
13231387
}
13241388

1389+
// Transpile get accessors
1390+
node.members.filter(ts.isGetAccessor).forEach((getAccessor) => {
1391+
result += this.transpileGetAccessorDeclaration(getAccessor, className);
1392+
});
1393+
1394+
// Transpile set accessors
1395+
node.members.filter(ts.isSetAccessor).forEach((setAccessor) => {
1396+
result += this.transpileSetAccessorDeclaration(setAccessor, className);
1397+
});
1398+
13251399
// Transpile methods
13261400
node.members.filter(ts.isMethodDeclaration).forEach((method) => {
13271401
result += this.transpileMethodDeclaration(method, `${className}.`);
@@ -1330,6 +1404,39 @@ export class LuaTranspiler {
13301404
return result;
13311405
}
13321406

1407+
public transpileGetAccessorDeclaration(getAccessor: ts.GetAccessorDeclaration, className: string): string {
1408+
const name = (getAccessor.name as ts.Identifier).escapedText;
1409+
1410+
let result = this.indent + `function ${className}.get__${name}()\n`;
1411+
1412+
this.pushIndent();
1413+
result += this.transpileBlock(getAccessor.body);
1414+
this.popIndent();
1415+
1416+
result += this.indent + `end\n`;
1417+
1418+
return result;
1419+
}
1420+
1421+
public transpileSetAccessorDeclaration(setAccessor: ts.SetAccessorDeclaration, className: string): string {
1422+
const name = (setAccessor.name as ts.Identifier).escapedText;
1423+
1424+
const paramNames: string[] = [];
1425+
setAccessor.parameters.forEach((param) => {
1426+
paramNames.push((param.name as ts.Identifier).escapedText as string);
1427+
});
1428+
1429+
let result = this.indent + `function ${className}.set__${name}(${paramNames.join(",")})\n`;
1430+
1431+
this.pushIndent();
1432+
result += this.transpileBlock(setAccessor.body);
1433+
this.popIndent();
1434+
1435+
result += this.indent + `end\n`;
1436+
1437+
return result;
1438+
}
1439+
13331440
public transpileConstructor(node: ts.ConstructorDeclaration,
13341441
className: string,
13351442
instanceFields: ts.PropertyDeclaration[]): string {

0 commit comments

Comments
 (0)