Fix class alias reference in static initializer for legacy class decorators (#54046)
This commit is contained in:
Родитель
9a52f943ef
Коммит
611a912dd1
|
@ -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();
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче