diff --git a/src/TSHelper.ts b/src/TSHelper.ts index aa87170e5..352575c01 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -81,14 +81,18 @@ export class TSHelper { } // iterate over a type and its bases until the callback returns true. - public static forTypeOrAnySupertype(type: ts.Type, callback: (type: ts.Type) => boolean): boolean { + public static forTypeOrAnySupertype(type: ts.Type, checker: ts.TypeChecker, callback: (type: ts.Type) => boolean): + boolean { if (callback(type)) { return true; } + if (!type.isClassOrInterface() && type.symbol) { + type = checker.getDeclaredTypeOfSymbol(type.symbol); + } const baseTypes = type.getBaseTypes(); if (baseTypes) { for (const baseType of baseTypes) { - if (this.forTypeOrAnySupertype(baseType, callback)) { + if (this.forTypeOrAnySupertype(baseType, checker, callback)) { return true; } } @@ -115,7 +119,7 @@ export class TSHelper { } public static isArrayType(type: ts.Type, checker: ts.TypeChecker): boolean { - return this.forTypeOrAnySupertype(type, t => this.isExplicitArrayType(t, checker)); + return this.forTypeOrAnySupertype(type, checker, t => this.isExplicitArrayType(t, checker)); } public static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { @@ -203,7 +207,7 @@ export class TSHelper { if (ts.isPropertyAccessExpression(node)) { const name = node.name.escapedText; const type = checker.getTypeAtLocation(node.expression); - return this.forTypeOrAnySupertype(type, t => this.hasExplicitGetAccessor(t, name)); + return this.forTypeOrAnySupertype(type, checker, t => this.hasExplicitGetAccessor(t, name)); } return false; } @@ -219,7 +223,7 @@ export class TSHelper { if (ts.isPropertyAccessExpression(node)) { const name = node.name.escapedText; const type = checker.getTypeAtLocation(node.expression); - return this.forTypeOrAnySupertype(type, t => this.hasExplicitSetAccessor(t, name)); + return this.forTypeOrAnySupertype(type, checker, t => this.hasExplicitSetAccessor(t, name)); } return false; } diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index d1daa4268..cb7a4c43c 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -43,8 +43,8 @@ export class ArrayTests { public derivedArrayAccess(): void { const lua = `local arr = {firstElement=function(self) return self[1]; end};` + util.transpileString( - `interface CustomArray extends Array{ firstElement():number; }; - declare const arr: CustomArray; + `interface CustomArray extends Array{ firstElement():number; }; + declare const arr: CustomArray; arr[0] = 3; return arr.firstElement();` ); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 868b9bee7..6f9c2ba30 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -257,6 +257,7 @@ export class ExpressionTests { @TestCase("inst.baseField", 7) @TestCase("inst.field", 6) @TestCase("inst.superField", 5) + @TestCase("inst.superBaseField", 4) @Test("Inherited accessors") public inheritedAccessors(expression: string, expected: any): void { const source = `class MyBaseClass {` @@ -273,6 +274,7 @@ export class ExpressionTests { + ` public _superField: number;` + ` public get superField(): number { return this._superField + 2; }` + ` public set superField(v: number) { this._superField = v; }` + + ` public get superBaseField() { return this.baseField - 3; }` + `}` + `var inst = new MySuperClass();` + `inst.baseField = 1;`