mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix crash for private identifier in expando assignments (#37764)
* Fix crash for private identifier in expando assignments It does this by disallowing private identifiers from expando assignments entirely. I haven't thought of a scenario where they make sense, but I haven't thought about it exhaustively either. Fixes #37356 * Update baselines I think the new error is probably better. It's certainly different!
This commit is contained in:
@@ -2155,7 +2155,7 @@ namespace ts {
|
||||
|
||||
/** Any series of property and element accesses. */
|
||||
export function isBindableStaticAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticAccessExpression {
|
||||
return isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword || isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
|
||||
return isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword || isIdentifier(node.name) && isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
|
||||
|| isBindableStaticElementAccessExpression(node, excludeThisKeyword);
|
||||
}
|
||||
|
||||
@@ -4432,7 +4432,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isPropertyAccessEntityNameExpression(node: Node): node is PropertyAccessEntityNameExpression {
|
||||
return isPropertyAccessExpression(node) && isEntityNameExpression(node.expression);
|
||||
return isPropertyAccessExpression(node) && isIdentifier(node.name) && isEntityNameExpression(node.expression);
|
||||
}
|
||||
|
||||
export function tryGetPropertyAccessOrIdentifierToString(expr: Expression): string | undefined {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//// [privateIdentifierExpando.js]
|
||||
const x = {};
|
||||
x.#bar.baz = 20;
|
||||
|
||||
|
||||
|
||||
|
||||
//// [privateIdentifierExpando.d.ts]
|
||||
declare const x: {};
|
||||
@@ -0,0 +1,7 @@
|
||||
=== tests/cases/conformance/salsa/privateIdentifierExpando.js ===
|
||||
const x = {};
|
||||
>x : Symbol(x, Decl(privateIdentifierExpando.js, 0, 5))
|
||||
|
||||
x.#bar.baz = 20;
|
||||
>x : Symbol(x, Decl(privateIdentifierExpando.js, 0, 5))
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/conformance/salsa/privateIdentifierExpando.js ===
|
||||
const x = {};
|
||||
>x : {}
|
||||
>{} : {}
|
||||
|
||||
x.#bar.baz = 20;
|
||||
>x.#bar.baz = 20 : 20
|
||||
>x.#bar.baz : any
|
||||
>x.#bar : any
|
||||
>x : {}
|
||||
>baz : any
|
||||
>20 : 20
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(1,9): error TS2339: Property '#nope' does not exist on type 'typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment")'.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(1,1): error TS2304: Cannot find name 'exports'.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(1,9): error TS18016: Private identifiers are not allowed outside class bodies.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(3,13): error TS18016: Private identifiers are not allowed outside class bodies.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(6,3): error TS2339: Property '#foo' does not exist on type 'typeof B'.
|
||||
tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js(11,14): error TS2339: Property '#foo' does not exist on type 'C'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js (4 errors) ====
|
||||
==== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js (5 errors) ====
|
||||
exports.#nope = 1; // Error (outside class body)
|
||||
~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'exports'.
|
||||
~~~~~
|
||||
!!! error TS2339: Property '#nope' does not exist on type 'typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment")'.
|
||||
!!! error TS18016: Private identifiers are not allowed outside class bodies.
|
||||
function A() { }
|
||||
A.prototype.#no = 2; // Error (outside class body)
|
||||
~~~
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
=== tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment.js ===
|
||||
exports.#nope = 1; // Error (outside class body)
|
||||
>exports : Symbol(#nope, Decl(privateNameJsBadAssignment.js, 0, 0))
|
||||
|
||||
function A() { }
|
||||
>A : Symbol(A, Decl(privateNameJsBadAssignment.js, 0, 18))
|
||||
|
||||
@@ -11,10 +9,10 @@ A.prototype.#no = 2; // Error (outside class body)
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
class B {}
|
||||
>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20), Decl(privateNameJsBadAssignment.js, 4, 10))
|
||||
>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20))
|
||||
|
||||
B.#foo = 3; // Error (outside class body)
|
||||
>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20), Decl(privateNameJsBadAssignment.js, 4, 10))
|
||||
>B : Symbol(B, Decl(privateNameJsBadAssignment.js, 2, 20))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(privateNameJsBadAssignment.js, 5, 11))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
exports.#nope = 1; // Error (outside class body)
|
||||
>exports.#nope = 1 : 1
|
||||
>exports.#nope : any
|
||||
>exports : typeof import("tests/cases/conformance/classes/members/privateNames/privateNameJsBadAssignment")
|
||||
>exports : any
|
||||
>1 : 1
|
||||
|
||||
function A() { }
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @Filename: privateIdentifierExpando.js
|
||||
|
||||
const x = {};
|
||||
x.#bar.baz = 20;
|
||||
Reference in New Issue
Block a user