Skip to content

Commit

Permalink
Added missing static check for the containing property. Fixed other c…
Browse files Browse the repository at this point in the history
…ode review issues.
  • Loading branch information
dragomirtitian committed Apr 5, 2021
1 parent a29bcb0 commit dc0a347
Show file tree
Hide file tree
Showing 10 changed files with 578 additions and 137 deletions.
9 changes: 4 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26982,12 +26982,11 @@ namespace ts {
grammarErrorOnNode(right, Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, idText(right));
}

if (lexicallyScopedSymbol && (compilerOptions.target === ScriptTarget.ESNext && !useDefineForClassFields)) {
const lexicalValueDecl = lexicallyScopedSymbol.valueDeclaration;
const lexicalClass = lexicalValueDecl && getContainingClass(lexicalValueDecl);
if (lexicallyScopedSymbol?.valueDeclaration && (compilerOptions.target === ScriptTarget.ESNext && !useDefineForClassFields)) {
const lexicalClass = getContainingClass(lexicallyScopedSymbol.valueDeclaration);
const parentStaticFieldInitializer = findAncestor(node, (n) => {
if (n === lexicalClass) return "quit";
if (isPropertyDeclaration(n.parent) && n.parent.initializer === n && n.parent.parent === lexicalClass) {
if (isPropertyDeclaration(n.parent) && hasStaticModifier(n.parent) && n.parent.initializer === n && n.parent.parent === lexicalClass) {
return true;
}
return false;
Expand All @@ -26996,7 +26995,7 @@ namespace ts {
const parentStaticFieldInitializerSymbol = getSymbolOfNode(parentStaticFieldInitializer.parent);
Debug.assert(parentStaticFieldInitializerSymbol, "Initializer without declaration symbol");
const diagnostic = error(node,
Diagnostics.Property_0_is_used_in_a_static_property_s_initializer_in_the_same_class_This_is_only_supported_when_target_set_to_is_esnext_and_if_useDefineForClassFields_is_set_to_true,
Diagnostics.Property_0_may_not_be_used_in_a_static_property_s_initializer_in_the_same_class_when_target_is_esnext_and_useDefineForClassFields_is_false,
symbolName(lexicallyScopedSymbol));
addRelatedInfo(diagnostic,
createDiagnosticForNode(parentStaticFieldInitializer.parent,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3312,7 +3312,7 @@
"category": "Error",
"code": 2809
},
"Property '{0}' is used in a static property's initializer in the same class. This is only supported when 'target' set to is 'esnext' and if 'useDefineForClassFields' is set to 'true'": {
"Property '{0}' may not be used in a static property's initializer in the same class when 'target' is 'esnext' and 'useDefineForClassFields' is 'false'.": {
"category": "Error",
"code": 2810
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
//// [privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts]
class Test {
class TestWithErrors {
#prop = 0
static dd = new Test().#prop; // Err
static dd = new TestWithErrors().#prop; // Err
static ["X_ z_ zz"] = class Inner {
#foo = 10
m() {
new Test().#prop // Err
new TestWithErrors().#prop // Err
}
static C = class InnerInner {
m() {
new Test().#prop // Err
new TestWithErrors().#prop // Err
new Inner().#foo; // Err
}
}

static M(){
return class {
m() {
new Test().#prop // Err
new TestWithErrors().#prop // Err
new Inner().#foo; // OK
}
}
}
}
}
}

class TestNoErrors {
#prop = 0
dd = new TestNoErrors().#prop; // OK
["X_ z_ zz"] = class Inner {
#foo = 10
m() {
new TestNoErrors().#prop // Ok
}
C = class InnerInner {
m() {
new TestNoErrors().#prop // Ok
new Inner().#foo; // Ok
}
}

static M(){
return class {
m() {
new TestNoErrors().#prop // OK
new Inner().#foo; // OK
}
}
}
}
}

//// [privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.js]
"use strict";
Expand All @@ -32,25 +58,25 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Test_prop, _Inner_foo, _a;
class Test {
var _TestWithErrors_prop, _Inner_foo, _a, _TestNoErrors_prop;
class TestWithErrors {
constructor() {
_Test_prop.set(this, 0);
_TestWithErrors_prop.set(this, 0);
}
}
_Test_prop = new WeakMap();
Test.dd = __classPrivateFieldGet(new Test(), _Test_prop, "f"); // Err
Test["X_ z_ zz"] = (_a = class Inner {
_TestWithErrors_prop = new WeakMap();
TestWithErrors.dd = __classPrivateFieldGet(new TestWithErrors(), _TestWithErrors_prop, "f"); // Err
TestWithErrors["X_ z_ zz"] = (_a = class Inner {
constructor() {
_Inner_foo.set(this, 10);
}
m() {
__classPrivateFieldGet(new Test(), _Test_prop, "f"); // Err
__classPrivateFieldGet(new TestWithErrors(), _TestWithErrors_prop, "f"); // Err
}
static M() {
return class {
m() {
__classPrivateFieldGet(new Test(), _Test_prop, "f"); // Err
__classPrivateFieldGet(new TestWithErrors(), _TestWithErrors_prop, "f"); // Err
__classPrivateFieldGet(new Inner(), _Inner_foo, "f"); // OK
}
};
Expand All @@ -59,8 +85,40 @@ Test["X_ z_ zz"] = (_a = class Inner {
_Inner_foo = new WeakMap(),
_a.C = class InnerInner {
m() {
__classPrivateFieldGet(new Test(), _Test_prop, "f"); // Err
__classPrivateFieldGet(new TestWithErrors(), _TestWithErrors_prop, "f"); // Err
__classPrivateFieldGet(new _a(), _Inner_foo, "f"); // Err
}
},
_a);
class TestNoErrors {
constructor() {
var _Inner_foo_1, _b;
_TestNoErrors_prop.set(this, 0);
this.dd = __classPrivateFieldGet(new TestNoErrors(), _TestNoErrors_prop, "f"); // OK
this["X_ z_ zz"] = (_b = class Inner {
constructor() {
_Inner_foo_1.set(this, 10);
this.C = class InnerInner {
m() {
__classPrivateFieldGet(new TestNoErrors(), _TestNoErrors_prop, "f"); // Ok
__classPrivateFieldGet(new Inner(), _Inner_foo_1, "f"); // Ok
}
};
}
m() {
__classPrivateFieldGet(new TestNoErrors(), _TestNoErrors_prop, "f"); // Ok
}
static M() {
return class {
m() {
__classPrivateFieldGet(new TestNoErrors(), _TestNoErrors_prop, "f"); // OK
__classPrivateFieldGet(new Inner(), _Inner_foo_1, "f"); // OK
}
};
}
},
_Inner_foo_1 = new WeakMap(),
_b);
}
}
_TestNoErrors_prop = new WeakMap();
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
=== tests/cases/conformance/classes/members/privateNames/privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts ===
class Test {
>Test : Symbol(Test, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
class TestWithErrors {
>TestWithErrors : Symbol(TestWithErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))

#prop = 0
>#prop : Symbol(Test.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 12))
>#prop : Symbol(TestWithErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 22))

static dd = new Test().#prop; // Err
>dd : Symbol(Test.dd, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 1, 13))
>new Test().#prop : Symbol(Test.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 12))
>Test : Symbol(Test, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
static dd = new TestWithErrors().#prop; // Err
>dd : Symbol(TestWithErrors.dd, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 1, 13))
>new TestWithErrors().#prop : Symbol(TestWithErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 22))
>TestWithErrors : Symbol(TestWithErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))

static ["X_ z_ zz"] = class Inner {
>["X_ z_ zz"] : Symbol(Test["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 2, 33))
>"X_ z_ zz" : Symbol(Test["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 2, 33))
>["X_ z_ zz"] : Symbol(TestWithErrors["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 2, 43))
>"X_ z_ zz" : Symbol(TestWithErrors["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 2, 43))
>Inner : Symbol(Inner, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 3, 25))

#foo = 10
Expand All @@ -21,9 +21,9 @@ class Test {
m() {
>m : Symbol(Inner.m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 4, 18))

new Test().#prop // Err
>new Test().#prop : Symbol(Test.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 12))
>Test : Symbol(Test, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
new TestWithErrors().#prop // Err
>new TestWithErrors().#prop : Symbol(TestWithErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 22))
>TestWithErrors : Symbol(TestWithErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
}
static C = class InnerInner {
>C : Symbol(Inner.C, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 7, 9))
Expand All @@ -32,9 +32,9 @@ class Test {
m() {
>m : Symbol(InnerInner.m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 8, 37))

new Test().#prop // Err
>new Test().#prop : Symbol(Test.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 12))
>Test : Symbol(Test, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
new TestWithErrors().#prop // Err
>new TestWithErrors().#prop : Symbol(TestWithErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 22))
>TestWithErrors : Symbol(TestWithErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))

new Inner().#foo; // Err
>new Inner().#foo : Symbol(Inner.#foo, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 3, 39))
Expand All @@ -49,9 +49,9 @@ class Test {
m() {
>m : Symbol((Anonymous class).m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 16, 26))

new Test().#prop // Err
>new Test().#prop : Symbol(Test.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 12))
>Test : Symbol(Test, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))
new TestWithErrors().#prop // Err
>new TestWithErrors().#prop : Symbol(TestWithErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 22))
>TestWithErrors : Symbol(TestWithErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 0, 0))

new Inner().#foo; // OK
>new Inner().#foo : Symbol(Inner.#foo, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 3, 39))
Expand All @@ -61,3 +61,66 @@ class Test {
}
}
}

class TestNoErrors {
>TestNoErrors : Symbol(TestNoErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 24, 1))

#prop = 0
>#prop : Symbol(TestNoErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 26, 20))

dd = new TestNoErrors().#prop; // OK
>dd : Symbol(TestNoErrors.dd, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 27, 13))
>new TestNoErrors().#prop : Symbol(TestNoErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 26, 20))
>TestNoErrors : Symbol(TestNoErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 24, 1))

["X_ z_ zz"] = class Inner {
>["X_ z_ zz"] : Symbol(TestNoErrors["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 28, 34))
>"X_ z_ zz" : Symbol(TestNoErrors["X_ z_ zz"], Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 28, 34))
>Inner : Symbol(Inner, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 18))

#foo = 10
>#foo : Symbol(Inner.#foo, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 32))

m() {
>m : Symbol(Inner.m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 30, 18))

new TestNoErrors().#prop // Ok
>new TestNoErrors().#prop : Symbol(TestNoErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 26, 20))
>TestNoErrors : Symbol(TestNoErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 24, 1))
}
C = class InnerInner {
>C : Symbol(Inner.C, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 33, 9))
>InnerInner : Symbol(InnerInner, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 34, 11))

m() {
>m : Symbol(InnerInner.m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 34, 30))

new TestNoErrors().#prop // Ok
>new TestNoErrors().#prop : Symbol(TestNoErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 26, 20))
>TestNoErrors : Symbol(TestNoErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 24, 1))

new Inner().#foo; // Ok
>new Inner().#foo : Symbol(Inner.#foo, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 32))
>Inner : Symbol(Inner, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 18))
}
}

static M(){
>M : Symbol(Inner.M, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 39, 9))

return class {
m() {
>m : Symbol((Anonymous class).m, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 42, 26))

new TestNoErrors().#prop // OK
>new TestNoErrors().#prop : Symbol(TestNoErrors.#prop, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 26, 20))
>TestNoErrors : Symbol(TestNoErrors, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 24, 1))

new Inner().#foo; // OK
>new Inner().#foo : Symbol(Inner.#foo, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 32))
>Inner : Symbol(Inner, Decl(privateNameErrorsOnNotUseDefineForClassFieldsInEsNext.ts, 29, 18))
}
}
}
}
}
Loading

0 comments on commit dc0a347

Please sign in to comment.