diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5956facf319..afd727b6f92 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3088,19 +3088,18 @@ namespace ts { function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; + const callee = skipOuterExpressions(node.expression); const expression = node.expression; if (node.typeArguments) { transformFlags |= TransformFlags.AssertTypeScript; } - if (subtreeFlags & TransformFlags.ContainsRestOrSpread - || (expression.transformFlags & (TransformFlags.Super | TransformFlags.ContainsSuper))) { + if (subtreeFlags & TransformFlags.ContainsRestOrSpread || isSuperOrSuperProperty(callee)) { // If the this node contains a SpreadExpression, or is a super call, then it is an ES6 // node. transformFlags |= TransformFlags.AssertES2015; - - if (expression.transformFlags & TransformFlags.ContainsSuper) { + if (isSuperProperty(callee)) { transformFlags |= TransformFlags.ContainsLexicalThis; } } @@ -3497,11 +3496,10 @@ namespace ts { // If a PropertyAccessExpression starts with a super keyword, then it is // ES6 syntax, and requires a lexical `this` binding. - if (transformFlags & TransformFlags.Super) { - transformFlags ^= TransformFlags.Super; + if (node.expression.kind === SyntaxKind.SuperKeyword) { // super inside of an async function requires hoisting the super access (ES2017). // same for super inside of an async generator, which is ES2018. - transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; + transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -3510,16 +3508,13 @@ namespace ts { function computeElementAccess(node: ElementAccessExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionFlags = expression.transformFlags; // We do not want to aggregate flags from the argument expression for super/this capturing // If an ElementAccessExpression starts with a super keyword, then it is // ES6 syntax, and requires a lexical `this` binding. - if (expressionFlags & TransformFlags.Super) { - transformFlags &= ~TransformFlags.Super; + if (node.expression.kind === SyntaxKind.SuperKeyword) { // super inside of an async function requires hoisting the super access (ES2017). // same for super inside of an async generator, which is ES2018. - transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; + transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -3783,7 +3778,7 @@ namespace ts { case SyntaxKind.SuperKeyword: // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.Super; + transformFlags |= TransformFlags.AssertES2015; excludeFlags = TransformFlags.OuterExpressionExcludes; // must be set to persist `Super` break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d6aecb3e177..d89502a55f8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5048,25 +5048,22 @@ namespace ts { ContainsES2017 = 1 << 4, ContainsES2016 = 1 << 5, ContainsES2015 = 1 << 6, - Generator = 1 << 7, - ContainsGenerator = 1 << 8, - DestructuringAssignment = 1 << 9, - ContainsDestructuringAssignment = 1 << 10, + ContainsGenerator = 1 << 7, + DestructuringAssignment = 1 << 8, + ContainsDestructuringAssignment = 1 << 9, // Markers // - Flags used to indicate that a subtree contains a specific transformation. + ContainsTypeScriptClassSyntax = 1 << 10, // Decorators, Property Initializers, Parameter Property Initializers 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, + ContainsRestOrSpread = 1 << 12, + ContainsObjectRestOrSpread = 1 << 13, + ContainsComputedPropertyName = 1 << 14, + ContainsBlockScopedBinding = 1 << 15, + ContainsBindingPattern = 1 << 16, + ContainsYield = 1 << 17, + ContainsHoistedDeclarationOrCompletion = 1 << 18, + ContainsDynamicImport = 1 << 19, // 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. @@ -5082,15 +5079,15 @@ namespace ts { AssertES2017 = ContainsES2017, AssertES2016 = ContainsES2016, AssertES2015 = ContainsES2015, - AssertGenerator = Generator | ContainsGenerator, + AssertGenerator = ContainsGenerator, AssertDestructuringAssignment = DestructuringAssignment | ContainsDestructuringAssignment, // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. - OuterExpressionExcludes = DestructuringAssignment | Generator | HasComputedFlags, - PropertyAccessExcludes = OuterExpressionExcludes | Super, - NodeExcludes = PropertyAccessExcludes | ContainsSuper, + OuterExpressionExcludes = DestructuringAssignment | HasComputedFlags, + PropertyAccessExcludes = OuterExpressionExcludes, + NodeExcludes = PropertyAccessExcludes, 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, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ef8a1dd9653..3ead19c01c9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1473,6 +1473,11 @@ namespace ts { } } + export function isSuperOrSuperProperty(node: Node): node is SuperExpression | SuperProperty { + return node.kind === SyntaxKind.SuperKeyword + || isSuperProperty(node); + } + /** * Determines whether a node is a property or element access expression for `super`. */