From 5ade1034d88098dea72c39899895f7115d90d0ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:37:05 +0000 Subject: [PATCH 1/2] Initial plan From 058ed9dc07854961e170cef45b9130ae7716aae9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:53:06 +0000 Subject: [PATCH 2/2] Port PR #62923: Fix crash in abstract property checking This ports TypeScript PR #62923 which fixes issue #62920 - a crash when using abstract properties in class expressions. The fix changes how we check for abstract properties in constructors: - Instead of getting the class declaration and accessing its name (which crashes for unnamed class expressions), we now check the parent symbol directly using SymbolFlagsClass - Use symbolToString() for the error message, which handles both named and unnamed classes correctly Added test case errorInUnnamedClassExpression.ts to verify the fix. --- internal/checker/checker.go | 6 +++--- .../errorInUnnamedClassExpression.errors.txt | 21 +++++++++++++++++++ .../errorInUnnamedClassExpression.symbols | 19 +++++++++++++++++ .../errorInUnnamedClassExpression.types | 21 +++++++++++++++++++ .../compiler/errorInUnnamedClassExpression.ts | 11 ++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 testdata/baselines/reference/compiler/errorInUnnamedClassExpression.errors.txt create mode 100644 testdata/baselines/reference/compiler/errorInUnnamedClassExpression.symbols create mode 100644 testdata/baselines/reference/compiler/errorInUnnamedClassExpression.types create mode 100644 testdata/tests/cases/compiler/errorInUnnamedClassExpression.ts diff --git a/internal/checker/checker.go b/internal/checker/checker.go index f2a212a060..34ba1c383b 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -11452,10 +11452,10 @@ func (c *Checker) checkPropertyAccessibilityAtLocation(location *ast.Node, isSup if flags&ast.ModifierFlagsAbstract != 0 && c.symbolHasNonMethodDeclaration(prop) && (isThisProperty(location) || isThisInitializedObjectBindingExpression(location) || ast.IsObjectBindingPattern(location.Parent) && isThisInitializedDeclaration(location.Parent.Parent)) { - declaringClassDeclaration := ast.GetClassLikeDeclarationOfSymbol(c.getParentOfSymbol(prop)) - if declaringClassDeclaration != nil && c.isNodeUsedDuringClassInitialization(location) { + parentSymbol := c.getParentOfSymbol(prop) + if parentSymbol != nil && parentSymbol.Flags&ast.SymbolFlagsClass != 0 && c.isNodeUsedDuringClassInitialization(location) { if errorNode != nil { - c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.symbolToString(prop), declaringClassDeclaration.Name().Text()) + c.error(errorNode, diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, c.symbolToString(prop), c.symbolToString(parentSymbol)) } return false } diff --git a/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.errors.txt b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.errors.txt new file mode 100644 index 0000000000..dd20f1b823 --- /dev/null +++ b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.errors.txt @@ -0,0 +1,21 @@ +errorInUnnamedClassExpression.ts(5,14): error TS2715: Abstract property 'bar' in class 'Foo' cannot be accessed in the constructor. +errorInUnnamedClassExpression.ts(7,5): error TS1253: Abstract properties can only appear within an abstract class. +errorInUnnamedClassExpression.ts(7,14): error TS7008: Member 'bar' implicitly has an 'any' type. + + +==== errorInUnnamedClassExpression.ts (3 errors) ==== + // https://github.com/microsoft/TypeScript/issues/62920 + + let Foo = class { + constructor() { + this.bar++; + ~~~ +!!! error TS2715: Abstract property 'bar' in class 'Foo' cannot be accessed in the constructor. + } + abstract bar; + ~~~~~~~~ +!!! error TS1253: Abstract properties can only appear within an abstract class. + ~~~ +!!! error TS7008: Member 'bar' implicitly has an 'any' type. + }; + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.symbols b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.symbols new file mode 100644 index 0000000000..66f6df7636 --- /dev/null +++ b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/errorInUnnamedClassExpression.ts] //// + +=== errorInUnnamedClassExpression.ts === +// https://github.com/microsoft/TypeScript/issues/62920 + +let Foo = class { +>Foo : Symbol(Foo, Decl(errorInUnnamedClassExpression.ts, 2, 3)) + + constructor() { + this.bar++; +>this.bar : Symbol(Foo.bar, Decl(errorInUnnamedClassExpression.ts, 5, 5)) +>this : Symbol(Foo, Decl(errorInUnnamedClassExpression.ts, 2, 9)) +>bar : Symbol(Foo.bar, Decl(errorInUnnamedClassExpression.ts, 5, 5)) + } + abstract bar; +>bar : Symbol(Foo.bar, Decl(errorInUnnamedClassExpression.ts, 5, 5)) + +}; + diff --git a/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.types b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.types new file mode 100644 index 0000000000..617a215a16 --- /dev/null +++ b/testdata/baselines/reference/compiler/errorInUnnamedClassExpression.types @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/errorInUnnamedClassExpression.ts] //// + +=== errorInUnnamedClassExpression.ts === +// https://github.com/microsoft/TypeScript/issues/62920 + +let Foo = class { +>Foo : typeof Foo +>class { constructor() { this.bar++; } abstract bar;} : typeof Foo + + constructor() { + this.bar++; +>this.bar++ : number +>this.bar : any +>this : this +>bar : any + } + abstract bar; +>bar : any + +}; + diff --git a/testdata/tests/cases/compiler/errorInUnnamedClassExpression.ts b/testdata/tests/cases/compiler/errorInUnnamedClassExpression.ts new file mode 100644 index 0000000000..2bd4792268 --- /dev/null +++ b/testdata/tests/cases/compiler/errorInUnnamedClassExpression.ts @@ -0,0 +1,11 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62920 + +let Foo = class { + constructor() { + this.bar++; + } + abstract bar; +};