Restore ContainsLexicalThsi flag for performance
This commit is contained in:
parent
86242eed87
commit
2fb0b85cf0
3 changed files with 39 additions and 91 deletions
|
@ -3099,8 +3099,7 @@ namespace ts {
|
|||
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
// super property or element accesses could be inside lambdas, etc, and need a captured `this`,
|
||||
// while super keyword for super calls (indicated by TransformFlags.Super) does not (since it can only be top-level in a constructor)
|
||||
|
||||
if (expression.transformFlags & TransformFlags.ContainsSuper) {
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
@ -3108,12 +3107,6 @@ namespace ts {
|
|||
|
||||
if (expression.kind === SyntaxKind.ImportKeyword) {
|
||||
transformFlags |= TransformFlags.ContainsDynamicImport;
|
||||
|
||||
// A dynamic 'import()' call that contains a lexical 'this' will
|
||||
// require a captured 'this' when emitting down-level.
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
|
||||
}
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -3236,12 +3229,6 @@ namespace ts {
|
|||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
|
||||
// A computed property name containing `this` might need to be rewritten,
|
||||
// so propagate the ContainsLexicalThis flag upward.
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
@ -3259,12 +3246,6 @@ namespace ts {
|
|||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
|
||||
// A computed property name containing `this` might need to be rewritten,
|
||||
// so propagate the ContainsLexicalThis flag upward.
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.ClassExcludes;
|
||||
}
|
||||
|
@ -3369,7 +3350,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.MethodOrAccessorExcludes;
|
||||
return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.MethodOrAccessorExcludes);
|
||||
}
|
||||
|
||||
function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) {
|
||||
|
@ -3391,7 +3372,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.MethodOrAccessorExcludes;
|
||||
return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.MethodOrAccessorExcludes);
|
||||
}
|
||||
|
||||
function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) {
|
||||
|
@ -3405,7 +3386,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.NodeExcludes;
|
||||
return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.PropertyExcludes);
|
||||
}
|
||||
|
||||
function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) {
|
||||
|
@ -3439,13 +3420,6 @@ namespace ts {
|
|||
transformFlags |= TransformFlags.AssertES2018;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration is generator function and is the body of a
|
||||
// transformed async function, then this node can be transformed to a
|
||||
// down-level generator.
|
||||
|
@ -3481,14 +3455,6 @@ namespace ts {
|
|||
transformFlags |= TransformFlags.AssertES2018;
|
||||
}
|
||||
|
||||
|
||||
// If a FunctionExpression's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// If a FunctionExpression is generator function and is the body of a
|
||||
// transformed async function, then this node can be transformed to a
|
||||
// down-level generator.
|
||||
|
@ -3522,11 +3488,6 @@ namespace ts {
|
|||
transformFlags |= TransformFlags.AssertES2018;
|
||||
}
|
||||
|
||||
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.ArrowFunctionExcludes;
|
||||
}
|
||||
|
@ -3810,17 +3771,6 @@ namespace ts {
|
|||
// This is so that they can flow through PropertyName transforms unaffected.
|
||||
// Instead, we mark the container as ES6, so that it can properly handle the transform.
|
||||
transformFlags |= TransformFlags.ContainsComputedPropertyName;
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
// A computed method name like `[this.getName()](x: string) { ... }` needs to
|
||||
// distinguish itself from the normal case of a method body containing `this`:
|
||||
// `this` inside a method doesn't need to be rewritten (the method provides `this`),
|
||||
// whereas `this` inside a computed name *might* need to be rewritten if the class/object
|
||||
// is inside an arrow function:
|
||||
// `_this = this; () => class K { [_this.getName()]() { ... } }`
|
||||
// To make this distinction, use ContainsLexicalThisInComputedPropertyName
|
||||
// instead of ContainsLexicalThis for computed property names
|
||||
transformFlags |= TransformFlags.ContainsLexicalThisInComputedPropertyName;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadElement:
|
||||
|
@ -3839,7 +3789,6 @@ namespace ts {
|
|||
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// Mark this node and its ancestors as containing a lexical `this` keyword.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
break;
|
||||
|
||||
|
@ -3876,12 +3825,6 @@ namespace ts {
|
|||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
|
||||
// A computed property name containing `this` might need to be rewritten,
|
||||
// so propagate the ContainsLexicalThis flag upward.
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
// If an ObjectLiteralExpression contains a spread element, then it
|
||||
// is an ES2018 node.
|
||||
|
@ -3906,10 +3849,6 @@ namespace ts {
|
|||
break;
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ReturnStatement:
|
||||
|
@ -3927,6 +3866,10 @@ namespace ts {
|
|||
return transformFlags & ~excludeFlags;
|
||||
}
|
||||
|
||||
function propagatePropertyNameFlags(node: PropertyName, transformFlags: TransformFlags) {
|
||||
return transformFlags | (node.transformFlags & TransformFlags.PropertyNamePropagatingFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform flags to exclude when unioning the transform flags of a subtree.
|
||||
*
|
||||
|
|
|
@ -229,8 +229,7 @@ namespace ts {
|
|||
//
|
||||
|
||||
NewTarget = 1 << 13, // Contains a 'new.target' meta-property
|
||||
LexicalThis = 1 << 14, // Contains a lexical `this` reference.
|
||||
CapturedLexicalThis = 1 << 15, // Contains a lexical `this` reference captured by an arrow function.
|
||||
CapturedLexicalThis = 1 << 14, // Contains a lexical `this` reference captured by an arrow function.
|
||||
|
||||
//
|
||||
// Subtree masks
|
||||
|
@ -239,7 +238,7 @@ namespace ts {
|
|||
SubtreeFactsMask = ~AncestorFactsMask,
|
||||
|
||||
ArrowFunctionSubtreeExcludes = None,
|
||||
FunctionSubtreeExcludes = NewTarget | LexicalThis | CapturedLexicalThis,
|
||||
FunctionSubtreeExcludes = NewTarget | CapturedLexicalThis,
|
||||
}
|
||||
|
||||
export function transformES2015(context: TransformationContext) {
|
||||
|
@ -565,7 +564,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function visitThisKeyword(node: Node): Node {
|
||||
hierarchyFacts |= HierarchyFacts.LexicalThis;
|
||||
if (hierarchyFacts & HierarchyFacts.ArrowFunction) {
|
||||
hierarchyFacts |= HierarchyFacts.CapturedLexicalThis;
|
||||
}
|
||||
|
@ -989,7 +987,7 @@ namespace ts {
|
|||
insertCaptureNewTargetIfNeeded(prologue, constructor, /*copyOnWrite*/ false);
|
||||
|
||||
if (isDerivedClass) {
|
||||
if (superCallExpression && statementOffset === constructor.body.statements.length && !(hierarchyFacts & HierarchyFacts.LexicalThis)) {
|
||||
if (superCallExpression && statementOffset === constructor.body.statements.length && !(constructor.body.transformFlags & TransformFlags.ContainsLexicalThis)) {
|
||||
// If the subclass constructor does *not* contain `this` and *ends* with a `super()` call, we will use the
|
||||
// following representation:
|
||||
//
|
||||
|
@ -1693,6 +1691,10 @@ namespace ts {
|
|||
* @param node An ArrowFunction node.
|
||||
*/
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
if (node.transformFlags & TransformFlags.ContainsLexicalThis) {
|
||||
hierarchyFacts |= HierarchyFacts.CapturedLexicalThis;
|
||||
}
|
||||
|
||||
const savedConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = undefined;
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.ArrowFunctionExcludes, HierarchyFacts.ArrowFunctionIncludes);
|
||||
|
|
|
@ -5055,20 +5055,18 @@ namespace ts {
|
|||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsTypeScriptClassSyntax = 1 << 11, // Decorators, Property Initializers, Parameter Property Initializers
|
||||
ContainsLexicalThis = 1 << 12,
|
||||
ContainsCapturedLexicalThis = 1 << 13,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 14,
|
||||
ContainsRestOrSpread = 1 << 15,
|
||||
ContainsObjectRestOrSpread = 1 << 16,
|
||||
ContainsComputedPropertyName = 1 << 17,
|
||||
ContainsBlockScopedBinding = 1 << 18,
|
||||
ContainsBindingPattern = 1 << 19,
|
||||
ContainsYield = 1 << 20,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 21,
|
||||
ContainsDynamicImport = 1 << 22,
|
||||
Super = 1 << 23,
|
||||
ContainsSuper = 1 << 24,
|
||||
ContainsLexicalThis = 1 << 11,
|
||||
ContainsTypeScriptClassSyntax = 1 << 12, // Decorators, Property Initializers, Parameter Property Initializers
|
||||
ContainsRestOrSpread = 1 << 13,
|
||||
ContainsObjectRestOrSpread = 1 << 14,
|
||||
ContainsComputedPropertyName = 1 << 15,
|
||||
ContainsBlockScopedBinding = 1 << 16,
|
||||
ContainsBindingPattern = 1 << 17,
|
||||
ContainsYield = 1 << 18,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 19,
|
||||
ContainsDynamicImport = 1 << 20,
|
||||
Super = 1 << 21,
|
||||
ContainsSuper = 1 << 22,
|
||||
|
||||
// Please leave this as 1 << 29.
|
||||
// It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
|
||||
|
@ -5093,20 +5091,25 @@ namespace ts {
|
|||
OuterExpressionExcludes = DestructuringAssignment | Generator | HasComputedFlags,
|
||||
PropertyAccessExcludes = OuterExpressionExcludes | Super,
|
||||
NodeExcludes = PropertyAccessExcludes | ContainsSuper,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
FunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ConstructorExcludes = NodeExcludes | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ClassExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
|
||||
ModuleExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
FunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ConstructorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
PropertyExcludes = NodeExcludes | ContainsLexicalThis,
|
||||
ClassExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsComputedPropertyName,
|
||||
ModuleExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
TypeExcludes = ~ContainsTypeScript,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName | ContainsObjectRestOrSpread,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsComputedPropertyName | ContainsObjectRestOrSpread,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsRestOrSpread,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ParameterExcludes = NodeExcludes,
|
||||
CatchClauseExcludes = NodeExcludes | ContainsObjectRestOrSpread,
|
||||
BindingPatternExcludes = NodeExcludes | ContainsRestOrSpread,
|
||||
|
||||
// Propagating flags
|
||||
// - Bitmasks for flags that should propagate from a child
|
||||
PropertyNamePropagatingFlags = ContainsLexicalThis,
|
||||
|
||||
// Masks
|
||||
// - Additional bitmasks
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue