Skip to content

Commit afb2a57

Browse files
committed
Primitive property override
1 parent 33b2084 commit afb2a57

3 files changed

Lines changed: 74 additions & 23 deletions

File tree

TSHelper.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ export class TSHelper {
3232
static isValueType(node: ts.Node): boolean {
3333
return ts.isIdentifier(node) || ts.isLiteralExpression(node) || ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node);
3434
}
35+
36+
static isArrayType(type: ts.Type): boolean {
37+
return type.flags == ts.TypeFlags.Object && (<ts.ObjectType>type).symbol.escapedName == "Array";
38+
}
3539
}

Transpiler.ts

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ export class LuaTranspiler {
257257
case ts.SyntaxKind.Identifier:
258258
// For identifiers simply return their name
259259
return (<ts.Identifier>node).text;
260-
case ts.SyntaxKind.StringLiteral:
260+
case ts.SyntaxKind.StringLiteral:
261261
const text = (<ts.StringLiteral>node).text;
262262
return `"${text}"`;
263263
case ts.SyntaxKind.NumericLiteral:
@@ -376,39 +376,76 @@ export class LuaTranspiler {
376376
const parameters = [];
377377
node.arguments.forEach(param => {
378378
parameters.push(this.transpileExpression(param));
379-
})
379+
});
380380

381381
return `${callPath}(${parameters.join(",")})`;
382382
}
383383

384384
transpilePropertyAccessExpression(node: ts.PropertyAccessExpression): string {
385-
let parts = [];
386-
node.forEachChild(child => {
387-
switch(child.kind) {
388-
case ts.SyntaxKind.ThisKeyword:
389-
parts.push("self");
390-
break;
391-
case ts.SyntaxKind.Identifier:
392-
parts.push((<ts.Identifier>child).escapedText);
393-
break;
394-
case ts.SyntaxKind.CallExpression:
395-
parts.push(this.transpileCallExpression(<ts.CallExpression>child));
396-
break;
397-
case ts.SyntaxKind.PropertyAccessExpression:
398-
parts.push(this.transpilePropertyAccessExpression(<ts.PropertyAccessExpression>child));
399-
break;
400-
default:
401-
throw new TranspileError("Unsupported access kind: " + tsEx.enumName(child.kind, ts.SyntaxKind), node);
402-
}
403-
});
404-
return parts.join(".");
385+
const property = node.name.text;
386+
387+
// Check for primitive types to override
388+
const type = this.checker.getTypeAtLocation(node.expression);
389+
console.log(type.flags);
390+
switch (type.flags) {
391+
case ts.TypeFlags.String:
392+
case ts.TypeFlags.StringLiteral:
393+
return this.transpileStringProperty(node);
394+
case ts.TypeFlags.Object:
395+
if (tsEx.isArrayType(type))
396+
return this.transpileArrayProperty(node);
397+
}
398+
399+
// Do regular handling
400+
switch(node.expression.kind) {
401+
case ts.SyntaxKind.ThisKeyword:
402+
return `self.${property}`;
403+
case ts.SyntaxKind.Identifier:
404+
let path = (<ts.Identifier>node.expression).text;
405+
return `${path}.${property}`;
406+
case ts.SyntaxKind.StringLiteral:
407+
case ts.SyntaxKind.NumericLiteral:
408+
case ts.SyntaxKind.ArrayLiteralExpression:
409+
path = this.transpileExpression(node.expression);
410+
return `${path}.${property}`;
411+
case ts.SyntaxKind.CallExpression:
412+
path = this.transpileCallExpression(<ts.CallExpression>node.expression);
413+
return `${path}.${property}`;
414+
case ts.SyntaxKind.PropertyAccessExpression:
415+
path = this.transpilePropertyAccessExpression(<ts.PropertyAccessExpression>node.expression);
416+
return `${path}.${property}`;
417+
default:
418+
throw new TranspileError("Unsupported access kind: " + tsEx.enumName(node.expression.kind, ts.SyntaxKind), node);
419+
}
420+
}
421+
422+
// Transpile access of string properties, only supported properties are allowed
423+
transpileStringProperty(node: ts.PropertyAccessExpression): string {
424+
const property = node.name;
425+
switch (property.escapedText) {
426+
case "length":
427+
return "#" + this.transpileExpression(node.expression);
428+
default:
429+
throw new TranspileError("Unsupported string property: " + property.escapedText, node);
430+
}
431+
}
432+
433+
// Transpile access of array properties, only supported properties are allowed
434+
transpileArrayProperty(node: ts.PropertyAccessExpression): string {
435+
const property = node.name;
436+
switch (property.escapedText) {
437+
case "length":
438+
return "#" + this.transpileExpression(node.expression);
439+
default:
440+
throw new TranspileError("Unsupported array property: " + property.escapedText, node);
441+
}
405442
}
406443

407444
transpileElementAccessExpression(node: ts.ElementAccessExpression): string {
408445
const element = this.transpileExpression(node.expression);
409446
const index = this.transpileExpression(node.argumentExpression);
410447

411-
const isArray = this.checker.getTypeAtLocation(node.expression).symbol.escapedName == "Array";
448+
const isArray = tsEx.isArrayType(this.checker.getTypeAtLocation(node.expression));
412449

413450
if (isArray) {
414451
return `${element}[${index}+1]`;

test/test3.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
let a = "";
2+
let b = [1,2,3];
3+
let c = {d: a, e: b};
4+
let d = b.length;
5+
let e = a.length;
6+
let f = c.d.length;
7+
let g = c.e.length;
8+
let h = "abc".length;
9+
b.push(3);
10+
//let d = a.indexOf("b");

0 commit comments

Comments
 (0)