From ba0d4d157c1d0aaa349d7274f8d7a51f1c88e3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 29 Mar 2025 14:59:13 +0100 Subject: [PATCH 1/3] Unify the way anonymous class symbols are printed in error messages --- internal/checker/checker.go | 2 +- internal/checker/relater.go | 5 ++-- internal/checker/utilities.go | 8 +++++ ...ivateNameMethodClassExpression2.errors.txt | 19 ++++++++++++ .../privateNameMethodClassExpression2.symbols | 17 +++++++++++ .../privateNameMethodClassExpression2.types | 29 +++++++++++++++++++ .../compiler/privateNamesUnique-6.errors.txt | 17 +++++++++++ .../compiler/privateNamesUnique-6.symbols | 20 +++++++++++++ .../compiler/privateNamesUnique-6.types | 22 ++++++++++++++ ...rivateNameMethodClassExpression.errors.txt | 8 ++--- ...eNameMethodClassExpression.errors.txt.diff | 8 ++--- .../privateNameMethodClassExpression2.ts | 13 +++++++++ .../cases/compiler/privateNamesUnique-6.ts | 13 +++++++++ 13 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 testdata/baselines/reference/compiler/privateNameMethodClassExpression2.errors.txt create mode 100644 testdata/baselines/reference/compiler/privateNameMethodClassExpression2.symbols create mode 100644 testdata/baselines/reference/compiler/privateNameMethodClassExpression2.types create mode 100644 testdata/baselines/reference/compiler/privateNamesUnique-6.errors.txt create mode 100644 testdata/baselines/reference/compiler/privateNamesUnique-6.symbols create mode 100644 testdata/baselines/reference/compiler/privateNamesUnique-6.types create mode 100644 testdata/tests/cases/compiler/privateNameMethodClassExpression2.ts create mode 100644 testdata/tests/cases/compiler/privateNamesUnique-6.ts diff --git a/internal/checker/checker.go b/internal/checker/checker.go index c620032515..f3c21713a4 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -10845,7 +10845,7 @@ func (c *Checker) checkPrivateIdentifierPropertyAccess(leftType *Type, right *as return true } } - c.error(right, diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, scanner.DeclarationNameToString(typeClass.Name())) + c.error(right, diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, classDeclarationNameToString(typeClass.Symbol().ValueDeclaration)) return true } return false diff --git a/internal/checker/relater.go b/internal/checker/relater.go index c0887f740b..8ebe08be1d 100644 --- a/internal/checker/relater.go +++ b/internal/checker/relater.go @@ -10,7 +10,6 @@ import ( "github.com/microsoft/typescript-go/internal/compiler/diagnostics" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/jsnum" - "github.com/microsoft/typescript-go/internal/scanner" ) type SignatureCheckMode uint32 @@ -4272,8 +4271,8 @@ func (r *Relater) reportUnmatchedProperty(source *Type, target *Type, unmatchedP privateIdentifierDescription := unmatchedProperty.ValueDeclaration.Name().Text() symbolTableKey := binder.GetSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription) if r.c.getPropertyOfType(source, symbolTableKey) != nil { - sourceName := scanner.DeclarationNameToString(ast.GetNameOfDeclaration(source.symbol.ValueDeclaration)) - targetName := scanner.DeclarationNameToString(ast.GetNameOfDeclaration(target.symbol.ValueDeclaration)) + sourceName := classDeclarationNameToString(source.symbol.ValueDeclaration) + targetName := classDeclarationNameToString(target.symbol.ValueDeclaration) r.reportError(diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, privateIdentifierDescription, sourceName, targetName) return } diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 190b1f6073..367421f9b2 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -2165,3 +2165,11 @@ func allDeclarationsInSameSourceFile(symbol *ast.Symbol) bool { } return true } + +func classDeclarationNameToString(declaration *ast.Node) string { + name := ast.GetNameOfDeclaration(declaration) + if name == nil { + return "(Anonymous class)" + } + return scanner.DeclarationNameToString(name) +} diff --git a/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.errors.txt b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.errors.txt new file mode 100644 index 0000000000..c8cb066fc9 --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.errors.txt @@ -0,0 +1,19 @@ +privateNameMethodClassExpression2.ts(5,6): error TS18013: Property '#method' is not accessible outside class '(Anonymous class)' because it has a private identifier. +privateNameMethodClassExpression2.ts(9,6): error TS18013: Property '#field' is not accessible outside class '(Anonymous class)' because it has a private identifier. + + +==== privateNameMethodClassExpression2.ts (2 errors) ==== + new (class { + #method() { + return 42; + } + })().#method; // error + ~~~~~~~ +!!! error TS18013: Property '#method' is not accessible outside class '(Anonymous class)' because it has a private identifier. + + new (class { + #field = 42; + })().#field; // error + ~~~~~~ +!!! error TS18013: Property '#field' is not accessible outside class '(Anonymous class)' because it has a private identifier. + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.symbols b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.symbols new file mode 100644 index 0000000000..9e13d6a715 --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.symbols @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/privateNameMethodClassExpression2.ts] //// + +=== privateNameMethodClassExpression2.ts === +new (class { + #method() { +>#method : Symbol(#method, Decl(privateNameMethodClassExpression2.ts, 0, 12)) + + return 42; + } +})().#method; // error + +new (class { + #field = 42; +>#field : Symbol(#field, Decl(privateNameMethodClassExpression2.ts, 6, 12)) + +})().#field; // error + diff --git a/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.types b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.types new file mode 100644 index 0000000000..20adafd543 --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNameMethodClassExpression2.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/privateNameMethodClassExpression2.ts] //// + +=== privateNameMethodClassExpression2.ts === +new (class { +>new (class { #method() { return 42; }})().#method : any +>new (class { #method() { return 42; }})() : (Anonymous class) +>(class { #method() { return 42; }}) : typeof (Anonymous class) +>class { #method() { return 42; }} : typeof (Anonymous class) + + #method() { +>#method : () => number + + return 42; +>42 : 42 + } +})().#method; // error + +new (class { +>new (class { #field = 42;})().#field : any +>new (class { #field = 42;})() : (Anonymous class) +>(class { #field = 42;}) : typeof (Anonymous class) +>class { #field = 42;} : typeof (Anonymous class) + + #field = 42; +>#field : number +>42 : 42 + +})().#field; // error + diff --git a/testdata/baselines/reference/compiler/privateNamesUnique-6.errors.txt b/testdata/baselines/reference/compiler/privateNamesUnique-6.errors.txt new file mode 100644 index 0000000000..3e53eca74d --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNamesUnique-6.errors.txt @@ -0,0 +1,17 @@ +privateNamesUnique-6.ts(6,7): error TS2322: Type '(Anonymous class)' is not assignable to type 'A'. + Property '#foo' in type '(Anonymous class)' refers to a different member that cannot be accessed from within type 'A'. + + +==== privateNamesUnique-6.ts (1 errors) ==== + class A { + #foo: number; + } + + // error + const test: A = new (class { + ~~~~ +!!! error TS2322: Type '(Anonymous class)' is not assignable to type 'A'. +!!! error TS2322: Property '#foo' in type '(Anonymous class)' refers to a different member that cannot be accessed from within type 'A'. + #foo: number; + })(); + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/privateNamesUnique-6.symbols b/testdata/baselines/reference/compiler/privateNamesUnique-6.symbols new file mode 100644 index 0000000000..bf1234ce3f --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNamesUnique-6.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/privateNamesUnique-6.ts] //// + +=== privateNamesUnique-6.ts === +class A { +>A : Symbol(A, Decl(privateNamesUnique-6.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(#foo, Decl(privateNamesUnique-6.ts, 0, 9)) +} + +// error +const test: A = new (class { +>test : Symbol(test, Decl(privateNamesUnique-6.ts, 5, 5)) +>A : Symbol(A, Decl(privateNamesUnique-6.ts, 0, 0)) + + #foo: number; +>#foo : Symbol(#foo, Decl(privateNamesUnique-6.ts, 5, 28)) + +})(); + diff --git a/testdata/baselines/reference/compiler/privateNamesUnique-6.types b/testdata/baselines/reference/compiler/privateNamesUnique-6.types new file mode 100644 index 0000000000..9ca9524185 --- /dev/null +++ b/testdata/baselines/reference/compiler/privateNamesUnique-6.types @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/privateNamesUnique-6.ts] //// + +=== privateNamesUnique-6.ts === +class A { +>A : A + + #foo: number; +>#foo : number +} + +// error +const test: A = new (class { +>test : A +>new (class { #foo: number;})() : (Anonymous class) +>(class { #foo: number;}) : typeof (Anonymous class) +>class { #foo: number;} : typeof (Anonymous class) + + #foo: number; +>#foo : number + +})(); + diff --git a/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt b/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt index 6be1907e16..7b2e560cbf 100644 --- a/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt +++ b/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt @@ -1,5 +1,5 @@ -privateNameMethodClassExpression.ts(9,17): error TS18013: Property '#method' is not accessible outside class '(Missing)' because it has a private identifier. -privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is not accessible outside class '(Missing)' because it has a private identifier. +privateNameMethodClassExpression.ts(9,17): error TS18013: Property '#method' is not accessible outside class 'C' because it has a private identifier. +privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is not accessible outside class 'C' because it has a private identifier. ==== privateNameMethodClassExpression.ts (2 errors) ==== @@ -13,9 +13,9 @@ privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is console.log(C.getInstance().getField()); C.getInstance().#method; // Error ~~~~~~~ -!!! error TS18013: Property '#method' is not accessible outside class '(Missing)' because it has a private identifier. +!!! error TS18013: Property '#method' is not accessible outside class 'C' because it has a private identifier. C.getInstance().#field; // Error ~~~~~~ -!!! error TS18013: Property '#field' is not accessible outside class '(Missing)' because it has a private identifier. +!!! error TS18013: Property '#field' is not accessible outside class 'C' because it has a private identifier. \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff index 13ca7e726a..25b1b8d18f 100644 --- a/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff +++ b/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff @@ -3,8 +3,8 @@ @@= skipped -0, +0 lines =@@ -privateNameMethodClassExpression.ts(9,17): error TS18013: Property '#method' is not accessible outside class '(anonymous)' because it has a private identifier. -privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is not accessible outside class '(anonymous)' because it has a private identifier. -+privateNameMethodClassExpression.ts(9,17): error TS18013: Property '#method' is not accessible outside class '(Missing)' because it has a private identifier. -+privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is not accessible outside class '(Missing)' because it has a private identifier. ++privateNameMethodClassExpression.ts(9,17): error TS18013: Property '#method' is not accessible outside class 'C' because it has a private identifier. ++privateNameMethodClassExpression.ts(10,17): error TS18013: Property '#field' is not accessible outside class 'C' because it has a private identifier. ==== privateNameMethodClassExpression.ts (2 errors) ==== @@ -13,10 +13,10 @@ C.getInstance().#method; // Error ~~~~~~~ -!!! error TS18013: Property '#method' is not accessible outside class '(anonymous)' because it has a private identifier. -+!!! error TS18013: Property '#method' is not accessible outside class '(Missing)' because it has a private identifier. ++!!! error TS18013: Property '#method' is not accessible outside class 'C' because it has a private identifier. C.getInstance().#field; // Error ~~~~~~ -!!! error TS18013: Property '#field' is not accessible outside class '(anonymous)' because it has a private identifier. -+!!! error TS18013: Property '#field' is not accessible outside class '(Missing)' because it has a private identifier. ++!!! error TS18013: Property '#field' is not accessible outside class 'C' because it has a private identifier. diff --git a/testdata/tests/cases/compiler/privateNameMethodClassExpression2.ts b/testdata/tests/cases/compiler/privateNameMethodClassExpression2.ts new file mode 100644 index 0000000000..d0ff15f676 --- /dev/null +++ b/testdata/tests/cases/compiler/privateNameMethodClassExpression2.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: es2015 +// @noEmit: true + +new (class { + #method() { + return 42; + } +})().#method; // error + +new (class { + #field = 42; +})().#field; // error diff --git a/testdata/tests/cases/compiler/privateNamesUnique-6.ts b/testdata/tests/cases/compiler/privateNamesUnique-6.ts new file mode 100644 index 0000000000..601d35f0d6 --- /dev/null +++ b/testdata/tests/cases/compiler/privateNamesUnique-6.ts @@ -0,0 +1,13 @@ +// @strict: true +// @strictPropertyInitialization: false +// @target: es6 +// @noEmit: true + +class A { + #foo: number; +} + +// error +const test: A = new (class { + #foo: number; +})(); From 7e6dad88633873e68559766d3b8b3c39713080ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 29 Mar 2025 15:11:21 +0100 Subject: [PATCH 2/3] just use `c.SymbolToString` --- internal/checker/checker.go | 2 +- internal/checker/relater.go | 4 +--- internal/checker/utilities.go | 8 -------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/internal/checker/checker.go b/internal/checker/checker.go index f3c21713a4..da4bb6c0a4 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -10845,7 +10845,7 @@ func (c *Checker) checkPrivateIdentifierPropertyAccess(leftType *Type, right *as return true } } - c.error(right, diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, classDeclarationNameToString(typeClass.Symbol().ValueDeclaration)) + c.error(right, diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, c.SymbolToString(typeClass.Symbol())) return true } return false diff --git a/internal/checker/relater.go b/internal/checker/relater.go index 8ebe08be1d..d8231ed01e 100644 --- a/internal/checker/relater.go +++ b/internal/checker/relater.go @@ -4271,9 +4271,7 @@ func (r *Relater) reportUnmatchedProperty(source *Type, target *Type, unmatchedP privateIdentifierDescription := unmatchedProperty.ValueDeclaration.Name().Text() symbolTableKey := binder.GetSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription) if r.c.getPropertyOfType(source, symbolTableKey) != nil { - sourceName := classDeclarationNameToString(source.symbol.ValueDeclaration) - targetName := classDeclarationNameToString(target.symbol.ValueDeclaration) - r.reportError(diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, privateIdentifierDescription, sourceName, targetName) + r.reportError(diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, privateIdentifierDescription, r.c.SymbolToString(source.symbol), r.c.SymbolToString(target.symbol)) return } } diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 367421f9b2..190b1f6073 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -2165,11 +2165,3 @@ func allDeclarationsInSameSourceFile(symbol *ast.Symbol) bool { } return true } - -func classDeclarationNameToString(declaration *ast.Node) string { - name := ast.GetNameOfDeclaration(declaration) - if name == nil { - return "(Anonymous class)" - } - return scanner.DeclarationNameToString(name) -} From ab1364d80875d9f178c7d20d666a6e0cc68d7fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 29 Mar 2025 20:20:23 +0100 Subject: [PATCH 3/3] accept change --- .../conformance/privateNameMethodClassExpression.errors.txt.diff | 0 testdata/submoduleAccepted.txt | 1 + 2 files changed, 1 insertion(+) rename testdata/baselines/reference/{submodule => submoduleAccepted}/conformance/privateNameMethodClassExpression.errors.txt.diff (100%) diff --git a/testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/conformance/privateNameMethodClassExpression.errors.txt.diff similarity index 100% rename from testdata/baselines/reference/submodule/conformance/privateNameMethodClassExpression.errors.txt.diff rename to testdata/baselines/reference/submoduleAccepted/conformance/privateNameMethodClassExpression.errors.txt.diff diff --git a/testdata/submoduleAccepted.txt b/testdata/submoduleAccepted.txt index 1550fd35cb..80e3afbbe7 100644 --- a/testdata/submoduleAccepted.txt +++ b/testdata/submoduleAccepted.txt @@ -1 +1,2 @@ # Diff files to instead write to submoduleAccepted as "accepted" changes. +conformance/privateNameMethodClassExpression.errors.txt.diff