From 3d5ac88d1bfcf649d700c419c5ebc439e2a66717 Mon Sep 17 00:00:00 2001 From: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:31:00 +0200 Subject: [PATCH 1/2] Allow private properties in optional chains --- src/compiler/diagnosticMessages.json | 4 --- src/compiler/parser.ts | 3 -- .../privateIdentifierChain.1.errors.txt | 28 ------------------- .../reference/privateIdentifierChain.1.js | 16 +++++++---- .../privateIdentifierChain.1.symbols | 13 +++++++-- .../reference/privateIdentifierChain.1.types | 27 +++++++++++++----- ...ateNameUncheckedJsOptionalChain.errors.txt | 17 ----------- .../privateNameUncheckedJsOptionalChain.types | 5 +--- .../privateIdentifierChain.1.ts | 8 ++++-- 9 files changed, 46 insertions(+), 75 deletions(-) delete mode 100644 tests/baselines/reference/privateIdentifierChain.1.errors.txt delete mode 100644 tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7f686076f1824..d620376f3602b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8322,10 +8322,6 @@ "category": "Error", "code": 18029 }, - "An optional chain cannot contain private identifiers.": { - "category": "Error", - "code": 18030 - }, "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents.": { "category": "Error", "code": 18031 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59ad1f030220f..91be37e3da197 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6405,9 +6405,6 @@ namespace Parser { const propertyAccess = isOptionalChain ? factoryCreatePropertyAccessChain(expression, questionDotToken, name) : factoryCreatePropertyAccessExpression(expression, name); - if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { - parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); - } if (isExpressionWithTypeArguments(expression) && expression.typeArguments) { const pos = expression.typeArguments.pos - 1; const end = skipTrivia(sourceText, expression.typeArguments.end) + 1; diff --git a/tests/baselines/reference/privateIdentifierChain.1.errors.txt b/tests/baselines/reference/privateIdentifierChain.1.errors.txt deleted file mode 100644 index f39beb93eda6c..0000000000000 --- a/tests/baselines/reference/privateIdentifierChain.1.errors.txt +++ /dev/null @@ -1,28 +0,0 @@ -privateIdentifierChain.1.ts(8,15): error TS18030: An optional chain cannot contain private identifiers. -privateIdentifierChain.1.ts(9,9): error TS2532: Object is possibly 'undefined'. -privateIdentifierChain.1.ts(9,17): error TS18030: An optional chain cannot contain private identifiers. -privateIdentifierChain.1.ts(10,22): error TS18030: An optional chain cannot contain private identifiers. - - -==== privateIdentifierChain.1.ts (4 errors) ==== - class A { - a?: A - #b?: A; - getA(): A { - return new A(); - } - constructor() { - this?.#b; // Error - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.a.#b; // Error - ~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.getA().#b; // Error - ~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - } - } - \ No newline at end of file diff --git a/tests/baselines/reference/privateIdentifierChain.1.js b/tests/baselines/reference/privateIdentifierChain.1.js index 37e85cb1096c7..1ea67a244b7b6 100644 --- a/tests/baselines/reference/privateIdentifierChain.1.js +++ b/tests/baselines/reference/privateIdentifierChain.1.js @@ -8,9 +8,11 @@ class A { return new A(); } constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; } } @@ -23,8 +25,10 @@ class A { return new A(); } constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; } } diff --git a/tests/baselines/reference/privateIdentifierChain.1.symbols b/tests/baselines/reference/privateIdentifierChain.1.symbols index 018ca51f62f21..3a5fb46551aec 100644 --- a/tests/baselines/reference/privateIdentifierChain.1.symbols +++ b/tests/baselines/reference/privateIdentifierChain.1.symbols @@ -20,17 +20,24 @@ class A { >A : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) } constructor() { - this?.#b; // Error + this.a = this; +>this.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) +>a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) +>this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) + + // None of these should error + this?.#b; >this?.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) >this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) - this?.a.#b; // Error + this?.a.#b; >this?.a.#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) >this?.a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) >this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) >a : Symbol(A.a, Decl(privateIdentifierChain.1.ts, 0, 9)) - this?.getA().#b; // Error + this?.getA().#b; >this?.getA().#b : Symbol(A.#b, Decl(privateIdentifierChain.1.ts, 1, 9)) >this?.getA : Symbol(A.getA, Decl(privateIdentifierChain.1.ts, 2, 11)) >this : Symbol(A, Decl(privateIdentifierChain.1.ts, 0, 0)) diff --git a/tests/baselines/reference/privateIdentifierChain.1.types b/tests/baselines/reference/privateIdentifierChain.1.types index 70827d3bcbc0c..3a7b58bae956f 100644 --- a/tests/baselines/reference/privateIdentifierChain.1.types +++ b/tests/baselines/reference/privateIdentifierChain.1.types @@ -24,23 +24,36 @@ class A { > : ^^^^^^^^ } constructor() { - this?.#b; // Error + this.a = this; +>this.a = this : this +> : ^^^^ +>this.a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>a : A | undefined +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ + + // None of these should error + this?.#b; >this?.#b : A | undefined > : ^^^^^^^^^^^^^ >this : this > : ^^^^ - this?.a.#b; // Error + this?.a.#b; >this?.a.#b : A | undefined > : ^^^^^^^^^^^^^ ->this?.a : A | undefined -> : ^^^^^^^^^^^^^ +>this?.a : A +> : ^ >this : this > : ^^^^ ->a : A | undefined -> : ^^^^^^^^^^^^^ +>a : A +> : ^ - this?.getA().#b; // Error + this?.getA().#b; >this?.getA().#b : A | undefined > : ^^^^^^^^^^^^^ >this?.getA() : A diff --git a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt deleted file mode 100644 index 13327c6a0151c..0000000000000 --- a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -privateNameUncheckedJsOptionalChain.js(4,15): error TS18030: An optional chain cannot contain private identifiers. -privateNameUncheckedJsOptionalChain.js(5,15): error TS18030: An optional chain cannot contain private identifiers. - - -==== privateNameUncheckedJsOptionalChain.js (2 errors) ==== - class C { - #bar; - constructor () { - this?.#foo; - ~~~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - this?.#bar; - ~~~~ -!!! error TS18030: An optional chain cannot contain private identifiers. - } - } - \ No newline at end of file diff --git a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types index cea9ea7054bd5..9dfc318ecca2b 100644 --- a/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types +++ b/tests/baselines/reference/privateNameUncheckedJsOptionalChain.types @@ -7,18 +7,15 @@ class C { #bar; >#bar : any -> : ^^^ constructor () { this?.#foo; ->this?.#foo : any -> : ^^^ +>this?.#foo : error >this : this > : ^^^^ this?.#bar; >this?.#bar : any -> : ^^^ >this : this > : ^^^^ } diff --git a/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts index e98eeba739d5a..047da6bf55ff6 100644 --- a/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts +++ b/tests/cases/conformance/expressions/optionalChaining/privateIdentifierChain/privateIdentifierChain.1.ts @@ -9,8 +9,10 @@ class A { return new A(); } constructor() { - this?.#b; // Error - this?.a.#b; // Error - this?.getA().#b; // Error + this.a = this; + // None of these should error + this?.#b; + this?.a.#b; + this?.getA().#b; } } From 0156c57f143bcd26ba0fc5788f0d4254621b4f8e Mon Sep 17 00:00:00 2001 From: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com> Date: Fri, 18 Oct 2024 00:03:14 +0200 Subject: [PATCH 2/2] Fix linter error --- src/compiler/parser.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 91be37e3da197..71fc00c185cea 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -159,7 +159,6 @@ import { isMetaProperty, isModifierKind, isNonNullExpression, - isPrivateIdentifier, isSetAccessorDeclaration, isStringOrNumericLiteralLike, isTaggedTemplateExpression,