From cc15c7bf6064937323f46b0274743873493e3c6f Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 15 Nov 2023 21:17:45 +0800 Subject: [PATCH 1/2] fix: diagnose correct class name when resolving class member fails --- src/resolver.ts | 50 +++++++++++++++----------------- tests/compiler/class-errors.json | 9 ++++++ tests/compiler/class-errors.ts | 7 +++++ 3 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 tests/compiler/class-errors.json create mode 100644 tests/compiler/class-errors.ts diff --git a/src/resolver.ts b/src/resolver.ts index ca05a3424b..377dfdd7ca 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1440,8 +1440,10 @@ export class Resolver extends DiagnosticEmitter { case ElementKind.InterfacePrototype: case ElementKind.Class: case ElementKind.Interface: { + let classLikeTarget = target; + let findBase = false; do { - let member = target.getMember(propertyName); + let member = classLikeTarget.getMember(propertyName); if (member) { if (member.kind == ElementKind.PropertyPrototype) { let propertyInstance = this.resolveProperty(member, reportMode); @@ -1458,34 +1460,30 @@ export class Resolver extends DiagnosticEmitter { this.currentElementExpression = null; return member; // instance FIELD, static GLOBAL, FUNCTION_PROTOTYPE, PROPERTY... } - // traverse inherited static members on the base prototype if target is a class prototype - if ( - target.kind == ElementKind.ClassPrototype || - target.kind == ElementKind.InterfacePrototype - ) { - let classPrototype = target; - let basePrototype = classPrototype.basePrototype; - if (basePrototype) { - target = basePrototype; - } else { + findBase = false; + switch (classLikeTarget.kind) { + case ElementKind.ClassPrototype: + case ElementKind.InterfacePrototype: + // traverse inherited static members on the base prototype if target is a class prototype + let classPrototype = classLikeTarget; + let basePrototype = classPrototype.basePrototype; + if (basePrototype) { + findBase = true; + classLikeTarget = basePrototype; + } break; - } - // traverse inherited instance members on the base class if target is a class instance - } else if ( - target.kind == ElementKind.Class || - target.kind == ElementKind.Interface - ) { - let classInstance = target; - let baseInstance = classInstance.base; - if (baseInstance) { - target = baseInstance; - } else { + case ElementKind.Class: + case ElementKind.Interface: + // traverse inherited instance members on the base class if target is a class instance + let classInstance = classLikeTarget; + let baseInstance = classInstance.base; + if (baseInstance) { + findBase = true; + classLikeTarget = baseInstance; + } break; - } - } else { - break; } - } while (true); + } while (findBase); break; } default: { // enums or other namespace-like elements diff --git a/tests/compiler/class-errors.json b/tests/compiler/class-errors.json new file mode 100644 index 0000000000..d852107478 --- /dev/null +++ b/tests/compiler/class-errors.json @@ -0,0 +1,9 @@ +{ + "asc_flags": [ + ], + "stderr": [ + "TS2304: Cannot find name 'T'.", + "TS2339: Property 'v' does not exist on type 'class-errors/A'.", + "EOF" + ] +} diff --git a/tests/compiler/class-errors.ts b/tests/compiler/class-errors.ts new file mode 100644 index 0000000000..ff71b03088 --- /dev/null +++ b/tests/compiler/class-errors.ts @@ -0,0 +1,7 @@ +class A { + v: T; +} + +new A().v; + +ERROR("EOF"); From f8049c136c7fd6056c222c41839db12302d47e41 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 15 Nov 2023 21:36:25 +0800 Subject: [PATCH 2/2] fix warn --- src/resolver.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/resolver.ts b/src/resolver.ts index 377dfdd7ca..b1c2504521 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1463,7 +1463,7 @@ export class Resolver extends DiagnosticEmitter { findBase = false; switch (classLikeTarget.kind) { case ElementKind.ClassPrototype: - case ElementKind.InterfacePrototype: + case ElementKind.InterfacePrototype: { // traverse inherited static members on the base prototype if target is a class prototype let classPrototype = classLikeTarget; let basePrototype = classPrototype.basePrototype; @@ -1472,8 +1472,9 @@ export class Resolver extends DiagnosticEmitter { classLikeTarget = basePrototype; } break; + } case ElementKind.Class: - case ElementKind.Interface: + case ElementKind.Interface: { // traverse inherited instance members on the base class if target is a class instance let classInstance = classLikeTarget; let baseInstance = classInstance.base; @@ -1482,6 +1483,7 @@ export class Resolver extends DiagnosticEmitter { classLikeTarget = baseInstance; } break; + } } } while (findBase); break;