From b88c957ac49bdc4cb057ca61f98801233c8a3bbb Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 27 Jun 2022 23:56:43 +0300 Subject: [PATCH] fix(49685): omit incorrect visibility error when setter precedes getter --- src/compiler/utilities.ts | 3 +- .../reference/accessorDeclarationOrder.js | 61 +++++++++++++++ .../accessorDeclarationOrder.symbols | 72 ++++++++++++++++++ .../reference/accessorDeclarationOrder.types | 76 +++++++++++++++++++ .../compiler/accessorDeclarationOrder.ts | 35 +++++++++ 5 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/accessorDeclarationOrder.js create mode 100644 tests/baselines/reference/accessorDeclarationOrder.symbols create mode 100644 tests/baselines/reference/accessorDeclarationOrder.types create mode 100644 tests/cases/compiler/accessorDeclarationOrder.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0ac57b26fee15..96bfc3a73696f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5565,7 +5565,8 @@ namespace ts { export function getDeclarationModifierFlagsFromSymbol(s: Symbol, isWrite = false): ModifierFlags { if (s.valueDeclaration) { - const declaration = (isWrite && s.declarations && find(s.declarations, d => d.kind === SyntaxKind.SetAccessor)) || s.valueDeclaration; + const declaration = (isWrite && s.declarations && find(s.declarations, isSetAccessorDeclaration)) + || (s.flags & SymbolFlags.GetAccessor && find(s.declarations, isGetAccessorDeclaration)) || s.valueDeclaration; const flags = getCombinedModifierFlags(declaration); return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier; } diff --git a/tests/baselines/reference/accessorDeclarationOrder.js b/tests/baselines/reference/accessorDeclarationOrder.js new file mode 100644 index 0000000000000..d7b0474e5bf10 --- /dev/null +++ b/tests/baselines/reference/accessorDeclarationOrder.js @@ -0,0 +1,61 @@ +//// [accessorDeclarationOrder.ts] +class C1 { + #name: string; + + public get name() { + return this.#name; + } + + private set name(name: string) { + this.#name = name; + } +} + +class C2 { + #name: string; + + private set name(name: string) { + this.#name = name; + } + + public get name() { + return this.#name; + } +} + +const c1 = new C1(); +const c2 = new C2(); + + +// no error +c1.name; + +// no error +c2.name; + + +//// [accessorDeclarationOrder.js] +class C1 { + #name; + get name() { + return this.#name; + } + set name(name) { + this.#name = name; + } +} +class C2 { + #name; + set name(name) { + this.#name = name; + } + get name() { + return this.#name; + } +} +const c1 = new C1(); +const c2 = new C2(); +// no error +c1.name; +// no error +c2.name; diff --git a/tests/baselines/reference/accessorDeclarationOrder.symbols b/tests/baselines/reference/accessorDeclarationOrder.symbols new file mode 100644 index 0000000000000..b889c5b5fc8ac --- /dev/null +++ b/tests/baselines/reference/accessorDeclarationOrder.symbols @@ -0,0 +1,72 @@ +=== tests/cases/compiler/accessorDeclarationOrder.ts === +class C1 { +>C1 : Symbol(C1, Decl(accessorDeclarationOrder.ts, 0, 0)) + + #name: string; +>#name : Symbol(C1.#name, Decl(accessorDeclarationOrder.ts, 0, 10)) + + public get name() { +>name : Symbol(C1.name, Decl(accessorDeclarationOrder.ts, 1, 18), Decl(accessorDeclarationOrder.ts, 5, 5)) + + return this.#name; +>this.#name : Symbol(C1.#name, Decl(accessorDeclarationOrder.ts, 0, 10)) +>this : Symbol(C1, Decl(accessorDeclarationOrder.ts, 0, 0)) + } + + private set name(name: string) { +>name : Symbol(C1.name, Decl(accessorDeclarationOrder.ts, 1, 18), Decl(accessorDeclarationOrder.ts, 5, 5)) +>name : Symbol(name, Decl(accessorDeclarationOrder.ts, 7, 21)) + + this.#name = name; +>this.#name : Symbol(C1.#name, Decl(accessorDeclarationOrder.ts, 0, 10)) +>this : Symbol(C1, Decl(accessorDeclarationOrder.ts, 0, 0)) +>name : Symbol(name, Decl(accessorDeclarationOrder.ts, 7, 21)) + } +} + +class C2 { +>C2 : Symbol(C2, Decl(accessorDeclarationOrder.ts, 10, 1)) + + #name: string; +>#name : Symbol(C2.#name, Decl(accessorDeclarationOrder.ts, 12, 10)) + + private set name(name: string) { +>name : Symbol(C2.name, Decl(accessorDeclarationOrder.ts, 13, 18), Decl(accessorDeclarationOrder.ts, 17, 5)) +>name : Symbol(name, Decl(accessorDeclarationOrder.ts, 15, 21)) + + this.#name = name; +>this.#name : Symbol(C2.#name, Decl(accessorDeclarationOrder.ts, 12, 10)) +>this : Symbol(C2, Decl(accessorDeclarationOrder.ts, 10, 1)) +>name : Symbol(name, Decl(accessorDeclarationOrder.ts, 15, 21)) + } + + public get name() { +>name : Symbol(C2.name, Decl(accessorDeclarationOrder.ts, 13, 18), Decl(accessorDeclarationOrder.ts, 17, 5)) + + return this.#name; +>this.#name : Symbol(C2.#name, Decl(accessorDeclarationOrder.ts, 12, 10)) +>this : Symbol(C2, Decl(accessorDeclarationOrder.ts, 10, 1)) + } +} + +const c1 = new C1(); +>c1 : Symbol(c1, Decl(accessorDeclarationOrder.ts, 24, 5)) +>C1 : Symbol(C1, Decl(accessorDeclarationOrder.ts, 0, 0)) + +const c2 = new C2(); +>c2 : Symbol(c2, Decl(accessorDeclarationOrder.ts, 25, 5)) +>C2 : Symbol(C2, Decl(accessorDeclarationOrder.ts, 10, 1)) + + +// no error +c1.name; +>c1.name : Symbol(C1.name, Decl(accessorDeclarationOrder.ts, 1, 18), Decl(accessorDeclarationOrder.ts, 5, 5)) +>c1 : Symbol(c1, Decl(accessorDeclarationOrder.ts, 24, 5)) +>name : Symbol(C1.name, Decl(accessorDeclarationOrder.ts, 1, 18), Decl(accessorDeclarationOrder.ts, 5, 5)) + +// no error +c2.name; +>c2.name : Symbol(C2.name, Decl(accessorDeclarationOrder.ts, 13, 18), Decl(accessorDeclarationOrder.ts, 17, 5)) +>c2 : Symbol(c2, Decl(accessorDeclarationOrder.ts, 25, 5)) +>name : Symbol(C2.name, Decl(accessorDeclarationOrder.ts, 13, 18), Decl(accessorDeclarationOrder.ts, 17, 5)) + diff --git a/tests/baselines/reference/accessorDeclarationOrder.types b/tests/baselines/reference/accessorDeclarationOrder.types new file mode 100644 index 0000000000000..325596dd70d09 --- /dev/null +++ b/tests/baselines/reference/accessorDeclarationOrder.types @@ -0,0 +1,76 @@ +=== tests/cases/compiler/accessorDeclarationOrder.ts === +class C1 { +>C1 : C1 + + #name: string; +>#name : string + + public get name() { +>name : string + + return this.#name; +>this.#name : string +>this : this + } + + private set name(name: string) { +>name : string +>name : string + + this.#name = name; +>this.#name = name : string +>this.#name : string +>this : this +>name : string + } +} + +class C2 { +>C2 : C2 + + #name: string; +>#name : string + + private set name(name: string) { +>name : string +>name : string + + this.#name = name; +>this.#name = name : string +>this.#name : string +>this : this +>name : string + } + + public get name() { +>name : string + + return this.#name; +>this.#name : string +>this : this + } +} + +const c1 = new C1(); +>c1 : C1 +>new C1() : C1 +>C1 : typeof C1 + +const c2 = new C2(); +>c2 : C2 +>new C2() : C2 +>C2 : typeof C2 + + +// no error +c1.name; +>c1.name : string +>c1 : C1 +>name : string + +// no error +c2.name; +>c2.name : string +>c2 : C2 +>name : string + diff --git a/tests/cases/compiler/accessorDeclarationOrder.ts b/tests/cases/compiler/accessorDeclarationOrder.ts new file mode 100644 index 0000000000000..ae3ab8e877645 --- /dev/null +++ b/tests/cases/compiler/accessorDeclarationOrder.ts @@ -0,0 +1,35 @@ +// @target: esnext + +class C1 { + #name: string; + + public get name() { + return this.#name; + } + + private set name(name: string) { + this.#name = name; + } +} + +class C2 { + #name: string; + + private set name(name: string) { + this.#name = name; + } + + public get name() { + return this.#name; + } +} + +const c1 = new C1(); +const c2 = new C2(); + + +// no error +c1.name; + +// no error +c2.name;