From 682906f2d96e2cdd80f40044f8ef0733f1c58c32 Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Fri, 19 Mar 2021 08:51:02 +0000 Subject: [PATCH 1/3] leave bad code in for #constructor --- src/compiler/transformers/classFields.ts | 19 +++++++++++++++++++ .../privateNameConstructorReserved.js | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 84a1f32c6f943..3dbe89b4d4373 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -260,6 +260,11 @@ namespace ts { return visitEachChild(node, classElementVisitor, context); } + // leave invalid code as it is + if (isReservedPrivateName(node)) { + return node; + } + const functionName = getHoistedFunctionName(node); if (functionName) { getPendingExpressions().push( @@ -303,6 +308,12 @@ namespace ts { function visitPropertyDeclaration(node: PropertyDeclaration) { Debug.assert(!some(node.decorators)); + + // leave invalid code as it is + if (isReservedPrivateName(node)) { + return node; + } + if (!shouldTransformPrivateElements && isPrivateIdentifier(node.name)) { // Initializer is elided as the field is initialized in transformConstructor. return factory.updatePropertyDeclaration( @@ -1475,4 +1486,12 @@ namespace ts { [receiver] ); } + + function isReservedPrivateName(node: PropertyDeclaration | MethodDeclaration | AccessorDeclaration) { + if (!isPrivateIdentifier(node.name)) { + return false; + } + + return getTextOfPropertyName(node.name) === "#constructor"; + } } diff --git a/tests/baselines/reference/privateNameConstructorReserved.js b/tests/baselines/reference/privateNameConstructorReserved.js index d1de278658b38..9e6a7eb62da90 100644 --- a/tests/baselines/reference/privateNameConstructorReserved.js +++ b/tests/baselines/reference/privateNameConstructorReserved.js @@ -10,5 +10,6 @@ class A { constructor() { _A_instances.add(this); } + #constructor() { } // Error: `#constructor` is a reserved word. } -_A_instances = new WeakSet(), _A_constructor = function _A_constructor() { }; +_A_instances = new WeakSet(); From d911f26ed1d6b08d3ce5891408ca058b5e0bce1d Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Fri, 19 Mar 2021 11:21:45 +0000 Subject: [PATCH 2/3] abort transform if there are duplicate private names --- src/compiler/transformers/classFields.ts | 54 ++- .../reference/privateNameDuplicateField.js | 361 ++++++++---------- .../reference/privateNamesUnique-3.js | 8 +- 3 files changed, 203 insertions(+), 220 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 3dbe89b4d4373..9a9df723b204a 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -770,7 +770,11 @@ namespace ts { // Declare private names. for (const member of node.members) { if (isPrivateIdentifierClassElementDeclaration(member)) { - addPrivateIdentifierToEnvironment(member); + const error = addPrivateIdentifierToEnvironment(member); + if (error) { + // leave invalid code as it is + return node.members; + } } } @@ -1168,16 +1172,20 @@ namespace ts { return pendingExpressions || (pendingExpressions = []); } - function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration) { + function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration): Error | void { const text = getTextOfPropertyName(node.name) as string; const env = getPrivateIdentifierEnvironment(); const { weakSetName, classConstructor } = env; const assignmentExpressions: Expression[] = []; + + const privateName = node.name.escapedText; + let potentialDuplicatePrivateName = env.identifiers.has(privateName); + if (hasStaticModifier(node)) { Debug.assert(classConstructor, "weakSetName should be set in private identifier environment"); if (isPropertyDeclaration(node)) { const variableName = createHoistedVariableForPrivateName(text, node); - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Field, variableName, brandCheckIdentifier: classConstructor, @@ -1186,7 +1194,7 @@ namespace ts { } else if (isMethodDeclaration(node)) { const functionName = createHoistedVariableForPrivateName(text, node); - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Method, methodName: functionName, brandCheckIdentifier: classConstructor, @@ -1195,12 +1203,13 @@ namespace ts { } else if (isGetAccessorDeclaration(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); - const previousInfo = env.identifiers.get(node.name.escapedText); - if (previousInfo?.kind === PrivateIdentifierKind.Accessor) { + const previousInfo = env.identifiers.get(privateName); + if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.getterName) { + potentialDuplicatePrivateName = false; previousInfo.getterName = getterName; } else { - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Accessor, getterName, setterName: undefined, @@ -1211,12 +1220,13 @@ namespace ts { } else if (isSetAccessorDeclaration(node)) { const setterName = createHoistedVariableForPrivateName(text + "_set", node); - const previousInfo = env.identifiers.get(node.name.escapedText); - if (previousInfo?.kind === PrivateIdentifierKind.Accessor) { + const previousInfo = env.identifiers.get(privateName); + if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.setterName) { + potentialDuplicatePrivateName = false; previousInfo.setterName = setterName; } else { - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Accessor, getterName: undefined, setterName, @@ -1231,7 +1241,7 @@ namespace ts { } else if (isPropertyDeclaration(node)) { const weakMapName = createHoistedVariableForPrivateName(text, node); - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Field, brandCheckIdentifier: weakMapName, isStatic: false, @@ -1250,7 +1260,7 @@ namespace ts { else if (isMethodDeclaration(node)) { Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Method, methodName: createHoistedVariableForPrivateName(text, node), brandCheckIdentifier: weakSetName, @@ -1259,16 +1269,17 @@ namespace ts { } else if (isAccessor(node)) { Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - const previousInfo = env.identifiers.get(node.name.escapedText); + const previousInfo = env.identifiers.get(privateName); if (isGetAccessor(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); - if (previousInfo?.kind === PrivateIdentifierKind.Accessor) { + if (previousInfo?.kind === PrivateIdentifierKind.Accessor && !previousInfo.isStatic && !previousInfo.getterName) { + potentialDuplicatePrivateName = false; previousInfo.getterName = getterName; } else { - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Accessor, getterName, setterName: undefined, @@ -1280,11 +1291,12 @@ namespace ts { else { const setterName = createHoistedVariableForPrivateName(text + "_set", node); - if (previousInfo?.kind === PrivateIdentifierKind.Accessor) { + if (previousInfo?.kind === PrivateIdentifierKind.Accessor && !previousInfo.isStatic && !previousInfo.setterName) { + potentialDuplicatePrivateName = false; previousInfo.setterName = setterName; } else { - env.identifiers.set(node.name.escapedText, { + env.identifiers.set(privateName, { kind: PrivateIdentifierKind.Accessor, getterName: undefined, setterName, @@ -1298,6 +1310,10 @@ namespace ts { Debug.assertNever(node, "Unknown class element type."); } + if (potentialDuplicatePrivateName) { + return new Error("Duplicate private name"); + } + getPendingExpressions().push(...assignmentExpressions); } @@ -1487,8 +1503,8 @@ namespace ts { ); } - function isReservedPrivateName(node: PropertyDeclaration | MethodDeclaration | AccessorDeclaration) { - if (!isPrivateIdentifier(node.name)) { + function isReservedPrivateName(node: ClassElement) { + if (!node.name || !isPrivateIdentifier(node.name)) { return false; } diff --git a/tests/baselines/reference/privateNameDuplicateField.js b/tests/baselines/reference/privateNameDuplicateField.js index 255fb235ecc1c..717a4fca7d78c 100644 --- a/tests/baselines/reference/privateNameDuplicateField.js +++ b/tests/baselines/reference/privateNameDuplicateField.js @@ -409,145 +409,119 @@ function Field() { var _A_Field_Field_foo, _A_Field_Field_foo_1, _A_Field_Method_instances, _A_Field_Method_foo, _A_Field_Method_foo_1, _A_Field_Getter_instances, _A_Field_Getter_foo, _A_Field_Getter_foo_get, _A_Field_Setter_instances, _A_Field_Setter_foo, _A_Field_Setter_foo_set, _a, _A_Field_StaticField_foo, _A_Field_StaticField_foo_1, _b, _A_Field_StaticMethod_foo, _A_Field_StaticMethod_foo_1, _c, _A_Field_StaticGetter_foo, _A_Field_StaticGetter_foo_get, _d, _A_Field_StaticSetter_foo, _A_Field_StaticSetter_foo_set; // Error class A_Field_Field { - constructor() { - _A_Field_Field_foo_1.set(this, "foo"); - _A_Field_Field_foo_1.set(this, "foo"); - } + #foo = "foo"; + #foo = "foo"; } - _A_Field_Field_foo = new WeakMap(), _A_Field_Field_foo_1 = new WeakMap(); + _A_Field_Field_foo = new WeakMap(); // Error class A_Field_Method { - constructor() { - _A_Field_Method_instances.add(this); - } + #foo = "foo"; + #foo() { } } - _A_Field_Method_foo = new WeakMap(), _A_Field_Method_instances = new WeakSet(), _A_Field_Method_foo_1 = function _A_Field_Method_foo_1() { }; + _A_Field_Method_foo = new WeakMap(); // Error class A_Field_Getter { - constructor() { - _A_Field_Getter_instances.add(this); - } + #foo = "foo"; + get #foo() { return ""; } } - _A_Field_Getter_foo = new WeakMap(), _A_Field_Getter_instances = new WeakSet(), _A_Field_Getter_foo_get = function _A_Field_Getter_foo_get() { return ""; }; + _A_Field_Getter_foo = new WeakMap(); // Error class A_Field_Setter { - constructor() { - _A_Field_Setter_instances.add(this); - } + #foo = "foo"; + set #foo(value) { } } - _A_Field_Setter_foo = new WeakMap(), _A_Field_Setter_instances = new WeakSet(), _A_Field_Setter_foo_set = function _A_Field_Setter_foo_set(value) { }; + _A_Field_Setter_foo = new WeakMap(); // Error class A_Field_StaticField { - constructor() { - _A_Field_StaticField_foo_1 = { value: "foo" }; - } + #foo = "foo"; + static #foo = "foo"; } _a = A_Field_StaticField, _A_Field_StaticField_foo = new WeakMap(); _A_Field_StaticField_foo_1 = { value: "foo" }; // Error class A_Field_StaticMethod { - constructor() { - } + #foo = "foo"; + static #foo() { } } - _b = A_Field_StaticMethod, _A_Field_StaticMethod_foo = new WeakMap(), _A_Field_StaticMethod_foo_1 = function _A_Field_StaticMethod_foo_1() { }; + _b = A_Field_StaticMethod, _A_Field_StaticMethod_foo = new WeakMap(); // Error class A_Field_StaticGetter { - constructor() { - } + #foo = "foo"; + static get #foo() { return ""; } } - _c = A_Field_StaticGetter, _A_Field_StaticGetter_foo = new WeakMap(), _A_Field_StaticGetter_foo_get = function _A_Field_StaticGetter_foo_get() { return ""; }; + _c = A_Field_StaticGetter, _A_Field_StaticGetter_foo = new WeakMap(); // Error class A_Field_StaticSetter { - constructor() { - } + #foo = "foo"; + static set #foo(value) { } } - _d = A_Field_StaticSetter, _A_Field_StaticSetter_foo = new WeakMap(), _A_Field_StaticSetter_foo_set = function _A_Field_StaticSetter_foo_set(value) { }; + _d = A_Field_StaticSetter, _A_Field_StaticSetter_foo = new WeakMap(); } function Method() { var _A_Method_Field_instances, _A_Method_Field_foo, _A_Method_Field_foo_1, _A_Method_Method_instances, _A_Method_Method_foo, _A_Method_Method_foo_1, _A_Method_Getter_instances, _A_Method_Getter_foo, _A_Method_Getter_foo_get, _A_Method_Setter_instances, _A_Method_Setter_foo, _A_Method_Setter_foo_set, _A_Method_StaticField_instances, _a, _A_Method_StaticField_foo, _A_Method_StaticField_foo_1, _A_Method_StaticMethod_instances, _b, _A_Method_StaticMethod_foo, _A_Method_StaticMethod_foo_1, _A_Method_StaticGetter_instances, _c, _A_Method_StaticGetter_foo, _A_Method_StaticGetter_foo_get, _A_Method_StaticSetter_instances, _d, _A_Method_StaticSetter_foo, _A_Method_StaticSetter_foo_set; // Error class A_Method_Field { - constructor() { - _A_Method_Field_instances.add(this); - _A_Method_Field_foo_1.set(this, "foo"); - } + #foo() { } + #foo = "foo"; } - _A_Method_Field_foo_1 = new WeakMap(), _A_Method_Field_instances = new WeakSet(); // Error class A_Method_Method { - constructor() { - _A_Method_Method_instances.add(this); - } + #foo() { } + #foo() { } } - _A_Method_Method_instances = new WeakSet(), _A_Method_Method_foo_1 = function _A_Method_Method_foo_1() { }, _A_Method_Method_foo_1 = function _A_Method_Method_foo_1() { }; // Error class A_Method_Getter { - constructor() { - _A_Method_Getter_instances.add(this); - } + #foo() { } + get #foo() { return ""; } } - _A_Method_Getter_instances = new WeakSet(), _A_Method_Getter_foo_get = function _A_Method_Getter_foo_get() { return ""; }; // Error class A_Method_Setter { - constructor() { - _A_Method_Setter_instances.add(this); - } + #foo() { } + set #foo(value) { } } - _A_Method_Setter_instances = new WeakSet(), _A_Method_Setter_foo_set = function _A_Method_Setter_foo_set(value) { }; // Error class A_Method_StaticField { - constructor() { - _A_Method_StaticField_instances.add(this); - } + #foo() { } + static #foo = "foo"; } - _a = A_Method_StaticField, _A_Method_StaticField_instances = new WeakSet(); + _a = A_Method_StaticField; _A_Method_StaticField_foo_1 = { value: "foo" }; // Error class A_Method_StaticMethod { - constructor() { - _A_Method_StaticMethod_instances.add(this); - } + #foo() { } + static #foo() { } } - _b = A_Method_StaticMethod, _A_Method_StaticMethod_instances = new WeakSet(), _A_Method_StaticMethod_foo_1 = function _A_Method_StaticMethod_foo_1() { }, _A_Method_StaticMethod_foo_1 = function _A_Method_StaticMethod_foo_1() { }; + _b = A_Method_StaticMethod; // Error class A_Method_StaticGetter { - constructor() { - _A_Method_StaticGetter_instances.add(this); - } + #foo() { } + static get #foo() { return ""; } } - _c = A_Method_StaticGetter, _A_Method_StaticGetter_instances = new WeakSet(), _A_Method_StaticGetter_foo_get = function _A_Method_StaticGetter_foo_get() { return ""; }; + _c = A_Method_StaticGetter; // Error class A_Method_StaticSetter { - constructor() { - _A_Method_StaticSetter_instances.add(this); - } + #foo() { } + static set #foo(value) { } } - _d = A_Method_StaticSetter, _A_Method_StaticSetter_instances = new WeakSet(), _A_Method_StaticSetter_foo_set = function _A_Method_StaticSetter_foo_set(value) { }; + _d = A_Method_StaticSetter; } function Getter() { var _A_Getter_Field_instances, _A_Getter_Field_foo_get, _A_Getter_Field_foo, _A_Getter_Method_instances, _A_Getter_Method_foo_get, _A_Getter_Method_foo, _A_Getter_Getter_instances, _A_Getter_Getter_foo_get, _A_Getter_Getter_foo_get_1, _A_Getter_Setter_instances, _A_Getter_Setter_foo_get, _A_Getter_Setter_foo_set, _A_Getter_StaticField_instances, _a, _A_Getter_StaticField_foo_get, _A_Getter_StaticField_foo, _A_Getter_StaticMethod_instances, _b, _A_Getter_StaticMethod_foo_get, _A_Getter_StaticMethod_foo, _A_Getter_StaticGetter_instances, _c, _A_Getter_StaticGetter_foo_get, _A_Getter_StaticGetter_foo_get_1, _A_Getter_StaticSetter_instances, _d, _A_Getter_StaticSetter_foo_get, _A_Getter_StaticSetter_foo_set; // Error class A_Getter_Field { - constructor() { - _A_Getter_Field_instances.add(this); - _A_Getter_Field_foo.set(this, "foo"); - } + get #foo() { return ""; } + #foo = "foo"; } - _A_Getter_Field_foo = new WeakMap(), _A_Getter_Field_instances = new WeakSet(); // Error class A_Getter_Method { - constructor() { - _A_Getter_Method_instances.add(this); - } + get #foo() { return ""; } + #foo() { } } - _A_Getter_Method_instances = new WeakSet(), _A_Getter_Method_foo = function _A_Getter_Method_foo() { return ""; }, _A_Getter_Method_foo = function _A_Getter_Method_foo() { }; // Error class A_Getter_Getter { - constructor() { - _A_Getter_Getter_instances.add(this); - } + get #foo() { return ""; } + get #foo() { return ""; } } - _A_Getter_Getter_instances = new WeakSet(), _A_Getter_Getter_foo_get_1 = function _A_Getter_Getter_foo_get_1() { return ""; }, _A_Getter_Getter_foo_get_1 = function _A_Getter_Getter_foo_get_1() { return ""; }; //OK class A_Getter_Setter { constructor() { @@ -557,50 +531,41 @@ function Getter() { _A_Getter_Setter_instances = new WeakSet(), _A_Getter_Setter_foo_get = function _A_Getter_Setter_foo_get() { return ""; }, _A_Getter_Setter_foo_set = function _A_Getter_Setter_foo_set(value) { }; // Error class A_Getter_StaticField { - constructor() { - _A_Getter_StaticField_instances.add(this); - } + get #foo() { return ""; } + static #foo() { } } - _a = A_Getter_StaticField, _A_Getter_StaticField_instances = new WeakSet(), _A_Getter_StaticField_foo = function _A_Getter_StaticField_foo() { return ""; }, _A_Getter_StaticField_foo = function _A_Getter_StaticField_foo() { }; + _a = A_Getter_StaticField; // Error class A_Getter_StaticMethod { - constructor() { - _A_Getter_StaticMethod_instances.add(this); - } + get #foo() { return ""; } + static #foo() { } } - _b = A_Getter_StaticMethod, _A_Getter_StaticMethod_instances = new WeakSet(), _A_Getter_StaticMethod_foo = function _A_Getter_StaticMethod_foo() { return ""; }, _A_Getter_StaticMethod_foo = function _A_Getter_StaticMethod_foo() { }; + _b = A_Getter_StaticMethod; // Error class A_Getter_StaticGetter { - constructor() { - _A_Getter_StaticGetter_instances.add(this); - } + get #foo() { return ""; } + static get #foo() { return ""; } } - _c = A_Getter_StaticGetter, _A_Getter_StaticGetter_instances = new WeakSet(), _A_Getter_StaticGetter_foo_get_1 = function _A_Getter_StaticGetter_foo_get_1() { return ""; }, _A_Getter_StaticGetter_foo_get_1 = function _A_Getter_StaticGetter_foo_get_1() { return ""; }; + _c = A_Getter_StaticGetter; // Error class A_Getter_StaticSetter { - constructor() { - _A_Getter_StaticSetter_instances.add(this); - } + get #foo() { return ""; } + static set #foo(value) { } } - _d = A_Getter_StaticSetter, _A_Getter_StaticSetter_instances = new WeakSet(), _A_Getter_StaticSetter_foo_get = function _A_Getter_StaticSetter_foo_get() { return ""; }, _A_Getter_StaticSetter_foo_set = function _A_Getter_StaticSetter_foo_set(value) { }; + _d = A_Getter_StaticSetter; } function Setter() { var _A_Setter_Field_instances, _A_Setter_Field_foo_set, _A_Setter_Field_foo, _A_Setter_Method_instances, _A_Setter_Method_foo_set, _A_Setter_Method_foo, _A_Setter_Getter_instances, _A_Setter_Getter_foo_set, _A_Setter_Getter_foo_get, _A_Setter_Setter_instances, _A_Setter_Setter_foo_set, _A_Setter_Setter_foo_set_1, _A_Setter_StaticField_instances, _a, _A_Setter_StaticField_foo_set, _A_Setter_StaticField_foo, _A_Setter_StaticMethod_instances, _b, _A_Setter_StaticMethod_foo_set, _A_Setter_StaticMethod_foo, _A_Setter_StaticGetter_instances, _c, _A_Setter_StaticGetter_foo_set, _A_Setter_StaticGetter_foo_get, _A_Setter_StaticSetter_instances, _d, _A_Setter_StaticSetter_foo_set, _A_Setter_StaticSetter_foo_set_1; // Error class A_Setter_Field { - constructor() { - _A_Setter_Field_instances.add(this); - _A_Setter_Field_foo.set(this, "foo"); - } + set #foo(value) { } + #foo = "foo"; } - _A_Setter_Field_foo = new WeakMap(), _A_Setter_Field_instances = new WeakSet(); // Error class A_Setter_Method { - constructor() { - _A_Setter_Method_instances.add(this); - } + set #foo(value) { } + #foo() { } } - _A_Setter_Method_instances = new WeakSet(), _A_Setter_Method_foo = function _A_Setter_Method_foo(value) { }, _A_Setter_Method_foo = function _A_Setter_Method_foo() { }; // OK class A_Setter_Getter { constructor() { @@ -610,181 +575,185 @@ function Setter() { _A_Setter_Getter_instances = new WeakSet(), _A_Setter_Getter_foo_set = function _A_Setter_Getter_foo_set(value) { }, _A_Setter_Getter_foo_get = function _A_Setter_Getter_foo_get() { return ""; }; // Error class A_Setter_Setter { - constructor() { - _A_Setter_Setter_instances.add(this); - } + set #foo(value) { } + set #foo(value) { } } - _A_Setter_Setter_instances = new WeakSet(), _A_Setter_Setter_foo_set_1 = function _A_Setter_Setter_foo_set_1(value) { }, _A_Setter_Setter_foo_set_1 = function _A_Setter_Setter_foo_set_1(value) { }; // Error class A_Setter_StaticField { - constructor() { - _A_Setter_StaticField_instances.add(this); - } + set #foo(value) { } + static #foo = "foo"; } - _a = A_Setter_StaticField, _A_Setter_StaticField_instances = new WeakSet(); + _a = A_Setter_StaticField; _A_Setter_StaticField_foo = { value: "foo" }; // Error class A_Setter_StaticMethod { - constructor() { - _A_Setter_StaticMethod_instances.add(this); - } + set #foo(value) { } + static #foo() { } } - _b = A_Setter_StaticMethod, _A_Setter_StaticMethod_instances = new WeakSet(), _A_Setter_StaticMethod_foo = function _A_Setter_StaticMethod_foo(value) { }, _A_Setter_StaticMethod_foo = function _A_Setter_StaticMethod_foo() { }; + _b = A_Setter_StaticMethod; // Error class A_Setter_StaticGetter { - constructor() { - _A_Setter_StaticGetter_instances.add(this); - } + set #foo(value) { } + static get #foo() { return ""; } } - _c = A_Setter_StaticGetter, _A_Setter_StaticGetter_instances = new WeakSet(), _A_Setter_StaticGetter_foo_set = function _A_Setter_StaticGetter_foo_set(value) { }, _A_Setter_StaticGetter_foo_get = function _A_Setter_StaticGetter_foo_get() { return ""; }; + _c = A_Setter_StaticGetter; // Error class A_Setter_StaticSetter { - constructor() { - _A_Setter_StaticSetter_instances.add(this); - } + set #foo(value) { } + static set #foo(value) { } } - _d = A_Setter_StaticSetter, _A_Setter_StaticSetter_instances = new WeakSet(), _A_Setter_StaticSetter_foo_set_1 = function _A_Setter_StaticSetter_foo_set_1(value) { }, _A_Setter_StaticSetter_foo_set_1 = function _A_Setter_StaticSetter_foo_set_1(value) { }; + _d = A_Setter_StaticSetter; } function StaticField() { var _a, _A_StaticField_Field_foo, _A_StaticField_Field_foo_1, _A_StaticField_Method_instances, _b, _A_StaticField_Method_foo, _A_StaticField_Method_foo_1, _A_StaticField_Getter_instances, _c, _A_StaticField_Getter_foo, _A_StaticField_Getter_foo_get, _A_StaticField_Setter_instances, _d, _A_StaticField_Setter_foo, _A_StaticField_Setter_foo_set, _e, _A_StaticField_StaticField_foo, _A_StaticField_StaticField_foo_1, _f, _A_StaticField_StaticMethod_foo, _A_StaticField_StaticMethod_foo_1, _g, _A_StaticField_StaticGetter_foo, _A_StaticField_StaticGetter_foo_get, _h, _A_StaticField_StaticSetter_foo, _A_StaticField_StaticSetter_foo_set; // Error class A_StaticField_Field { - constructor() { - _A_StaticField_Field_foo_1.set(this, "foo"); - } + static #foo = "foo"; + #foo = "foo"; } - _a = A_StaticField_Field, _A_StaticField_Field_foo_1 = new WeakMap(); + _a = A_StaticField_Field; _A_StaticField_Field_foo_1.set(A_StaticField_Field, "foo"); // Error class A_StaticField_Method { - constructor() { - _A_StaticField_Method_instances.add(this); - } + static #foo = "foo"; + #foo() { } } - _b = A_StaticField_Method, _A_StaticField_Method_instances = new WeakSet(), _A_StaticField_Method_foo_1 = function _A_StaticField_Method_foo_1() { }; + _b = A_StaticField_Method; // Error class A_StaticField_Getter { - constructor() { - _A_StaticField_Getter_instances.add(this); - } + static #foo = "foo"; + get #foo() { return ""; } } - _c = A_StaticField_Getter, _A_StaticField_Getter_instances = new WeakSet(), _A_StaticField_Getter_foo_get = function _A_StaticField_Getter_foo_get() { return ""; }; + _c = A_StaticField_Getter; // Error class A_StaticField_Setter { - constructor() { - _A_StaticField_Setter_instances.add(this); - } + static #foo = "foo"; + set #foo(value) { } } - _d = A_StaticField_Setter, _A_StaticField_Setter_instances = new WeakSet(), _A_StaticField_Setter_foo_set = function _A_StaticField_Setter_foo_set(value) { }; + _d = A_StaticField_Setter; // Error class A_StaticField_StaticField { + static #foo = "foo"; + static #foo = "foo"; } _e = A_StaticField_StaticField; _A_StaticField_StaticField_foo_1 = { value: "foo" }; _A_StaticField_StaticField_foo_1 = { value: "foo" }; // Error class A_StaticField_StaticMethod { + static #foo = "foo"; + static #foo() { } } - _f = A_StaticField_StaticMethod, _A_StaticField_StaticMethod_foo_1 = function _A_StaticField_StaticMethod_foo_1() { }; + _f = A_StaticField_StaticMethod; // Error class A_StaticField_StaticGetter { + static #foo = "foo"; + static get #foo() { return ""; } } - _g = A_StaticField_StaticGetter, _A_StaticField_StaticGetter_foo_get = function _A_StaticField_StaticGetter_foo_get() { return ""; }; + _g = A_StaticField_StaticGetter; // Error class A_StaticField_StaticSetter { + static #foo = "foo"; + static set #foo(value) { } } - _h = A_StaticField_StaticSetter, _A_StaticField_StaticSetter_foo_set = function _A_StaticField_StaticSetter_foo_set(value) { }; + _h = A_StaticField_StaticSetter; } function StaticMethod() { var _a, _A_StaticMethod_Field_foo, _A_StaticMethod_Field_foo_1, _A_StaticMethod_Method_instances, _b, _A_StaticMethod_Method_foo, _A_StaticMethod_Method_foo_1, _A_StaticMethod_Getter_instances, _c, _A_StaticMethod_Getter_foo, _A_StaticMethod_Getter_foo_get, _A_StaticMethod_Setter_instances, _d, _A_StaticMethod_Setter_foo, _A_StaticMethod_Setter_foo_set, _e, _A_StaticMethod_StaticField_foo, _A_StaticMethod_StaticField_foo_1, _f, _A_StaticMethod_StaticMethod_foo, _A_StaticMethod_StaticMethod_foo_1, _g, _A_StaticMethod_StaticGetter_foo, _A_StaticMethod_StaticGetter_foo_get, _h, _A_StaticMethod_StaticSetter_foo, _A_StaticMethod_StaticSetter_foo_set; // Error class A_StaticMethod_Field { - constructor() { - _A_StaticMethod_Field_foo_1.set(this, "foo"); - } + static #foo() { } + #foo = "foo"; } - _a = A_StaticMethod_Field, _A_StaticMethod_Field_foo_1 = new WeakMap(); + _a = A_StaticMethod_Field; // Error class A_StaticMethod_Method { - constructor() { - _A_StaticMethod_Method_instances.add(this); - } + static #foo() { } + #foo() { } } - _b = A_StaticMethod_Method, _A_StaticMethod_Method_instances = new WeakSet(), _A_StaticMethod_Method_foo_1 = function _A_StaticMethod_Method_foo_1() { }, _A_StaticMethod_Method_foo_1 = function _A_StaticMethod_Method_foo_1() { }; + _b = A_StaticMethod_Method; // Error class A_StaticMethod_Getter { - constructor() { - _A_StaticMethod_Getter_instances.add(this); - } + static #foo() { } + get #foo() { return ""; } } - _c = A_StaticMethod_Getter, _A_StaticMethod_Getter_instances = new WeakSet(), _A_StaticMethod_Getter_foo_get = function _A_StaticMethod_Getter_foo_get() { return ""; }; + _c = A_StaticMethod_Getter; // Error class A_StaticMethod_Setter { - constructor() { - _A_StaticMethod_Setter_instances.add(this); - } + static #foo() { } + set #foo(value) { } } - _d = A_StaticMethod_Setter, _A_StaticMethod_Setter_instances = new WeakSet(), _A_StaticMethod_Setter_foo_set = function _A_StaticMethod_Setter_foo_set(value) { }; + _d = A_StaticMethod_Setter; // Error class A_StaticMethod_StaticField { + static #foo() { } + static #foo = "foo"; } _e = A_StaticMethod_StaticField; _A_StaticMethod_StaticField_foo_1 = { value: "foo" }; // Error class A_StaticMethod_StaticMethod { + static #foo() { } + static #foo() { } } - _f = A_StaticMethod_StaticMethod, _A_StaticMethod_StaticMethod_foo_1 = function _A_StaticMethod_StaticMethod_foo_1() { }, _A_StaticMethod_StaticMethod_foo_1 = function _A_StaticMethod_StaticMethod_foo_1() { }; + _f = A_StaticMethod_StaticMethod; // Error class A_StaticMethod_StaticGetter { + static #foo() { } + static get #foo() { return ""; } } - _g = A_StaticMethod_StaticGetter, _A_StaticMethod_StaticGetter_foo_get = function _A_StaticMethod_StaticGetter_foo_get() { return ""; }; + _g = A_StaticMethod_StaticGetter; // Error class A_StaticMethod_StaticSetter { + static #foo() { } + static set #foo(value) { } } - _h = A_StaticMethod_StaticSetter, _A_StaticMethod_StaticSetter_foo_set = function _A_StaticMethod_StaticSetter_foo_set(value) { }; + _h = A_StaticMethod_StaticSetter; } function StaticGetter() { var _a, _A_StaticGetter_Field_foo_get, _A_StaticGetter_Field_foo, _A_StaticGetter_Method_instances, _b, _A_StaticGetter_Method_foo_get, _A_StaticGetter_Method_foo, _A_StaticGetter_Getter_instances, _c, _A_StaticGetter_Getter_foo_get, _A_StaticGetter_Getter_foo_get_1, _A_StaticGetter_Setter_instances, _d, _A_StaticGetter_Setter_foo_get, _A_StaticGetter_Setter_foo_set, _e, _A_StaticGetter_StaticField_foo_get, _A_StaticGetter_StaticField_foo, _f, _A_StaticGetter_StaticMethod_foo_get, _A_StaticGetter_StaticMethod_foo, _g, _A_StaticGetter_StaticGetter_foo_get, _A_StaticGetter_StaticGetter_foo_get_1, _h, _A_StaticGetter_StaticSetter_foo_get, _A_StaticGetter_StaticSetter_foo_set; // Error class A_StaticGetter_Field { - constructor() { - _A_StaticGetter_Field_foo.set(this, "foo"); - } + static get #foo() { return ""; } + #foo = "foo"; } - _a = A_StaticGetter_Field, _A_StaticGetter_Field_foo = new WeakMap(); + _a = A_StaticGetter_Field; // Error class A_StaticGetter_Method { - constructor() { - _A_StaticGetter_Method_instances.add(this); - } + static get #foo() { return ""; } + #foo() { } } - _b = A_StaticGetter_Method, _A_StaticGetter_Method_instances = new WeakSet(), _A_StaticGetter_Method_foo = function _A_StaticGetter_Method_foo() { return ""; }, _A_StaticGetter_Method_foo = function _A_StaticGetter_Method_foo() { }; + _b = A_StaticGetter_Method; // Error class A_StaticGetter_Getter { - constructor() { - _A_StaticGetter_Getter_instances.add(this); - } + static get #foo() { return ""; } + get #foo() { return ""; } } - _c = A_StaticGetter_Getter, _A_StaticGetter_Getter_instances = new WeakSet(), _A_StaticGetter_Getter_foo_get_1 = function _A_StaticGetter_Getter_foo_get_1() { return ""; }, _A_StaticGetter_Getter_foo_get_1 = function _A_StaticGetter_Getter_foo_get_1() { return ""; }; + _c = A_StaticGetter_Getter; // Error class A_StaticGetter_Setter { - constructor() { - _A_StaticGetter_Setter_instances.add(this); - } + static get #foo() { return ""; } + set #foo(value) { } } - _d = A_StaticGetter_Setter, _A_StaticGetter_Setter_instances = new WeakSet(), _A_StaticGetter_Setter_foo_get = function _A_StaticGetter_Setter_foo_get() { return ""; }, _A_StaticGetter_Setter_foo_set = function _A_StaticGetter_Setter_foo_set(value) { }; + _d = A_StaticGetter_Setter; // Error class A_StaticGetter_StaticField { + static get #foo() { return ""; } + static #foo() { } } - _e = A_StaticGetter_StaticField, _A_StaticGetter_StaticField_foo = function _A_StaticGetter_StaticField_foo() { return ""; }, _A_StaticGetter_StaticField_foo = function _A_StaticGetter_StaticField_foo() { }; + _e = A_StaticGetter_StaticField; // Error class A_StaticGetter_StaticMethod { + static get #foo() { return ""; } + static #foo() { } } - _f = A_StaticGetter_StaticMethod, _A_StaticGetter_StaticMethod_foo = function _A_StaticGetter_StaticMethod_foo() { return ""; }, _A_StaticGetter_StaticMethod_foo = function _A_StaticGetter_StaticMethod_foo() { }; + _f = A_StaticGetter_StaticMethod; // Error class A_StaticGetter_StaticGetter { + static get #foo() { return ""; } + static get #foo() { return ""; } } - _g = A_StaticGetter_StaticGetter, _A_StaticGetter_StaticGetter_foo_get_1 = function _A_StaticGetter_StaticGetter_foo_get_1() { return ""; }, _A_StaticGetter_StaticGetter_foo_get_1 = function _A_StaticGetter_StaticGetter_foo_get_1() { return ""; }; + _g = A_StaticGetter_StaticGetter; // OK class A_StaticGetter_StaticSetter { } @@ -794,47 +763,49 @@ function StaticSetter() { var _a, _A_StaticSetter_Field_foo_set, _A_StaticSetter_Field_foo, _A_StaticSetter_Method_instances, _b, _A_StaticSetter_Method_foo_set, _A_StaticSetter_Method_foo, _A_StaticSetter_Getter_instances, _c, _A_StaticSetter_Getter_foo_set, _A_StaticSetter_Getter_foo_get, _A_StaticSetter_Setter_instances, _d, _A_StaticSetter_Setter_foo_set, _A_StaticSetter_Setter_foo_set_1, _e, _A_StaticSetter_StaticField_foo_set, _A_StaticSetter_StaticField_foo, _f, _A_StaticSetter_StaticMethod_foo_set, _A_StaticSetter_StaticMethod_foo, _g, _A_StaticSetter_StaticGetter_foo_set, _A_StaticSetter_StaticGetter_foo_get, _h, _A_StaticSetter_StaticSetter_foo_set, _A_StaticSetter_StaticSetter_foo_set_1; // Error class A_StaticSetter_Field { - constructor() { - _A_StaticSetter_Field_foo.set(this, "foo"); - } + static set #foo(value) { } + #foo = "foo"; } - _a = A_StaticSetter_Field, _A_StaticSetter_Field_foo = new WeakMap(); + _a = A_StaticSetter_Field; // Error class A_StaticSetter_Method { - constructor() { - _A_StaticSetter_Method_instances.add(this); - } + static set #foo(value) { } + #foo() { } } - _b = A_StaticSetter_Method, _A_StaticSetter_Method_instances = new WeakSet(), _A_StaticSetter_Method_foo = function _A_StaticSetter_Method_foo(value) { }, _A_StaticSetter_Method_foo = function _A_StaticSetter_Method_foo() { }; + _b = A_StaticSetter_Method; // Error class A_StaticSetter_Getter { - constructor() { - _A_StaticSetter_Getter_instances.add(this); - } + static set #foo(value) { } + get #foo() { return ""; } } - _c = A_StaticSetter_Getter, _A_StaticSetter_Getter_instances = new WeakSet(), _A_StaticSetter_Getter_foo_set = function _A_StaticSetter_Getter_foo_set(value) { }, _A_StaticSetter_Getter_foo_get = function _A_StaticSetter_Getter_foo_get() { return ""; }; + _c = A_StaticSetter_Getter; // Error class A_StaticSetter_Setter { - constructor() { - _A_StaticSetter_Setter_instances.add(this); - } + static set #foo(value) { } + set #foo(value) { } } - _d = A_StaticSetter_Setter, _A_StaticSetter_Setter_instances = new WeakSet(), _A_StaticSetter_Setter_foo_set_1 = function _A_StaticSetter_Setter_foo_set_1(value) { }, _A_StaticSetter_Setter_foo_set_1 = function _A_StaticSetter_Setter_foo_set_1(value) { }; + _d = A_StaticSetter_Setter; // Error class A_StaticSetter_StaticField { + static set #foo(value) { } + static #foo = "foo"; } _e = A_StaticSetter_StaticField; _A_StaticSetter_StaticField_foo = { value: "foo" }; // Error class A_StaticSetter_StaticMethod { + static set #foo(value) { } + static #foo() { } } - _f = A_StaticSetter_StaticMethod, _A_StaticSetter_StaticMethod_foo = function _A_StaticSetter_StaticMethod_foo(value) { }, _A_StaticSetter_StaticMethod_foo = function _A_StaticSetter_StaticMethod_foo() { }; + _f = A_StaticSetter_StaticMethod; // OK class A_StaticSetter_StaticGetter { } _g = A_StaticSetter_StaticGetter, _A_StaticSetter_StaticGetter_foo_set = function _A_StaticSetter_StaticGetter_foo_set(value) { }, _A_StaticSetter_StaticGetter_foo_get = function _A_StaticSetter_StaticGetter_foo_get() { return ""; }; // Error class A_StaticSetter_StaticSetter { + static set #foo(value) { } + static set #foo(value) { } } - _h = A_StaticSetter_StaticSetter, _A_StaticSetter_StaticSetter_foo_set_1 = function _A_StaticSetter_StaticSetter_foo_set_1(value) { }, _A_StaticSetter_StaticSetter_foo_set_1 = function _A_StaticSetter_StaticSetter_foo_set_1(value) { }; + _h = A_StaticSetter_StaticSetter; } diff --git a/tests/baselines/reference/privateNamesUnique-3.js b/tests/baselines/reference/privateNamesUnique-3.js index 0447e3cf6f852..23fb6a0098fba 100644 --- a/tests/baselines/reference/privateNamesUnique-3.js +++ b/tests/baselines/reference/privateNamesUnique-3.js @@ -22,12 +22,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( }; var _a, _A_foo, _A_foo_1, _b, _B_foo; class A { - constructor() { - _A_foo_1 = { value: 1 }; - // because static and instance private names - // share the same lexical scope - // https://tc39.es/proposal-class-fields/#prod-ClassBody - } + #foo = 1; + static #foo = true; // error (duplicate) } _a = A, _A_foo = new WeakMap(); _A_foo_1 = { value: true }; // error (duplicate) From daab99027808b8833d0a62d751f737331bcb67d2 Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Fri, 19 Mar 2021 16:07:07 +0000 Subject: [PATCH 3/3] do not abort early, leave invalid declarations untransformed --- src/compiler/transformers/classFields.ts | 85 +++---- .../reference/privateNameDuplicateField.js | 213 +++++++++++++++--- .../reference/privateNamesUnique-3.js | 6 + 3 files changed, 230 insertions(+), 74 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 9a9df723b204a..326ecdfeab343 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -24,6 +24,11 @@ namespace ts { * Stores if the identifier is static or not */ isStatic: boolean; + /** + * Stores if the identifier declaration is valid or not. Reserved names (e.g. #constructor) + * or duplicate identifiers are considered invalid. + */ + isValid: boolean; } interface PrivateIdentifierAccessorInfo extends PrivateIdentifierInfoBase { kind: PrivateIdentifierKind.Accessor; @@ -260,8 +265,10 @@ namespace ts { return visitEachChild(node, classElementVisitor, context); } - // leave invalid code as it is - if (isReservedPrivateName(node)) { + // leave invalid code untransformed + const info = accessPrivateIdentifier(node.name); + Debug.assert(info, "Undeclared private name for property declaration."); + if (!info.isValid) { return node; } @@ -309,22 +316,26 @@ namespace ts { function visitPropertyDeclaration(node: PropertyDeclaration) { Debug.assert(!some(node.decorators)); - // leave invalid code as it is - if (isReservedPrivateName(node)) { - return node; - } + if (isPrivateIdentifier(node.name)) { + if (!shouldTransformPrivateElements) { + // Initializer is elided as the field is initialized in transformConstructor. + return factory.updatePropertyDeclaration( + node, + /*decorators*/ undefined, + visitNodes(node.modifiers, visitor, isModifier), + node.name, + /*questionOrExclamationToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ); + } - if (!shouldTransformPrivateElements && isPrivateIdentifier(node.name)) { - // Initializer is elided as the field is initialized in transformConstructor. - return factory.updatePropertyDeclaration( - node, - /*decorators*/ undefined, - visitNodes(node.modifiers, visitor, isModifier), - node.name, - /*questionOrExclamationToken*/ undefined, - /*type*/ undefined, - /*initializer*/ undefined - ); + // leave invalid code untransformed + const info = accessPrivateIdentifier(node.name); + Debug.assert(info, "Undeclared private name for property declaration."); + if (!info.isValid) { + return node; + } } // Create a temporary variable to store a computed property name (if necessary). // If it's not inlineable, then we emit an expression after the class which assigns @@ -770,11 +781,7 @@ namespace ts { // Declare private names. for (const member of node.members) { if (isPrivateIdentifierClassElementDeclaration(member)) { - const error = addPrivateIdentifierToEnvironment(member); - if (error) { - // leave invalid code as it is - return node.members; - } + addPrivateIdentifierToEnvironment(member); } } @@ -1172,14 +1179,15 @@ namespace ts { return pendingExpressions || (pendingExpressions = []); } - function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration): Error | void { + function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration) { const text = getTextOfPropertyName(node.name) as string; const env = getPrivateIdentifierEnvironment(); const { weakSetName, classConstructor } = env; const assignmentExpressions: Expression[] = []; const privateName = node.name.escapedText; - let potentialDuplicatePrivateName = env.identifiers.has(privateName); + const previousInfo = env.identifiers.get(privateName); + const isValid = !isReservedPrivateName(node.name) && previousInfo === undefined; if (hasStaticModifier(node)) { Debug.assert(classConstructor, "weakSetName should be set in private identifier environment"); @@ -1190,6 +1198,7 @@ namespace ts { variableName, brandCheckIdentifier: classConstructor, isStatic: true, + isValid, }); } else if (isMethodDeclaration(node)) { @@ -1199,13 +1208,12 @@ namespace ts { methodName: functionName, brandCheckIdentifier: classConstructor, isStatic: true, + isValid, }); } else if (isGetAccessorDeclaration(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); - const previousInfo = env.identifiers.get(privateName); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.getterName) { - potentialDuplicatePrivateName = false; previousInfo.getterName = getterName; } else { @@ -1215,14 +1223,13 @@ namespace ts { setterName: undefined, brandCheckIdentifier: classConstructor, isStatic: true, + isValid, }); } } else if (isSetAccessorDeclaration(node)) { const setterName = createHoistedVariableForPrivateName(text + "_set", node); - const previousInfo = env.identifiers.get(privateName); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.setterName) { - potentialDuplicatePrivateName = false; previousInfo.setterName = setterName; } else { @@ -1232,6 +1239,7 @@ namespace ts { setterName, brandCheckIdentifier: classConstructor, isStatic: true, + isValid, }); } } @@ -1245,7 +1253,8 @@ namespace ts { kind: PrivateIdentifierKind.Field, brandCheckIdentifier: weakMapName, isStatic: false, - variableName: undefined + variableName: undefined, + isValid, }); assignmentExpressions.push(factory.createAssignment( @@ -1265,17 +1274,16 @@ namespace ts { methodName: createHoistedVariableForPrivateName(text, node), brandCheckIdentifier: weakSetName, isStatic: false, + isValid, }); } else if (isAccessor(node)) { Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - const previousInfo = env.identifiers.get(privateName); if (isGetAccessor(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && !previousInfo.isStatic && !previousInfo.getterName) { - potentialDuplicatePrivateName = false; previousInfo.getterName = getterName; } else { @@ -1285,6 +1293,7 @@ namespace ts { setterName: undefined, brandCheckIdentifier: weakSetName, isStatic: false, + isValid, }); } } @@ -1292,7 +1301,6 @@ namespace ts { const setterName = createHoistedVariableForPrivateName(text + "_set", node); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && !previousInfo.isStatic && !previousInfo.setterName) { - potentialDuplicatePrivateName = false; previousInfo.setterName = setterName; } else { @@ -1302,6 +1310,7 @@ namespace ts { setterName, brandCheckIdentifier: weakSetName, isStatic: false, + isValid, }); } } @@ -1310,10 +1319,6 @@ namespace ts { Debug.assertNever(node, "Unknown class element type."); } - if (potentialDuplicatePrivateName) { - return new Error("Duplicate private name"); - } - getPendingExpressions().push(...assignmentExpressions); } @@ -1503,11 +1508,7 @@ namespace ts { ); } - function isReservedPrivateName(node: ClassElement) { - if (!node.name || !isPrivateIdentifier(node.name)) { - return false; - } - - return getTextOfPropertyName(node.name) === "#constructor"; + function isReservedPrivateName(node: PrivateIdentifier) { + return node.escapedText === "#constructor"; } } diff --git a/tests/baselines/reference/privateNameDuplicateField.js b/tests/baselines/reference/privateNameDuplicateField.js index 717a4fca7d78c..3b59b74ad8165 100644 --- a/tests/baselines/reference/privateNameDuplicateField.js +++ b/tests/baselines/reference/privateNameDuplicateField.js @@ -409,30 +409,46 @@ function Field() { var _A_Field_Field_foo, _A_Field_Field_foo_1, _A_Field_Method_instances, _A_Field_Method_foo, _A_Field_Method_foo_1, _A_Field_Getter_instances, _A_Field_Getter_foo, _A_Field_Getter_foo_get, _A_Field_Setter_instances, _A_Field_Setter_foo, _A_Field_Setter_foo_set, _a, _A_Field_StaticField_foo, _A_Field_StaticField_foo_1, _b, _A_Field_StaticMethod_foo, _A_Field_StaticMethod_foo_1, _c, _A_Field_StaticGetter_foo, _A_Field_StaticGetter_foo_get, _d, _A_Field_StaticSetter_foo, _A_Field_StaticSetter_foo_set; // Error class A_Field_Field { + constructor() { + _A_Field_Field_foo_1.set(this, "foo"); + _A_Field_Field_foo_1.set(this, "foo"); + } #foo = "foo"; #foo = "foo"; } - _A_Field_Field_foo = new WeakMap(); + _A_Field_Field_foo = new WeakMap(), _A_Field_Field_foo_1 = new WeakMap(); // Error class A_Field_Method { + constructor() { + _A_Field_Method_instances.add(this); + } #foo = "foo"; #foo() { } } - _A_Field_Method_foo = new WeakMap(); + _A_Field_Method_foo = new WeakMap(), _A_Field_Method_instances = new WeakSet(); // Error class A_Field_Getter { + constructor() { + _A_Field_Getter_instances.add(this); + } #foo = "foo"; get #foo() { return ""; } } - _A_Field_Getter_foo = new WeakMap(); + _A_Field_Getter_foo = new WeakMap(), _A_Field_Getter_instances = new WeakSet(); // Error class A_Field_Setter { + constructor() { + _A_Field_Setter_instances.add(this); + } #foo = "foo"; set #foo(value) { } } - _A_Field_Setter_foo = new WeakMap(); + _A_Field_Setter_foo = new WeakMap(), _A_Field_Setter_instances = new WeakSet(); // Error class A_Field_StaticField { + constructor() { + _A_Field_StaticField_foo_1 = { value: "foo" }; + } #foo = "foo"; static #foo = "foo"; } @@ -440,18 +456,24 @@ function Field() { _A_Field_StaticField_foo_1 = { value: "foo" }; // Error class A_Field_StaticMethod { + constructor() { + } #foo = "foo"; static #foo() { } } _b = A_Field_StaticMethod, _A_Field_StaticMethod_foo = new WeakMap(); // Error class A_Field_StaticGetter { + constructor() { + } #foo = "foo"; static get #foo() { return ""; } } _c = A_Field_StaticGetter, _A_Field_StaticGetter_foo = new WeakMap(); // Error class A_Field_StaticSetter { + constructor() { + } #foo = "foo"; static set #foo(value) { } } @@ -461,67 +483,109 @@ function Method() { var _A_Method_Field_instances, _A_Method_Field_foo, _A_Method_Field_foo_1, _A_Method_Method_instances, _A_Method_Method_foo, _A_Method_Method_foo_1, _A_Method_Getter_instances, _A_Method_Getter_foo, _A_Method_Getter_foo_get, _A_Method_Setter_instances, _A_Method_Setter_foo, _A_Method_Setter_foo_set, _A_Method_StaticField_instances, _a, _A_Method_StaticField_foo, _A_Method_StaticField_foo_1, _A_Method_StaticMethod_instances, _b, _A_Method_StaticMethod_foo, _A_Method_StaticMethod_foo_1, _A_Method_StaticGetter_instances, _c, _A_Method_StaticGetter_foo, _A_Method_StaticGetter_foo_get, _A_Method_StaticSetter_instances, _d, _A_Method_StaticSetter_foo, _A_Method_StaticSetter_foo_set; // Error class A_Method_Field { + constructor() { + _A_Method_Field_instances.add(this); + _A_Method_Field_foo_1.set(this, "foo"); + } #foo() { } #foo = "foo"; } + _A_Method_Field_foo_1 = new WeakMap(), _A_Method_Field_instances = new WeakSet(); // Error class A_Method_Method { + constructor() { + _A_Method_Method_instances.add(this); + } #foo() { } #foo() { } } + _A_Method_Method_instances = new WeakSet(); // Error class A_Method_Getter { + constructor() { + _A_Method_Getter_instances.add(this); + } #foo() { } get #foo() { return ""; } } + _A_Method_Getter_instances = new WeakSet(); // Error class A_Method_Setter { + constructor() { + _A_Method_Setter_instances.add(this); + } #foo() { } set #foo(value) { } } + _A_Method_Setter_instances = new WeakSet(); // Error class A_Method_StaticField { + constructor() { + _A_Method_StaticField_instances.add(this); + } #foo() { } static #foo = "foo"; } - _a = A_Method_StaticField; + _a = A_Method_StaticField, _A_Method_StaticField_instances = new WeakSet(); _A_Method_StaticField_foo_1 = { value: "foo" }; // Error class A_Method_StaticMethod { + constructor() { + _A_Method_StaticMethod_instances.add(this); + } #foo() { } static #foo() { } } - _b = A_Method_StaticMethod; + _b = A_Method_StaticMethod, _A_Method_StaticMethod_instances = new WeakSet(); // Error class A_Method_StaticGetter { + constructor() { + _A_Method_StaticGetter_instances.add(this); + } #foo() { } static get #foo() { return ""; } } - _c = A_Method_StaticGetter; + _c = A_Method_StaticGetter, _A_Method_StaticGetter_instances = new WeakSet(); // Error class A_Method_StaticSetter { + constructor() { + _A_Method_StaticSetter_instances.add(this); + } #foo() { } static set #foo(value) { } } - _d = A_Method_StaticSetter; + _d = A_Method_StaticSetter, _A_Method_StaticSetter_instances = new WeakSet(); } function Getter() { var _A_Getter_Field_instances, _A_Getter_Field_foo_get, _A_Getter_Field_foo, _A_Getter_Method_instances, _A_Getter_Method_foo_get, _A_Getter_Method_foo, _A_Getter_Getter_instances, _A_Getter_Getter_foo_get, _A_Getter_Getter_foo_get_1, _A_Getter_Setter_instances, _A_Getter_Setter_foo_get, _A_Getter_Setter_foo_set, _A_Getter_StaticField_instances, _a, _A_Getter_StaticField_foo_get, _A_Getter_StaticField_foo, _A_Getter_StaticMethod_instances, _b, _A_Getter_StaticMethod_foo_get, _A_Getter_StaticMethod_foo, _A_Getter_StaticGetter_instances, _c, _A_Getter_StaticGetter_foo_get, _A_Getter_StaticGetter_foo_get_1, _A_Getter_StaticSetter_instances, _d, _A_Getter_StaticSetter_foo_get, _A_Getter_StaticSetter_foo_set; // Error class A_Getter_Field { + constructor() { + _A_Getter_Field_instances.add(this); + _A_Getter_Field_foo.set(this, "foo"); + } get #foo() { return ""; } #foo = "foo"; } + _A_Getter_Field_foo = new WeakMap(), _A_Getter_Field_instances = new WeakSet(); // Error class A_Getter_Method { + constructor() { + _A_Getter_Method_instances.add(this); + } get #foo() { return ""; } #foo() { } } + _A_Getter_Method_instances = new WeakSet(); // Error class A_Getter_Getter { + constructor() { + _A_Getter_Getter_instances.add(this); + } get #foo() { return ""; } get #foo() { return ""; } } + _A_Getter_Getter_instances = new WeakSet(); //OK class A_Getter_Setter { constructor() { @@ -531,41 +595,62 @@ function Getter() { _A_Getter_Setter_instances = new WeakSet(), _A_Getter_Setter_foo_get = function _A_Getter_Setter_foo_get() { return ""; }, _A_Getter_Setter_foo_set = function _A_Getter_Setter_foo_set(value) { }; // Error class A_Getter_StaticField { + constructor() { + _A_Getter_StaticField_instances.add(this); + } get #foo() { return ""; } static #foo() { } } - _a = A_Getter_StaticField; + _a = A_Getter_StaticField, _A_Getter_StaticField_instances = new WeakSet(); // Error class A_Getter_StaticMethod { + constructor() { + _A_Getter_StaticMethod_instances.add(this); + } get #foo() { return ""; } static #foo() { } } - _b = A_Getter_StaticMethod; + _b = A_Getter_StaticMethod, _A_Getter_StaticMethod_instances = new WeakSet(); // Error class A_Getter_StaticGetter { + constructor() { + _A_Getter_StaticGetter_instances.add(this); + } get #foo() { return ""; } static get #foo() { return ""; } } - _c = A_Getter_StaticGetter; + _c = A_Getter_StaticGetter, _A_Getter_StaticGetter_instances = new WeakSet(); // Error class A_Getter_StaticSetter { + constructor() { + _A_Getter_StaticSetter_instances.add(this); + } get #foo() { return ""; } static set #foo(value) { } } - _d = A_Getter_StaticSetter; + _d = A_Getter_StaticSetter, _A_Getter_StaticSetter_instances = new WeakSet(); } function Setter() { var _A_Setter_Field_instances, _A_Setter_Field_foo_set, _A_Setter_Field_foo, _A_Setter_Method_instances, _A_Setter_Method_foo_set, _A_Setter_Method_foo, _A_Setter_Getter_instances, _A_Setter_Getter_foo_set, _A_Setter_Getter_foo_get, _A_Setter_Setter_instances, _A_Setter_Setter_foo_set, _A_Setter_Setter_foo_set_1, _A_Setter_StaticField_instances, _a, _A_Setter_StaticField_foo_set, _A_Setter_StaticField_foo, _A_Setter_StaticMethod_instances, _b, _A_Setter_StaticMethod_foo_set, _A_Setter_StaticMethod_foo, _A_Setter_StaticGetter_instances, _c, _A_Setter_StaticGetter_foo_set, _A_Setter_StaticGetter_foo_get, _A_Setter_StaticSetter_instances, _d, _A_Setter_StaticSetter_foo_set, _A_Setter_StaticSetter_foo_set_1; // Error class A_Setter_Field { + constructor() { + _A_Setter_Field_instances.add(this); + _A_Setter_Field_foo.set(this, "foo"); + } set #foo(value) { } #foo = "foo"; } + _A_Setter_Field_foo = new WeakMap(), _A_Setter_Field_instances = new WeakSet(); // Error class A_Setter_Method { + constructor() { + _A_Setter_Method_instances.add(this); + } set #foo(value) { } #foo() { } } + _A_Setter_Method_instances = new WeakSet(); // OK class A_Setter_Getter { constructor() { @@ -575,62 +660,90 @@ function Setter() { _A_Setter_Getter_instances = new WeakSet(), _A_Setter_Getter_foo_set = function _A_Setter_Getter_foo_set(value) { }, _A_Setter_Getter_foo_get = function _A_Setter_Getter_foo_get() { return ""; }; // Error class A_Setter_Setter { + constructor() { + _A_Setter_Setter_instances.add(this); + } set #foo(value) { } set #foo(value) { } } + _A_Setter_Setter_instances = new WeakSet(); // Error class A_Setter_StaticField { + constructor() { + _A_Setter_StaticField_instances.add(this); + } set #foo(value) { } static #foo = "foo"; } - _a = A_Setter_StaticField; + _a = A_Setter_StaticField, _A_Setter_StaticField_instances = new WeakSet(); _A_Setter_StaticField_foo = { value: "foo" }; // Error class A_Setter_StaticMethod { + constructor() { + _A_Setter_StaticMethod_instances.add(this); + } set #foo(value) { } static #foo() { } } - _b = A_Setter_StaticMethod; + _b = A_Setter_StaticMethod, _A_Setter_StaticMethod_instances = new WeakSet(); // Error class A_Setter_StaticGetter { + constructor() { + _A_Setter_StaticGetter_instances.add(this); + } set #foo(value) { } static get #foo() { return ""; } } - _c = A_Setter_StaticGetter; + _c = A_Setter_StaticGetter, _A_Setter_StaticGetter_instances = new WeakSet(); // Error class A_Setter_StaticSetter { + constructor() { + _A_Setter_StaticSetter_instances.add(this); + } set #foo(value) { } static set #foo(value) { } } - _d = A_Setter_StaticSetter; + _d = A_Setter_StaticSetter, _A_Setter_StaticSetter_instances = new WeakSet(); } function StaticField() { var _a, _A_StaticField_Field_foo, _A_StaticField_Field_foo_1, _A_StaticField_Method_instances, _b, _A_StaticField_Method_foo, _A_StaticField_Method_foo_1, _A_StaticField_Getter_instances, _c, _A_StaticField_Getter_foo, _A_StaticField_Getter_foo_get, _A_StaticField_Setter_instances, _d, _A_StaticField_Setter_foo, _A_StaticField_Setter_foo_set, _e, _A_StaticField_StaticField_foo, _A_StaticField_StaticField_foo_1, _f, _A_StaticField_StaticMethod_foo, _A_StaticField_StaticMethod_foo_1, _g, _A_StaticField_StaticGetter_foo, _A_StaticField_StaticGetter_foo_get, _h, _A_StaticField_StaticSetter_foo, _A_StaticField_StaticSetter_foo_set; // Error class A_StaticField_Field { + constructor() { + _A_StaticField_Field_foo_1.set(this, "foo"); + } static #foo = "foo"; #foo = "foo"; } - _a = A_StaticField_Field; + _a = A_StaticField_Field, _A_StaticField_Field_foo_1 = new WeakMap(); _A_StaticField_Field_foo_1.set(A_StaticField_Field, "foo"); // Error class A_StaticField_Method { + constructor() { + _A_StaticField_Method_instances.add(this); + } static #foo = "foo"; #foo() { } } - _b = A_StaticField_Method; + _b = A_StaticField_Method, _A_StaticField_Method_instances = new WeakSet(); // Error class A_StaticField_Getter { + constructor() { + _A_StaticField_Getter_instances.add(this); + } static #foo = "foo"; get #foo() { return ""; } } - _c = A_StaticField_Getter; + _c = A_StaticField_Getter, _A_StaticField_Getter_instances = new WeakSet(); // Error class A_StaticField_Setter { + constructor() { + _A_StaticField_Setter_instances.add(this); + } static #foo = "foo"; set #foo(value) { } } - _d = A_StaticField_Setter; + _d = A_StaticField_Setter, _A_StaticField_Setter_instances = new WeakSet(); // Error class A_StaticField_StaticField { static #foo = "foo"; @@ -662,28 +775,40 @@ function StaticMethod() { var _a, _A_StaticMethod_Field_foo, _A_StaticMethod_Field_foo_1, _A_StaticMethod_Method_instances, _b, _A_StaticMethod_Method_foo, _A_StaticMethod_Method_foo_1, _A_StaticMethod_Getter_instances, _c, _A_StaticMethod_Getter_foo, _A_StaticMethod_Getter_foo_get, _A_StaticMethod_Setter_instances, _d, _A_StaticMethod_Setter_foo, _A_StaticMethod_Setter_foo_set, _e, _A_StaticMethod_StaticField_foo, _A_StaticMethod_StaticField_foo_1, _f, _A_StaticMethod_StaticMethod_foo, _A_StaticMethod_StaticMethod_foo_1, _g, _A_StaticMethod_StaticGetter_foo, _A_StaticMethod_StaticGetter_foo_get, _h, _A_StaticMethod_StaticSetter_foo, _A_StaticMethod_StaticSetter_foo_set; // Error class A_StaticMethod_Field { + constructor() { + _A_StaticMethod_Field_foo_1.set(this, "foo"); + } static #foo() { } #foo = "foo"; } - _a = A_StaticMethod_Field; + _a = A_StaticMethod_Field, _A_StaticMethod_Field_foo_1 = new WeakMap(); // Error class A_StaticMethod_Method { + constructor() { + _A_StaticMethod_Method_instances.add(this); + } static #foo() { } #foo() { } } - _b = A_StaticMethod_Method; + _b = A_StaticMethod_Method, _A_StaticMethod_Method_instances = new WeakSet(); // Error class A_StaticMethod_Getter { + constructor() { + _A_StaticMethod_Getter_instances.add(this); + } static #foo() { } get #foo() { return ""; } } - _c = A_StaticMethod_Getter; + _c = A_StaticMethod_Getter, _A_StaticMethod_Getter_instances = new WeakSet(); // Error class A_StaticMethod_Setter { + constructor() { + _A_StaticMethod_Setter_instances.add(this); + } static #foo() { } set #foo(value) { } } - _d = A_StaticMethod_Setter; + _d = A_StaticMethod_Setter, _A_StaticMethod_Setter_instances = new WeakSet(); // Error class A_StaticMethod_StaticField { static #foo() { } @@ -714,28 +839,40 @@ function StaticGetter() { var _a, _A_StaticGetter_Field_foo_get, _A_StaticGetter_Field_foo, _A_StaticGetter_Method_instances, _b, _A_StaticGetter_Method_foo_get, _A_StaticGetter_Method_foo, _A_StaticGetter_Getter_instances, _c, _A_StaticGetter_Getter_foo_get, _A_StaticGetter_Getter_foo_get_1, _A_StaticGetter_Setter_instances, _d, _A_StaticGetter_Setter_foo_get, _A_StaticGetter_Setter_foo_set, _e, _A_StaticGetter_StaticField_foo_get, _A_StaticGetter_StaticField_foo, _f, _A_StaticGetter_StaticMethod_foo_get, _A_StaticGetter_StaticMethod_foo, _g, _A_StaticGetter_StaticGetter_foo_get, _A_StaticGetter_StaticGetter_foo_get_1, _h, _A_StaticGetter_StaticSetter_foo_get, _A_StaticGetter_StaticSetter_foo_set; // Error class A_StaticGetter_Field { + constructor() { + _A_StaticGetter_Field_foo.set(this, "foo"); + } static get #foo() { return ""; } #foo = "foo"; } - _a = A_StaticGetter_Field; + _a = A_StaticGetter_Field, _A_StaticGetter_Field_foo = new WeakMap(); // Error class A_StaticGetter_Method { + constructor() { + _A_StaticGetter_Method_instances.add(this); + } static get #foo() { return ""; } #foo() { } } - _b = A_StaticGetter_Method; + _b = A_StaticGetter_Method, _A_StaticGetter_Method_instances = new WeakSet(); // Error class A_StaticGetter_Getter { + constructor() { + _A_StaticGetter_Getter_instances.add(this); + } static get #foo() { return ""; } get #foo() { return ""; } } - _c = A_StaticGetter_Getter; + _c = A_StaticGetter_Getter, _A_StaticGetter_Getter_instances = new WeakSet(); // Error class A_StaticGetter_Setter { + constructor() { + _A_StaticGetter_Setter_instances.add(this); + } static get #foo() { return ""; } set #foo(value) { } } - _d = A_StaticGetter_Setter; + _d = A_StaticGetter_Setter, _A_StaticGetter_Setter_instances = new WeakSet(); // Error class A_StaticGetter_StaticField { static get #foo() { return ""; } @@ -763,28 +900,40 @@ function StaticSetter() { var _a, _A_StaticSetter_Field_foo_set, _A_StaticSetter_Field_foo, _A_StaticSetter_Method_instances, _b, _A_StaticSetter_Method_foo_set, _A_StaticSetter_Method_foo, _A_StaticSetter_Getter_instances, _c, _A_StaticSetter_Getter_foo_set, _A_StaticSetter_Getter_foo_get, _A_StaticSetter_Setter_instances, _d, _A_StaticSetter_Setter_foo_set, _A_StaticSetter_Setter_foo_set_1, _e, _A_StaticSetter_StaticField_foo_set, _A_StaticSetter_StaticField_foo, _f, _A_StaticSetter_StaticMethod_foo_set, _A_StaticSetter_StaticMethod_foo, _g, _A_StaticSetter_StaticGetter_foo_set, _A_StaticSetter_StaticGetter_foo_get, _h, _A_StaticSetter_StaticSetter_foo_set, _A_StaticSetter_StaticSetter_foo_set_1; // Error class A_StaticSetter_Field { + constructor() { + _A_StaticSetter_Field_foo.set(this, "foo"); + } static set #foo(value) { } #foo = "foo"; } - _a = A_StaticSetter_Field; + _a = A_StaticSetter_Field, _A_StaticSetter_Field_foo = new WeakMap(); // Error class A_StaticSetter_Method { + constructor() { + _A_StaticSetter_Method_instances.add(this); + } static set #foo(value) { } #foo() { } } - _b = A_StaticSetter_Method; + _b = A_StaticSetter_Method, _A_StaticSetter_Method_instances = new WeakSet(); // Error class A_StaticSetter_Getter { + constructor() { + _A_StaticSetter_Getter_instances.add(this); + } static set #foo(value) { } get #foo() { return ""; } } - _c = A_StaticSetter_Getter; + _c = A_StaticSetter_Getter, _A_StaticSetter_Getter_instances = new WeakSet(); // Error class A_StaticSetter_Setter { + constructor() { + _A_StaticSetter_Setter_instances.add(this); + } static set #foo(value) { } set #foo(value) { } } - _d = A_StaticSetter_Setter; + _d = A_StaticSetter_Setter, _A_StaticSetter_Setter_instances = new WeakSet(); // Error class A_StaticSetter_StaticField { static set #foo(value) { } diff --git a/tests/baselines/reference/privateNamesUnique-3.js b/tests/baselines/reference/privateNamesUnique-3.js index 23fb6a0098fba..5d4257eecd2c3 100644 --- a/tests/baselines/reference/privateNamesUnique-3.js +++ b/tests/baselines/reference/privateNamesUnique-3.js @@ -22,6 +22,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( }; var _a, _A_foo, _A_foo_1, _b, _B_foo; class A { + constructor() { + _A_foo_1 = { value: 1 }; + // because static and instance private names + // share the same lexical scope + // https://tc39.es/proposal-class-fields/#prod-ClassBody + } #foo = 1; static #foo = true; // error (duplicate) }