From 49eb0d7a2b87f0ad1175b86d24df1d57c07e01d2 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 23 Jan 2020 22:18:10 +0100 Subject: [PATCH] Disallow 'declare' modifier on private named properties (#36381) Fixes: #36345 --- src/compiler/checker.ts | 11 ++++++---- ...ivateNamesIncompatibleModifiers.errors.txt | 22 +++++++++++-------- .../privateNamesIncompatibleModifiers.js | 1 + .../privateNamesIncompatibleModifiers.symbols | 7 ++++-- .../privateNamesIncompatibleModifiers.types | 3 +++ .../privateNamesIncompatibleModifiers.ts | 1 + 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 59f18ef87bc..409d785a227 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35350,6 +35350,9 @@ namespace ts { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract"); } } + else if (isPrivateIdentifierPropertyDeclaration(node)) { + return grammarErrorOnNode(modifier, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); + } flags |= modifierToFlag(modifier.kind); break; @@ -35436,6 +35439,9 @@ namespace ts { else if ((node.parent.flags & NodeFlags.Ambient) && node.parent.kind === SyntaxKind.ModuleBlock) { return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); } + else if (isPrivateIdentifierPropertyDeclaration(node)) { + return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare"); + } flags |= ModifierFlags.Ambient; lastDeclare = modifier; break; @@ -35462,7 +35468,7 @@ namespace ts { } } if (isNamedDeclaration(node) && node.name.kind === SyntaxKind.PrivateIdentifier) { - return grammarErrorOnNode(node, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract"); + return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract"); } flags |= ModifierFlags.Abstract; @@ -35508,9 +35514,6 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && (node).dotDotDotToken) { return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } - else if (isNamedDeclaration(node) && (flags & ModifierFlags.AccessibilityModifier) && node.name.kind === SyntaxKind.PrivateIdentifier) { - return grammarErrorOnNode(node, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); - } if (flags & ModifierFlags.Async) { return checkGrammarAsyncModifier(node, lastAsync!); } diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt b/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt index e5da07f40eb..3bb142060cf 100644 --- a/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.errors.txt @@ -1,26 +1,30 @@ -tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(2,12): error TS18010: An accessibility modifier cannot be used with a private identifier. -tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(3,13): error TS18010: An accessibility modifier cannot be used with a private identifier. -tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(4,15): error TS18010: An accessibility modifier cannot be used with a private identifier. -tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(9,14): error TS18019: 'abstract' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(2,5): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(3,5): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(4,5): error TS18010: An accessibility modifier cannot be used with a private identifier. +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(6,5): error TS18019: 'declare' modifier cannot be used with a private identifier +tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts(10,5): error TS18019: 'abstract' modifier cannot be used with a private identifier -==== tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts (4 errors) ==== +==== tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts (5 errors) ==== class A { public #foo = 3; // Error - ~~~~ + ~~~~~~ !!! error TS18010: An accessibility modifier cannot be used with a private identifier. private #bar = 3; // Error - ~~~~ + ~~~~~~~ !!! error TS18010: An accessibility modifier cannot be used with a private identifier. protected #baz = 3; // Error - ~~~~ + ~~~~~~~~~ !!! error TS18010: An accessibility modifier cannot be used with a private identifier. readonly #qux = 3; // OK + declare #what: number; // Error + ~~~~~~~ +!!! error TS18019: 'declare' modifier cannot be used with a private identifier } abstract class B { abstract #quux = 3; // Error - ~~~~~ + ~~~~~~~~ !!! error TS18019: 'abstract' modifier cannot be used with a private identifier } \ No newline at end of file diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.js b/tests/baselines/reference/privateNamesIncompatibleModifiers.js index 82d8551e7fa..48695a4604f 100644 --- a/tests/baselines/reference/privateNamesIncompatibleModifiers.js +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.js @@ -4,6 +4,7 @@ class A { private #bar = 3; // Error protected #baz = 3; // Error readonly #qux = 3; // OK + declare #what: number; // Error } abstract class B { diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols b/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols index 45b7114c1ae..65d665cb1d1 100644 --- a/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.symbols @@ -13,12 +13,15 @@ class A { readonly #qux = 3; // OK >#qux : Symbol(A.#qux, Decl(privateNamesIncompatibleModifiers.ts, 3, 23)) + + declare #what: number; // Error +>#what : Symbol(A.#what, Decl(privateNamesIncompatibleModifiers.ts, 4, 22)) } abstract class B { ->B : Symbol(B, Decl(privateNamesIncompatibleModifiers.ts, 5, 1)) +>B : Symbol(B, Decl(privateNamesIncompatibleModifiers.ts, 6, 1)) abstract #quux = 3; // Error ->#quux : Symbol(B.#quux, Decl(privateNamesIncompatibleModifiers.ts, 7, 18)) +>#quux : Symbol(B.#quux, Decl(privateNamesIncompatibleModifiers.ts, 8, 18)) } diff --git a/tests/baselines/reference/privateNamesIncompatibleModifiers.types b/tests/baselines/reference/privateNamesIncompatibleModifiers.types index f4929fd8139..ac2f60f67ff 100644 --- a/tests/baselines/reference/privateNamesIncompatibleModifiers.types +++ b/tests/baselines/reference/privateNamesIncompatibleModifiers.types @@ -17,6 +17,9 @@ class A { readonly #qux = 3; // OK >#qux : 3 >3 : 3 + + declare #what: number; // Error +>#what : number } abstract class B { diff --git a/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts b/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts index effcddcf4e3..ef4341ab567 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiers.ts @@ -6,6 +6,7 @@ class A { private #bar = 3; // Error protected #baz = 3; // Error readonly #qux = 3; // OK + declare #what: number; // Error } abstract class B {