mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Decorators normative updates (#55276)
This commit is contained in:
@@ -32875,7 +32875,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
*/
|
||||
function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression | undefined {
|
||||
const expression = node.kind === SyntaxKind.CallExpression ? node.expression :
|
||||
node.kind === SyntaxKind.TaggedTemplateExpression ? node.tag : undefined;
|
||||
node.kind === SyntaxKind.TaggedTemplateExpression ? node.tag :
|
||||
node.kind === SyntaxKind.Decorator && !legacyDecorators ? node.expression :
|
||||
undefined;
|
||||
if (expression) {
|
||||
const callee = skipOuterExpressions(expression);
|
||||
if (isAccessExpression(callee)) {
|
||||
|
||||
@@ -1645,7 +1645,7 @@ export function createAccessorPropertyBackingField(factory: NodeFactory, node: P
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function createAccessorPropertyGetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: ModifiersArray | undefined, name: PropertyName): GetAccessorDeclaration {
|
||||
export function createAccessorPropertyGetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()): GetAccessorDeclaration {
|
||||
return factory.createGetAccessorDeclaration(
|
||||
modifiers,
|
||||
name,
|
||||
@@ -1654,7 +1654,7 @@ export function createAccessorPropertyGetRedirector(factory: NodeFactory, node:
|
||||
factory.createBlock([
|
||||
factory.createReturnStatement(
|
||||
factory.createPropertyAccessExpression(
|
||||
factory.createThis(),
|
||||
receiver,
|
||||
factory.getGeneratedPrivateNameForNode(node.name, /*prefix*/ undefined, "_accessor_storage")
|
||||
)
|
||||
)
|
||||
@@ -1667,7 +1667,7 @@ export function createAccessorPropertyGetRedirector(factory: NodeFactory, node:
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: ModifiersArray | undefined, name: PropertyName) {
|
||||
export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()) {
|
||||
return factory.createSetAccessorDeclaration(
|
||||
modifiers,
|
||||
name,
|
||||
@@ -1680,7 +1680,7 @@ export function createAccessorPropertySetRedirector(factory: NodeFactory, node:
|
||||
factory.createExpressionStatement(
|
||||
factory.createAssignment(
|
||||
factory.createPropertyAccessExpression(
|
||||
factory.createThis(),
|
||||
receiver,
|
||||
factory.getGeneratedPrivateNameForNode(node.name, /*prefix*/ undefined, "_accessor_storage")
|
||||
),
|
||||
factory.createIdentifier("value")
|
||||
|
||||
@@ -154,6 +154,7 @@ import {
|
||||
Modifier,
|
||||
ModifierFlags,
|
||||
ModifierLike,
|
||||
modifiersToFlags,
|
||||
moveRangePastModifiers,
|
||||
moveRangePos,
|
||||
newPrivateEnvironment,
|
||||
@@ -896,6 +897,12 @@ export function transformClassFields(context: TransformationContext): (x: Source
|
||||
}
|
||||
}
|
||||
|
||||
function getClassThis() {
|
||||
const lex = getClassLexicalEnvironment();
|
||||
const classThis = lex.classThis ?? lex.classConstructor ?? currentClassContainer?.name;
|
||||
return Debug.checkDefined(classThis);
|
||||
}
|
||||
|
||||
function transformAutoAccessor(node: AutoAccessorPropertyDeclaration): VisitResult<Node> {
|
||||
// transforms:
|
||||
// accessor x = 1;
|
||||
@@ -935,12 +942,15 @@ export function transformClassFields(context: TransformationContext): (x: Source
|
||||
setEmitFlags(backingField, EmitFlags.NoComments);
|
||||
setSourceMapRange(backingField, sourceMapRange);
|
||||
|
||||
const getter = createAccessorPropertyGetRedirector(factory, node, modifiers, getterName);
|
||||
const receiver = isStatic(node) ? getClassThis() : factory.createThis();
|
||||
const getter = createAccessorPropertyGetRedirector(factory, node, modifiers, getterName, receiver);
|
||||
setOriginalNode(getter, node);
|
||||
setCommentRange(getter, commentRange);
|
||||
setSourceMapRange(getter, sourceMapRange);
|
||||
|
||||
const setter = createAccessorPropertySetRedirector(factory, node, modifiers, setterName);
|
||||
// create a fresh copy of the modifiers so that we don't duplicate comments
|
||||
const setterModifiers = factory.createModifiersFromModifierFlags(modifiersToFlags(modifiers));
|
||||
const setter = createAccessorPropertySetRedirector(factory, node, setterModifiers, setterName, receiver);
|
||||
setOriginalNode(setter, node);
|
||||
setEmitFlags(setter, EmitFlags.NoComments);
|
||||
setSourceMapRange(setter, sourceMapRange);
|
||||
@@ -1692,11 +1702,13 @@ export function transformClassFields(context: TransformationContext): (x: Source
|
||||
let containsInstanceAutoAccessors = false;
|
||||
for (const member of node.members) {
|
||||
if (isStatic(member)) {
|
||||
if (member.name &&
|
||||
(isPrivateIdentifier(member.name) || isAutoAccessorPropertyDeclaration(member)) &&
|
||||
if (member.name && (isPrivateIdentifier(member.name) || isAutoAccessorPropertyDeclaration(member)) &&
|
||||
shouldTransformPrivateElementsOrClassStaticBlocks) {
|
||||
facts |= ClassFacts.NeedsClassConstructorReference;
|
||||
}
|
||||
else if (isAutoAccessorPropertyDeclaration(member) && shouldTransformAutoAccessors === Ternary.True && !node.name && !node.emitNode?.classThis) {
|
||||
facts |= ClassFacts.NeedsClassConstructorReference;
|
||||
}
|
||||
if (isPropertyDeclaration(member) || isClassStaticBlockDeclaration(member)) {
|
||||
if (shouldTransformThisInStaticInitializers && member.transformFlags & TransformFlags.ContainsLexicalThis) {
|
||||
facts |= ClassFacts.NeedsSubstitutionForThisInClassStaticField;
|
||||
@@ -1846,10 +1858,10 @@ export function transformClassFields(context: TransformationContext): (x: Source
|
||||
getClassLexicalEnvironment().classConstructor = factory.cloneNode(temp);
|
||||
pendingClassReferenceAssignment = factory.createAssignment(temp, factory.getInternalName(node));
|
||||
}
|
||||
}
|
||||
|
||||
if (node.emitNode?.classThis) {
|
||||
getClassLexicalEnvironment().classThis = node.emitNode.classThis;
|
||||
}
|
||||
if (node.emitNode?.classThis) {
|
||||
getClassLexicalEnvironment().classThis = node.emitNode.classThis;
|
||||
}
|
||||
|
||||
const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsConstructorReference;
|
||||
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
getAllDecoratorsOfClassElement,
|
||||
getCommentRange,
|
||||
getEffectiveBaseTypeNode,
|
||||
getEmitScriptTarget,
|
||||
getFirstConstructorWithBody,
|
||||
getHeritageClause,
|
||||
getNonAssignmentOperatorForCompoundAssignment,
|
||||
@@ -62,6 +63,7 @@ import {
|
||||
injectClassNamedEvaluationHelperBlockIfMissing,
|
||||
injectClassThisAssignmentIfMissing,
|
||||
InternalEmitFlags,
|
||||
isAccessExpression,
|
||||
isAmbientPropertyDeclaration,
|
||||
isArrayBindingOrAssignmentElement,
|
||||
isArrayLiteralExpression,
|
||||
@@ -289,6 +291,7 @@ export function transformESDecorators(context: TransformationContext): (x: Sourc
|
||||
hoistVariableDeclaration,
|
||||
} = context;
|
||||
|
||||
const languageVersion = getEmitScriptTarget(context.getCompilerOptions());
|
||||
let top: LexicalEnvironmentStackEntry | undefined;
|
||||
let classInfo: ClassInfo | undefined;
|
||||
let classThis: Identifier | undefined;
|
||||
@@ -2147,6 +2150,13 @@ export function transformESDecorators(context: TransformationContext): (x: Sourc
|
||||
function transformDecorator(decorator: Decorator) {
|
||||
const expression = visitNode(decorator.expression, visitor, isExpression);
|
||||
setEmitFlags(expression, EmitFlags.NoComments);
|
||||
|
||||
// preserve the 'this' binding for an access expression
|
||||
const innerExpression = skipOuterExpressions(expression);
|
||||
if (isAccessExpression(innerExpression)) {
|
||||
const { target, thisArg } = factory.createCallBinding(expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true);
|
||||
return factory.restoreOuterExpressions(expression, factory.createFunctionBindCall(target, thisArg, []));
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user