Fix class alias reference in static initializer for legacy class decorators (#54046)

This commit is contained in:
Ron Buckton 2023-04-28 15:45:40 -04:00 коммит произвёл GitHub
Родитель 9a52f943ef
Коммит 611a912dd1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 86 добавлений и 1 удалений

Просмотреть файл

@ -37,6 +37,7 @@ import {
isBlock,
isCallToHelper,
isClassElement,
isClassStaticBlockDeclaration,
isComputedPropertyName,
isDecorator,
isExportOrDefaultModifier,
@ -339,6 +340,27 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
let decorationStatements: Statement[] | undefined = [];
({ members, decorationStatements } = transformDecoratorsOfClassElements(node, members));
// If we're emitting to ES2022 or later then we need to reassign the class alias before
// static initializers are evaluated.
const assignClassAliasInStaticBlock =
languageVersion >= ScriptTarget.ES2022 &&
!!classAlias &&
some(members, member =>
isPropertyDeclaration(member) && hasSyntacticModifier(member, ModifierFlags.Static) ||
isClassStaticBlockDeclaration(member));
if (assignClassAliasInStaticBlock) {
members = setTextRange(factory.createNodeArray([
factory.createClassStaticBlockDeclaration(
factory.createBlock([
factory.createExpressionStatement(
factory.createAssignment(classAlias, factory.createThis())
)
])
),
...members
]), members);
}
const classExpression = factory.createClassExpression(
modifiers,
name && isGeneratedIdentifier(name) ? undefined : name,
@ -355,7 +377,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
declName,
/*exclamationToken*/ undefined,
/*type*/ undefined,
classAlias ? factory.createAssignment(classAlias, classExpression) : classExpression
classAlias && !assignClassAliasInStaticBlock ? factory.createAssignment(classAlias, classExpression) : classExpression
);
setOriginalNode(varDecl, node);

Просмотреть файл

@ -0,0 +1,43 @@
//// [staticInitializersAndLegacyClassDecorators.ts]
// https://github.com/microsoft/TypeScript/issues/52004
declare var dec: any;
@dec
class C1
{
static instance = new C1();
}
@dec
class C2
{
static {
new C2();
}
}
//// [staticInitializersAndLegacyClassDecorators.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var C1_1, C2_1;
let C1 = class C1 {
static { C1_1 = this; }
static instance = new C1_1();
};
C1 = C1_1 = __decorate([
dec
], C1);
let C2 = class C2 {
static { C2_1 = this; }
static {
new C2_1();
}
};
C2 = C2_1 = __decorate([
dec
], C2);

Просмотреть файл

@ -0,0 +1,20 @@
// @target: es2022
// @experimentalDecorators: true
// @noTypesAndSymbols: true
// https://github.com/microsoft/TypeScript/issues/52004
declare var dec: any;
@dec
class C1
{
static instance = new C1();
}
@dec
class C2
{
static {
new C2();
}
}