1/*@internal*/ 2namespace ts { 3 const enum ESNextSubstitutionFlags { 4 /** Enables substitutions for async methods with `super` calls. */ 5 AsyncMethodsWithSuper = 1 << 0 6 } 7 8 // Facts we track as we traverse the tree 9 const enum HierarchyFacts { 10 None = 0, 11 12 // 13 // Ancestor facts 14 // 15 16 HasLexicalThis = 1 << 0, 17 IterationContainer = 1 << 1, 18 // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below. 19 20 // 21 // Ancestor masks 22 // 23 24 AncestorFactsMask = (IterationContainer << 1) - 1, 25 26 SourceFileIncludes = HasLexicalThis, 27 SourceFileExcludes = IterationContainer, 28 StrictModeSourceFileIncludes = None, 29 30 ClassOrFunctionIncludes = HasLexicalThis, 31 ClassOrFunctionExcludes = IterationContainer, 32 33 ArrowFunctionIncludes = None, 34 ArrowFunctionExcludes = ClassOrFunctionExcludes, 35 36 IterationStatementIncludes = IterationContainer, 37 IterationStatementExcludes = None, 38 } 39 40 export function transformES2018(context: TransformationContext) { 41 const { 42 factory, 43 getEmitHelperFactory: emitHelpers, 44 resumeLexicalEnvironment, 45 endLexicalEnvironment, 46 hoistVariableDeclaration 47 } = context; 48 49 const resolver = context.getEmitResolver(); 50 const compilerOptions = context.getCompilerOptions(); 51 const languageVersion = getEmitScriptTarget(compilerOptions); 52 53 const previousOnEmitNode = context.onEmitNode; 54 context.onEmitNode = onEmitNode; 55 56 const previousOnSubstituteNode = context.onSubstituteNode; 57 context.onSubstituteNode = onSubstituteNode; 58 59 let exportedVariableStatement = false; 60 let enabledSubstitutions: ESNextSubstitutionFlags; 61 let enclosingFunctionFlags: FunctionFlags; 62 let enclosingSuperContainerFlags: NodeCheckFlags = 0; 63 let hierarchyFacts: HierarchyFacts = 0; 64 65 let currentSourceFile: SourceFile; 66 let taggedTemplateStringDeclarations: VariableDeclaration[]; 67 68 /** Keeps track of property names accessed on super (`super.x`) within async functions. */ 69 let capturedSuperProperties: Set<__String>; 70 /** Whether the async function contains an element access on super (`super[x]`). */ 71 let hasSuperElementAccess: boolean; 72 /** A set of node IDs for generated super accessors. */ 73 const substitutedSuperAccessors: boolean[] = []; 74 75 return chainBundle(context, transformSourceFile); 76 77 function affectsSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { 78 return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts); 79 } 80 81 /** 82 * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification. 83 * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree. 84 * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree. 85 */ 86 function enterSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { 87 const ancestorFacts = hierarchyFacts; 88 hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & HierarchyFacts.AncestorFactsMask; 89 return ancestorFacts; 90 } 91 92 /** 93 * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's 94 * subtree. 95 * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree. 96 */ 97 function exitSubtree(ancestorFacts: HierarchyFacts) { 98 hierarchyFacts = ancestorFacts; 99 } 100 101 function recordTaggedTemplateString(temp: Identifier) { 102 taggedTemplateStringDeclarations = append( 103 taggedTemplateStringDeclarations, 104 factory.createVariableDeclaration(temp)); 105 } 106 107 function transformSourceFile(node: SourceFile) { 108 if (node.isDeclarationFile) { 109 return node; 110 } 111 112 currentSourceFile = node; 113 const visited = visitSourceFile(node); 114 addEmitHelpers(visited, context.readEmitHelpers()); 115 116 currentSourceFile = undefined!; 117 taggedTemplateStringDeclarations = undefined!; 118 return visited; 119 } 120 121 function visitor(node: Node): VisitResult<Node> { 122 return visitorWorker(node, /*expressionResultIsUnused*/ false); 123 } 124 125 function visitorWithUnusedExpressionResult(node: Node): VisitResult<Node> { 126 return visitorWorker(node, /*expressionResultIsUnused*/ true); 127 } 128 129 function visitorNoAsyncModifier(node: Node): VisitResult<Node> { 130 if (node.kind === SyntaxKind.AsyncKeyword) { 131 return undefined; 132 } 133 return node; 134 } 135 136 function doWithHierarchyFacts<T, U>(cb: (value: T) => U, value: T, excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { 137 if (affectsSubtree(excludeFacts, includeFacts)) { 138 const ancestorFacts = enterSubtree(excludeFacts, includeFacts); 139 const result = cb(value); 140 exitSubtree(ancestorFacts); 141 return result; 142 } 143 return cb(value); 144 } 145 146 function visitDefault(node: Node): VisitResult<Node> { 147 return visitEachChild(node, visitor, context); 148 } 149 150 /** 151 * @param expressionResultIsUnused Indicates the result of an expression is unused by the parent node (i.e., the left side of a comma or the 152 * expression of an `ExpressionStatement`). 153 */ 154 function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult<Node> { 155 if ((node.transformFlags & TransformFlags.ContainsES2018) === 0) { 156 return node; 157 } 158 switch (node.kind) { 159 case SyntaxKind.AwaitExpression: 160 return visitAwaitExpression(node as AwaitExpression); 161 case SyntaxKind.YieldExpression: 162 return visitYieldExpression(node as YieldExpression); 163 case SyntaxKind.ReturnStatement: 164 return visitReturnStatement(node as ReturnStatement); 165 case SyntaxKind.LabeledStatement: 166 return visitLabeledStatement(node as LabeledStatement); 167 case SyntaxKind.ObjectLiteralExpression: 168 return visitObjectLiteralExpression(node as ObjectLiteralExpression); 169 case SyntaxKind.BinaryExpression: 170 return visitBinaryExpression(node as BinaryExpression, expressionResultIsUnused); 171 case SyntaxKind.CommaListExpression: 172 return visitCommaListExpression(node as CommaListExpression, expressionResultIsUnused); 173 case SyntaxKind.CatchClause: 174 return visitCatchClause(node as CatchClause); 175 case SyntaxKind.VariableStatement: 176 return visitVariableStatement(node as VariableStatement); 177 case SyntaxKind.VariableDeclaration: 178 return visitVariableDeclaration(node as VariableDeclaration); 179 case SyntaxKind.DoStatement: 180 case SyntaxKind.WhileStatement: 181 case SyntaxKind.ForInStatement: 182 return doWithHierarchyFacts( 183 visitDefault, 184 node, 185 HierarchyFacts.IterationStatementExcludes, 186 HierarchyFacts.IterationStatementIncludes); 187 case SyntaxKind.ForOfStatement: 188 return visitForOfStatement(node as ForOfStatement, /*outermostLabeledStatement*/ undefined); 189 case SyntaxKind.ForStatement: 190 return doWithHierarchyFacts( 191 visitForStatement, 192 node as ForStatement, 193 HierarchyFacts.IterationStatementExcludes, 194 HierarchyFacts.IterationStatementIncludes); 195 case SyntaxKind.VoidExpression: 196 return visitVoidExpression(node as VoidExpression); 197 case SyntaxKind.Constructor: 198 return doWithHierarchyFacts( 199 visitConstructorDeclaration, 200 node as ConstructorDeclaration, 201 HierarchyFacts.ClassOrFunctionExcludes, 202 HierarchyFacts.ClassOrFunctionIncludes); 203 case SyntaxKind.MethodDeclaration: 204 return doWithHierarchyFacts( 205 visitMethodDeclaration, 206 node as MethodDeclaration, 207 HierarchyFacts.ClassOrFunctionExcludes, 208 HierarchyFacts.ClassOrFunctionIncludes); 209 case SyntaxKind.GetAccessor: 210 return doWithHierarchyFacts( 211 visitGetAccessorDeclaration, 212 node as GetAccessorDeclaration, 213 HierarchyFacts.ClassOrFunctionExcludes, 214 HierarchyFacts.ClassOrFunctionIncludes); 215 case SyntaxKind.SetAccessor: 216 return doWithHierarchyFacts( 217 visitSetAccessorDeclaration, 218 node as SetAccessorDeclaration, 219 HierarchyFacts.ClassOrFunctionExcludes, 220 HierarchyFacts.ClassOrFunctionIncludes); 221 case SyntaxKind.FunctionDeclaration: 222 return doWithHierarchyFacts( 223 visitFunctionDeclaration, 224 node as FunctionDeclaration, 225 HierarchyFacts.ClassOrFunctionExcludes, 226 HierarchyFacts.ClassOrFunctionIncludes); 227 case SyntaxKind.FunctionExpression: 228 return doWithHierarchyFacts( 229 visitFunctionExpression, 230 node as FunctionExpression, 231 HierarchyFacts.ClassOrFunctionExcludes, 232 HierarchyFacts.ClassOrFunctionIncludes); 233 case SyntaxKind.ArrowFunction: 234 return doWithHierarchyFacts( 235 visitArrowFunction, 236 node as ArrowFunction, 237 HierarchyFacts.ArrowFunctionExcludes, 238 HierarchyFacts.ArrowFunctionIncludes); 239 case SyntaxKind.Parameter: 240 return visitParameter(node as ParameterDeclaration); 241 case SyntaxKind.ExpressionStatement: 242 return visitExpressionStatement(node as ExpressionStatement); 243 case SyntaxKind.ParenthesizedExpression: 244 return visitParenthesizedExpression(node as ParenthesizedExpression, expressionResultIsUnused); 245 case SyntaxKind.TaggedTemplateExpression: 246 return visitTaggedTemplateExpression(node as TaggedTemplateExpression); 247 case SyntaxKind.PropertyAccessExpression: 248 if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) { 249 capturedSuperProperties.add(node.name.escapedText); 250 } 251 return visitEachChild(node, visitor, context); 252 case SyntaxKind.ElementAccessExpression: 253 if (capturedSuperProperties && (<ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) { 254 hasSuperElementAccess = true; 255 } 256 return visitEachChild(node, visitor, context); 257 case SyntaxKind.ClassDeclaration: 258 case SyntaxKind.ClassExpression: 259 return doWithHierarchyFacts( 260 visitDefault, 261 node, 262 HierarchyFacts.ClassOrFunctionExcludes, 263 HierarchyFacts.ClassOrFunctionIncludes); 264 default: 265 return visitEachChild(node, visitor, context); 266 } 267 } 268 269 function visitAwaitExpression(node: AwaitExpression): Expression { 270 if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { 271 return setOriginalNode( 272 setTextRange( 273 factory.createYieldExpression(/*asteriskToken*/ undefined, emitHelpers().createAwaitHelper(visitNode(node.expression, visitor, isExpression))), 274 /*location*/ node 275 ), 276 node 277 ); 278 } 279 return visitEachChild(node, visitor, context); 280 } 281 282 function visitYieldExpression(node: YieldExpression) { 283 if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { 284 if (node.asteriskToken) { 285 const expression = visitNode(Debug.assertDefined(node.expression), visitor, isExpression); 286 287 return setOriginalNode( 288 setTextRange( 289 factory.createYieldExpression( 290 /*asteriskToken*/ undefined, 291 emitHelpers().createAwaitHelper( 292 factory.updateYieldExpression( 293 node, 294 node.asteriskToken, 295 setTextRange( 296 emitHelpers().createAsyncDelegatorHelper( 297 setTextRange( 298 emitHelpers().createAsyncValuesHelper(expression), 299 expression 300 ) 301 ), 302 expression 303 ) 304 ) 305 ) 306 ), 307 node 308 ), 309 node 310 ); 311 } 312 313 return setOriginalNode( 314 setTextRange( 315 factory.createYieldExpression( 316 /*asteriskToken*/ undefined, 317 createDownlevelAwait( 318 node.expression 319 ? visitNode(node.expression, visitor, isExpression) 320 : factory.createVoidZero() 321 ) 322 ), 323 node 324 ), 325 node 326 ); 327 } 328 329 return visitEachChild(node, visitor, context); 330 } 331 332 function visitReturnStatement(node: ReturnStatement) { 333 if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { 334 return factory.updateReturnStatement(node, createDownlevelAwait( 335 node.expression ? visitNode(node.expression, visitor, isExpression) : factory.createVoidZero() 336 )); 337 } 338 339 return visitEachChild(node, visitor, context); 340 } 341 342 function visitLabeledStatement(node: LabeledStatement) { 343 if (enclosingFunctionFlags & FunctionFlags.Async) { 344 const statement = unwrapInnermostStatementOfLabel(node); 345 if (statement.kind === SyntaxKind.ForOfStatement && (<ForOfStatement>statement).awaitModifier) { 346 return visitForOfStatement(<ForOfStatement>statement, node); 347 } 348 return factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock), node); 349 } 350 return visitEachChild(node, visitor, context); 351 } 352 353 function chunkObjectLiteralElements(elements: readonly ObjectLiteralElementLike[]): Expression[] { 354 let chunkObject: ObjectLiteralElementLike[] | undefined; 355 const objects: Expression[] = []; 356 for (const e of elements) { 357 if (e.kind === SyntaxKind.SpreadAssignment) { 358 if (chunkObject) { 359 objects.push(factory.createObjectLiteralExpression(chunkObject)); 360 chunkObject = undefined; 361 } 362 const target = e.expression; 363 objects.push(visitNode(target, visitor, isExpression)); 364 } 365 else { 366 chunkObject = append(chunkObject, e.kind === SyntaxKind.PropertyAssignment 367 ? factory.createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression)) 368 : visitNode(e, visitor, isObjectLiteralElementLike)); 369 } 370 } 371 if (chunkObject) { 372 objects.push(factory.createObjectLiteralExpression(chunkObject)); 373 } 374 375 return objects; 376 } 377 378 function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression { 379 if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 380 // spread elements emit like so: 381 // non-spread elements are chunked together into object literals, and then all are passed to __assign: 382 // { a, ...o, b } => __assign(__assign({a}, o), {b}); 383 // If the first element is a spread element, then the first argument to __assign is {}: 384 // { ...o, a, b, ...o2 } => __assign(__assign(__assign({}, o), {a, b}), o2) 385 // 386 // We cannot call __assign with more than two elements, since any element could cause side effects. For 387 // example: 388 // var k = { a: 1, b: 2 }; 389 // var o = { a: 3, ...k, b: k.a++ }; 390 // // expected: { a: 1, b: 1 } 391 // If we translate the above to `__assign({ a: 3 }, k, { b: k.a++ })`, the `k.a++` will evaluate before 392 // `k` is spread and we end up with `{ a: 2, b: 1 }`. 393 // 394 // This also occurs for spread elements, not just property assignments: 395 // var k = { a: 1, get b() { l = { z: 9 }; return 2; } }; 396 // var l = { c: 3 }; 397 // var o = { ...k, ...l }; 398 // // expected: { a: 1, b: 2, z: 9 } 399 // If we translate the above to `__assign({}, k, l)`, the `l` will evaluate before `k` is spread and we 400 // end up with `{ a: 1, b: 2, c: 3 }` 401 const objects = chunkObjectLiteralElements(node.properties); 402 if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) { 403 objects.unshift(factory.createObjectLiteralExpression()); 404 } 405 let expression: Expression = objects[0]; 406 if (objects.length > 1) { 407 for (let i = 1; i < objects.length; i++) { 408 expression = emitHelpers().createAssignHelper([expression, objects[i]]); 409 } 410 return expression; 411 } 412 else { 413 return emitHelpers().createAssignHelper(objects); 414 } 415 } 416 return visitEachChild(node, visitor, context); 417 } 418 419 function visitExpressionStatement(node: ExpressionStatement): ExpressionStatement { 420 return visitEachChild(node, visitorWithUnusedExpressionResult, context); 421 } 422 423 /** 424 * @param expressionResultIsUnused Indicates the result of an expression is unused by the parent node (i.e., the left side of a comma or the 425 * expression of an `ExpressionStatement`). 426 */ 427 function visitParenthesizedExpression(node: ParenthesizedExpression, expressionResultIsUnused: boolean): ParenthesizedExpression { 428 return visitEachChild(node, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, context); 429 } 430 431 function visitSourceFile(node: SourceFile): SourceFile { 432 const ancestorFacts = enterSubtree( 433 HierarchyFacts.SourceFileExcludes, 434 isEffectiveStrictModeSourceFile(node, compilerOptions) ? 435 HierarchyFacts.StrictModeSourceFileIncludes : 436 HierarchyFacts.SourceFileIncludes); 437 exportedVariableStatement = false; 438 const visited = visitEachChild(node, visitor, context); 439 const statement = concatenate(visited.statements, taggedTemplateStringDeclarations && [ 440 factory.createVariableStatement(/*modifiers*/ undefined, 441 factory.createVariableDeclarationList(taggedTemplateStringDeclarations)) 442 ]); 443 const result = factory.updateSourceFile(visited, setTextRange(factory.createNodeArray(statement), node.statements)); 444 exitSubtree(ancestorFacts); 445 return result; 446 } 447 448 function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { 449 return processTaggedTemplateExpression( 450 context, 451 node, 452 visitor, 453 currentSourceFile, 454 recordTaggedTemplateString, 455 ProcessLevel.LiftRestriction 456 ); 457 } 458 459 /** 460 * Visits a BinaryExpression that contains a destructuring assignment. 461 * 462 * @param node A BinaryExpression node. 463 * @param expressionResultIsUnused Indicates the result of an expression is unused by the parent node (i.e., the left side of a comma or the 464 * expression of an `ExpressionStatement`). 465 */ 466 function visitBinaryExpression(node: BinaryExpression, expressionResultIsUnused: boolean): Expression { 467 if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 468 return flattenDestructuringAssignment( 469 node, 470 visitor, 471 context, 472 FlattenLevel.ObjectRest, 473 !expressionResultIsUnused 474 ); 475 } 476 if (node.operatorToken.kind === SyntaxKind.CommaToken) { 477 return factory.updateBinaryExpression( 478 node, 479 visitNode(node.left, visitorWithUnusedExpressionResult, isExpression), 480 node.operatorToken, 481 visitNode(node.right, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, isExpression) 482 ); 483 } 484 return visitEachChild(node, visitor, context); 485 } 486 487 /** 488 * @param expressionResultIsUnused Indicates the result of an expression is unused by the parent node (i.e., the left side of a comma or the 489 * expression of an `ExpressionStatement`). 490 */ 491 function visitCommaListExpression(node: CommaListExpression, expressionResultIsUnused: boolean): Expression { 492 if (expressionResultIsUnused) { 493 return visitEachChild(node, visitorWithUnusedExpressionResult, context); 494 } 495 let result: Expression[] | undefined; 496 for (let i = 0; i < node.elements.length; i++) { 497 const element = node.elements[i]; 498 const visited = visitNode(element, i < node.elements.length - 1 ? visitorWithUnusedExpressionResult : visitor, isExpression); 499 if (result || visited !== element) { 500 result ||= node.elements.slice(0, i); 501 result.push(visited); 502 } 503 } 504 const elements = result ? setTextRange(factory.createNodeArray(result), node.elements) : node.elements; 505 return factory.updateCommaListExpression(node, elements); 506 } 507 508 function visitCatchClause(node: CatchClause) { 509 if (node.variableDeclaration && 510 isBindingPattern(node.variableDeclaration.name) && 511 node.variableDeclaration.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 512 const name = factory.getGeneratedNameForNode(node.variableDeclaration.name); 513 const updatedDecl = factory.updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*exclamationToken*/ undefined, /*type*/ undefined, name); 514 const visitedBindings = flattenDestructuringBinding(updatedDecl, visitor, context, FlattenLevel.ObjectRest); 515 let block = visitNode(node.block, visitor, isBlock); 516 if (some(visitedBindings)) { 517 block = factory.updateBlock(block, [ 518 factory.createVariableStatement(/*modifiers*/ undefined, visitedBindings), 519 ...block.statements, 520 ]); 521 } 522 return factory.updateCatchClause( 523 node, 524 factory.updateVariableDeclaration(node.variableDeclaration, name, /*exclamationToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined), 525 block); 526 } 527 return visitEachChild(node, visitor, context); 528 } 529 530 function visitVariableStatement(node: VariableStatement): VisitResult<VariableStatement> { 531 if (hasSyntacticModifier(node, ModifierFlags.Export)) { 532 const savedExportedVariableStatement = exportedVariableStatement; 533 exportedVariableStatement = true; 534 const visited = visitEachChild(node, visitor, context); 535 exportedVariableStatement = savedExportedVariableStatement; 536 return visited; 537 } 538 return visitEachChild(node, visitor, context); 539 } 540 541 /** 542 * Visits a VariableDeclaration node with a binding pattern. 543 * 544 * @param node A VariableDeclaration node. 545 */ 546 function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> { 547 if (exportedVariableStatement) { 548 const savedExportedVariableStatement = exportedVariableStatement; 549 exportedVariableStatement = false; 550 const visited = visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ true); 551 exportedVariableStatement = savedExportedVariableStatement; 552 return visited; 553 } 554 return visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ false); 555 } 556 557 function visitVariableDeclarationWorker(node: VariableDeclaration, exportedVariableStatement: boolean): VisitResult<VariableDeclaration> { 558 // If we are here it is because the name contains a binding pattern with a rest somewhere in it. 559 if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 560 return flattenDestructuringBinding( 561 node, 562 visitor, 563 context, 564 FlattenLevel.ObjectRest, 565 /*rval*/ undefined, 566 exportedVariableStatement 567 ); 568 } 569 return visitEachChild(node, visitor, context); 570 } 571 572 function visitForStatement(node: ForStatement): VisitResult<Statement> { 573 return factory.updateForStatement( 574 node, 575 visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer), 576 visitNode(node.condition, visitor, isExpression), 577 visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression), 578 visitNode(node.statement, visitor, isStatement) 579 ); 580 } 581 582 function visitVoidExpression(node: VoidExpression) { 583 return visitEachChild(node, visitorWithUnusedExpressionResult, context); 584 } 585 586 /** 587 * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement. 588 * 589 * @param node A ForOfStatement. 590 */ 591 function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult<Statement> { 592 const ancestorFacts = enterSubtree(HierarchyFacts.IterationStatementExcludes, HierarchyFacts.IterationStatementIncludes); 593 if (node.initializer.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 594 node = transformForOfStatementWithObjectRest(node); 595 } 596 const result = node.awaitModifier ? 597 transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) : 598 factory.restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement); 599 exitSubtree(ancestorFacts); 600 return result; 601 } 602 603 function transformForOfStatementWithObjectRest(node: ForOfStatement) { 604 const initializerWithoutParens = skipParentheses(node.initializer) as ForInitializer; 605 if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) { 606 let bodyLocation: TextRange | undefined; 607 let statementsLocation: TextRange | undefined; 608 const temp = factory.createTempVariable(/*recordTempVariable*/ undefined); 609 const statements: Statement[] = [createForOfBindingStatement(factory, initializerWithoutParens, temp)]; 610 if (isBlock(node.statement)) { 611 addRange(statements, node.statement.statements); 612 bodyLocation = node.statement; 613 statementsLocation = node.statement.statements; 614 } 615 else if (node.statement) { 616 append(statements, node.statement); 617 bodyLocation = node.statement; 618 statementsLocation = node.statement; 619 } 620 return factory.updateForOfStatement( 621 node, 622 node.awaitModifier, 623 setTextRange( 624 factory.createVariableDeclarationList( 625 [ 626 setTextRange(factory.createVariableDeclaration(temp), node.initializer) 627 ], 628 NodeFlags.Let 629 ), 630 node.initializer 631 ), 632 node.expression, 633 setTextRange( 634 factory.createBlock( 635 setTextRange(factory.createNodeArray(statements), statementsLocation), 636 /*multiLine*/ true 637 ), 638 bodyLocation 639 ) 640 ); 641 } 642 return node; 643 } 644 645 function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression) { 646 const binding = createForOfBindingStatement(factory, node.initializer, boundValue); 647 648 let bodyLocation: TextRange | undefined; 649 let statementsLocation: TextRange | undefined; 650 const statements: Statement[] = [visitNode(binding, visitor, isStatement)]; 651 const statement = visitNode(node.statement, visitor, isStatement); 652 if (isBlock(statement)) { 653 addRange(statements, statement.statements); 654 bodyLocation = statement; 655 statementsLocation = statement.statements; 656 } 657 else { 658 statements.push(statement); 659 } 660 661 return setEmitFlags( 662 setTextRange( 663 factory.createBlock( 664 setTextRange(factory.createNodeArray(statements), statementsLocation), 665 /*multiLine*/ true 666 ), 667 bodyLocation 668 ), 669 EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps 670 ); 671 } 672 673 function createDownlevelAwait(expression: Expression) { 674 return enclosingFunctionFlags & FunctionFlags.Generator 675 ? factory.createYieldExpression(/*asteriskToken*/ undefined, emitHelpers().createAwaitHelper(expression)) 676 : factory.createAwaitExpression(expression); 677 } 678 679 function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts) { 680 const expression = visitNode(node.expression, visitor, isExpression); 681 const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); 682 const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); 683 const errorRecord = factory.createUniqueName("e"); 684 const catchVariable = factory.getGeneratedNameForNode(errorRecord); 685 const returnMethod = factory.createTempVariable(/*recordTempVariable*/ undefined); 686 const callValues = setTextRange(emitHelpers().createAsyncValuesHelper(expression), node.expression); 687 const callNext = factory.createCallExpression(factory.createPropertyAccessExpression(iterator, "next"), /*typeArguments*/ undefined, []); 688 const getDone = factory.createPropertyAccessExpression(result, "done"); 689 const getValue = factory.createPropertyAccessExpression(result, "value"); 690 const callReturn = factory.createFunctionCallCall(returnMethod, iterator, []); 691 692 hoistVariableDeclaration(errorRecord); 693 hoistVariableDeclaration(returnMethod); 694 695 // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration 696 const initializer = ancestorFacts & HierarchyFacts.IterationContainer ? 697 factory.inlineExpressions([factory.createAssignment(errorRecord, factory.createVoidZero()), callValues]) : 698 callValues; 699 700 const forStatement = setEmitFlags( 701 setTextRange( 702 factory.createForStatement( 703 /*initializer*/ setEmitFlags( 704 setTextRange( 705 factory.createVariableDeclarationList([ 706 setTextRange(factory.createVariableDeclaration(iterator, /*exclamationToken*/ undefined, /*type*/ undefined, initializer), node.expression), 707 factory.createVariableDeclaration(result) 708 ]), 709 node.expression 710 ), 711 EmitFlags.NoHoisting 712 ), 713 /*condition*/ factory.createComma( 714 factory.createAssignment(result, createDownlevelAwait(callNext)), 715 factory.createLogicalNot(getDone) 716 ), 717 /*incrementor*/ undefined, 718 /*statement*/ convertForOfStatementHead(node, getValue) 719 ), 720 /*location*/ node 721 ), 722 EmitFlags.NoTokenTrailingSourceMaps 723 ); 724 725 return factory.createTryStatement( 726 factory.createBlock([ 727 factory.restoreEnclosingLabel( 728 forStatement, 729 outermostLabeledStatement 730 ) 731 ]), 732 factory.createCatchClause( 733 factory.createVariableDeclaration(catchVariable), 734 setEmitFlags( 735 factory.createBlock([ 736 factory.createExpressionStatement( 737 factory.createAssignment( 738 errorRecord, 739 factory.createObjectLiteralExpression([ 740 factory.createPropertyAssignment("error", catchVariable) 741 ]) 742 ) 743 ) 744 ]), 745 EmitFlags.SingleLine 746 ) 747 ), 748 factory.createBlock([ 749 factory.createTryStatement( 750 /*tryBlock*/ factory.createBlock([ 751 setEmitFlags( 752 factory.createIfStatement( 753 factory.createLogicalAnd( 754 factory.createLogicalAnd( 755 result, 756 factory.createLogicalNot(getDone) 757 ), 758 factory.createAssignment( 759 returnMethod, 760 factory.createPropertyAccessExpression(iterator, "return") 761 ) 762 ), 763 factory.createExpressionStatement(createDownlevelAwait(callReturn)) 764 ), 765 EmitFlags.SingleLine 766 ) 767 ]), 768 /*catchClause*/ undefined, 769 /*finallyBlock*/ setEmitFlags( 770 factory.createBlock([ 771 setEmitFlags( 772 factory.createIfStatement( 773 errorRecord, 774 factory.createThrowStatement( 775 factory.createPropertyAccessExpression(errorRecord, "error") 776 ) 777 ), 778 EmitFlags.SingleLine 779 ) 780 ]), 781 EmitFlags.SingleLine 782 ) 783 ) 784 ]) 785 ); 786 } 787 788 function visitParameter(node: ParameterDeclaration): ParameterDeclaration { 789 if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 790 // Binding patterns are converted into a generated name and are 791 // evaluated inside the function body. 792 return factory.updateParameterDeclaration( 793 node, 794 /*decorators*/ undefined, 795 /*modifiers*/ undefined, 796 node.dotDotDotToken, 797 factory.getGeneratedNameForNode(node), 798 /*questionToken*/ undefined, 799 /*type*/ undefined, 800 visitNode(node.initializer, visitor, isExpression) 801 ); 802 } 803 return visitEachChild(node, visitor, context); 804 } 805 806 function visitConstructorDeclaration(node: ConstructorDeclaration) { 807 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 808 enclosingFunctionFlags = FunctionFlags.Normal; 809 const updated = factory.updateConstructorDeclaration( 810 node, 811 /*decorators*/ undefined, 812 node.modifiers, 813 visitParameterList(node.parameters, visitor, context), 814 transformFunctionBody(node) 815 ); 816 enclosingFunctionFlags = savedEnclosingFunctionFlags; 817 return updated; 818 } 819 820 function visitGetAccessorDeclaration(node: GetAccessorDeclaration) { 821 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 822 enclosingFunctionFlags = FunctionFlags.Normal; 823 const updated = factory.updateGetAccessorDeclaration( 824 node, 825 /*decorators*/ undefined, 826 node.modifiers, 827 visitNode(node.name, visitor, isPropertyName), 828 visitParameterList(node.parameters, visitor, context), 829 /*type*/ undefined, 830 transformFunctionBody(node) 831 ); 832 enclosingFunctionFlags = savedEnclosingFunctionFlags; 833 return updated; 834 } 835 836 function visitSetAccessorDeclaration(node: SetAccessorDeclaration) { 837 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 838 enclosingFunctionFlags = FunctionFlags.Normal; 839 const updated = factory.updateSetAccessorDeclaration( 840 node, 841 /*decorators*/ undefined, 842 node.modifiers, 843 visitNode(node.name, visitor, isPropertyName), 844 visitParameterList(node.parameters, visitor, context), 845 transformFunctionBody(node) 846 ); 847 enclosingFunctionFlags = savedEnclosingFunctionFlags; 848 return updated; 849 } 850 851 function visitMethodDeclaration(node: MethodDeclaration) { 852 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 853 enclosingFunctionFlags = getFunctionFlags(node); 854 const updated = factory.updateMethodDeclaration( 855 node, 856 /*decorators*/ undefined, 857 enclosingFunctionFlags & FunctionFlags.Generator 858 ? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier) 859 : node.modifiers, 860 enclosingFunctionFlags & FunctionFlags.Async 861 ? undefined 862 : node.asteriskToken, 863 visitNode(node.name, visitor, isPropertyName), 864 visitNode<Token<SyntaxKind.QuestionToken>>(/*questionToken*/ undefined, visitor, isToken), 865 /*typeParameters*/ undefined, 866 visitParameterList(node.parameters, visitor, context), 867 /*type*/ undefined, 868 enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator 869 ? transformAsyncGeneratorFunctionBody(node) 870 : transformFunctionBody(node) 871 ); 872 enclosingFunctionFlags = savedEnclosingFunctionFlags; 873 return updated; 874 } 875 876 function visitFunctionDeclaration(node: FunctionDeclaration) { 877 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 878 enclosingFunctionFlags = getFunctionFlags(node); 879 const updated = factory.updateFunctionDeclaration( 880 node, 881 /*decorators*/ undefined, 882 enclosingFunctionFlags & FunctionFlags.Generator 883 ? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier) 884 : node.modifiers, 885 enclosingFunctionFlags & FunctionFlags.Async 886 ? undefined 887 : node.asteriskToken, 888 node.name, 889 /*typeParameters*/ undefined, 890 visitParameterList(node.parameters, visitor, context), 891 /*type*/ undefined, 892 enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator 893 ? transformAsyncGeneratorFunctionBody(node) 894 : transformFunctionBody(node) 895 ); 896 enclosingFunctionFlags = savedEnclosingFunctionFlags; 897 return updated; 898 } 899 900 function visitArrowFunction(node: ArrowFunction) { 901 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 902 enclosingFunctionFlags = getFunctionFlags(node); 903 const updated = factory.updateArrowFunction( 904 node, 905 node.modifiers, 906 /*typeParameters*/ undefined, 907 visitParameterList(node.parameters, visitor, context), 908 /*type*/ undefined, 909 node.equalsGreaterThanToken, 910 transformFunctionBody(node), 911 ); 912 enclosingFunctionFlags = savedEnclosingFunctionFlags; 913 return updated; 914 } 915 916 function visitFunctionExpression(node: FunctionExpression) { 917 const savedEnclosingFunctionFlags = enclosingFunctionFlags; 918 enclosingFunctionFlags = getFunctionFlags(node); 919 const updated = factory.updateFunctionExpression( 920 node, 921 enclosingFunctionFlags & FunctionFlags.Generator 922 ? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier) 923 : node.modifiers, 924 enclosingFunctionFlags & FunctionFlags.Async 925 ? undefined 926 : node.asteriskToken, 927 node.name, 928 /*typeParameters*/ undefined, 929 visitParameterList(node.parameters, visitor, context), 930 /*type*/ undefined, 931 enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator 932 ? transformAsyncGeneratorFunctionBody(node) 933 : transformFunctionBody(node) 934 ); 935 enclosingFunctionFlags = savedEnclosingFunctionFlags; 936 return updated; 937 } 938 939 function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { 940 resumeLexicalEnvironment(); 941 const statements: Statement[] = []; 942 const statementOffset = factory.copyPrologue(node.body!.statements, statements, /*ensureUseStrict*/ false, visitor); 943 appendObjectRestAssignmentsIfNeeded(statements, node); 944 945 const savedCapturedSuperProperties = capturedSuperProperties; 946 const savedHasSuperElementAccess = hasSuperElementAccess; 947 capturedSuperProperties = new Set(); 948 hasSuperElementAccess = false; 949 950 const returnStatement = factory.createReturnStatement( 951 emitHelpers().createAsyncGeneratorHelper( 952 factory.createFunctionExpression( 953 /*modifiers*/ undefined, 954 factory.createToken(SyntaxKind.AsteriskToken), 955 node.name && factory.getGeneratedNameForNode(node.name), 956 /*typeParameters*/ undefined, 957 /*parameters*/ [], 958 /*type*/ undefined, 959 factory.updateBlock( 960 node.body!, 961 visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset) 962 ) 963 ), 964 !!(hierarchyFacts & HierarchyFacts.HasLexicalThis) 965 ) 966 ); 967 968 // Minor optimization, emit `_super` helper to capture `super` access in an arrow. 969 // This step isn't needed if we eventually transform this to ES5. 970 const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuperBinding | NodeCheckFlags.AsyncMethodWithSuper); 971 972 if (emitSuperHelpers) { 973 enableSubstitutionForAsyncMethodsWithSuper(); 974 const variableStatement = createSuperAccessVariableStatement(factory, resolver, node, capturedSuperProperties); 975 substitutedSuperAccessors[getNodeId(variableStatement)] = true; 976 insertStatementsAfterStandardPrologue(statements, [variableStatement]); 977 } 978 979 statements.push(returnStatement); 980 981 insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); 982 const block = factory.updateBlock(node.body!, statements); 983 984 if (emitSuperHelpers && hasSuperElementAccess) { 985 if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { 986 addEmitHelper(block, advancedAsyncSuperHelper); 987 } 988 else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) { 989 addEmitHelper(block, asyncSuperHelper); 990 } 991 } 992 993 capturedSuperProperties = savedCapturedSuperProperties; 994 hasSuperElementAccess = savedHasSuperElementAccess; 995 996 return block; 997 } 998 999 function transformFunctionBody(node: FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | AccessorDeclaration): FunctionBody; 1000 function transformFunctionBody(node: ArrowFunction): ConciseBody; 1001 function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody { 1002 resumeLexicalEnvironment(); 1003 let statementOffset = 0; 1004 const statements: Statement[] = []; 1005 const body = visitNode(node.body, visitor, isConciseBody) ?? factory.createBlock([]); 1006 if (isBlock(body)) { 1007 statementOffset = factory.copyPrologue(body.statements, statements, /*ensureUseStrict*/ false, visitor); 1008 } 1009 addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node)); 1010 const leadingStatements = endLexicalEnvironment(); 1011 if (statementOffset > 0 || some(statements) || some(leadingStatements)) { 1012 const block = factory.converters.convertToFunctionBlock(body, /*multiLine*/ true); 1013 insertStatementsAfterStandardPrologue(statements, leadingStatements); 1014 addRange(statements, block.statements.slice(statementOffset)); 1015 return factory.updateBlock(block, setTextRange(factory.createNodeArray(statements), block.statements)); 1016 } 1017 return body; 1018 } 1019 1020 function appendObjectRestAssignmentsIfNeeded(statements: Statement[] | undefined, node: FunctionLikeDeclaration): Statement[] | undefined { 1021 for (const parameter of node.parameters) { 1022 if (parameter.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 1023 const temp = factory.getGeneratedNameForNode(parameter); 1024 const declarations = flattenDestructuringBinding( 1025 parameter, 1026 visitor, 1027 context, 1028 FlattenLevel.ObjectRest, 1029 temp, 1030 /*doNotRecordTempVariablesInLine*/ false, 1031 /*skipInitializer*/ true, 1032 ); 1033 if (some(declarations)) { 1034 const statement = factory.createVariableStatement( 1035 /*modifiers*/ undefined, 1036 factory.createVariableDeclarationList( 1037 declarations 1038 ) 1039 ); 1040 setEmitFlags(statement, EmitFlags.CustomPrologue); 1041 statements = append(statements, statement); 1042 } 1043 } 1044 } 1045 return statements; 1046 } 1047 1048 function enableSubstitutionForAsyncMethodsWithSuper() { 1049 if ((enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper) === 0) { 1050 enabledSubstitutions |= ESNextSubstitutionFlags.AsyncMethodsWithSuper; 1051 1052 // We need to enable substitutions for call, property access, and element access 1053 // if we need to rewrite super calls. 1054 context.enableSubstitution(SyntaxKind.CallExpression); 1055 context.enableSubstitution(SyntaxKind.PropertyAccessExpression); 1056 context.enableSubstitution(SyntaxKind.ElementAccessExpression); 1057 1058 // We need to be notified when entering and exiting declarations that bind super. 1059 context.enableEmitNotification(SyntaxKind.ClassDeclaration); 1060 context.enableEmitNotification(SyntaxKind.MethodDeclaration); 1061 context.enableEmitNotification(SyntaxKind.GetAccessor); 1062 context.enableEmitNotification(SyntaxKind.SetAccessor); 1063 context.enableEmitNotification(SyntaxKind.Constructor); 1064 // We need to be notified when entering the generated accessor arrow functions. 1065 context.enableEmitNotification(SyntaxKind.VariableStatement); 1066 } 1067 } 1068 1069 /** 1070 * Called by the printer just before a node is printed. 1071 * 1072 * @param hint A hint as to the intended usage of the node. 1073 * @param node The node to be printed. 1074 * @param emitCallback The callback used to emit the node. 1075 */ 1076 function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { 1077 // If we need to support substitutions for `super` in an async method, 1078 // we should track it here. 1079 if (enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) { 1080 const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding); 1081 if (superContainerFlags !== enclosingSuperContainerFlags) { 1082 const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; 1083 enclosingSuperContainerFlags = superContainerFlags; 1084 previousOnEmitNode(hint, node, emitCallback); 1085 enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; 1086 return; 1087 } 1088 } 1089 // Disable substitution in the generated super accessor itself. 1090 else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) { 1091 const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; 1092 enclosingSuperContainerFlags = 0 as NodeCheckFlags; 1093 previousOnEmitNode(hint, node, emitCallback); 1094 enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; 1095 return; 1096 } 1097 1098 previousOnEmitNode(hint, node, emitCallback); 1099 } 1100 1101 /** 1102 * Hooks node substitutions. 1103 * 1104 * @param hint The context for the emitter. 1105 * @param node The node to substitute. 1106 */ 1107 function onSubstituteNode(hint: EmitHint, node: Node) { 1108 node = previousOnSubstituteNode(hint, node); 1109 if (hint === EmitHint.Expression && enclosingSuperContainerFlags) { 1110 return substituteExpression(<Expression>node); 1111 } 1112 return node; 1113 } 1114 1115 function substituteExpression(node: Expression) { 1116 switch (node.kind) { 1117 case SyntaxKind.PropertyAccessExpression: 1118 return substitutePropertyAccessExpression(<PropertyAccessExpression>node); 1119 case SyntaxKind.ElementAccessExpression: 1120 return substituteElementAccessExpression(<ElementAccessExpression>node); 1121 case SyntaxKind.CallExpression: 1122 return substituteCallExpression(<CallExpression>node); 1123 } 1124 return node; 1125 } 1126 1127 function substitutePropertyAccessExpression(node: PropertyAccessExpression) { 1128 if (node.expression.kind === SyntaxKind.SuperKeyword) { 1129 return setTextRange( 1130 factory.createPropertyAccessExpression( 1131 factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), 1132 node.name), 1133 node 1134 ); 1135 } 1136 return node; 1137 } 1138 1139 function substituteElementAccessExpression(node: ElementAccessExpression) { 1140 if (node.expression.kind === SyntaxKind.SuperKeyword) { 1141 return createSuperElementAccessInAsyncMethod( 1142 node.argumentExpression, 1143 node 1144 ); 1145 } 1146 return node; 1147 } 1148 1149 function substituteCallExpression(node: CallExpression): Expression { 1150 const expression = node.expression; 1151 if (isSuperProperty(expression)) { 1152 const argumentExpression = isPropertyAccessExpression(expression) 1153 ? substitutePropertyAccessExpression(expression) 1154 : substituteElementAccessExpression(expression); 1155 return factory.createCallExpression( 1156 factory.createPropertyAccessExpression(argumentExpression, "call"), 1157 /*typeArguments*/ undefined, 1158 [ 1159 factory.createThis(), 1160 ...node.arguments 1161 ] 1162 ); 1163 } 1164 return node; 1165 } 1166 1167 function isSuperContainer(node: Node) { 1168 const kind = node.kind; 1169 return kind === SyntaxKind.ClassDeclaration 1170 || kind === SyntaxKind.Constructor 1171 || kind === SyntaxKind.MethodDeclaration 1172 || kind === SyntaxKind.GetAccessor 1173 || kind === SyntaxKind.SetAccessor; 1174 } 1175 1176 function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression { 1177 if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) { 1178 return setTextRange( 1179 factory.createPropertyAccessExpression( 1180 factory.createCallExpression( 1181 factory.createIdentifier("_superIndex"), 1182 /*typeArguments*/ undefined, 1183 [argumentExpression] 1184 ), 1185 "value" 1186 ), 1187 location 1188 ); 1189 } 1190 else { 1191 return setTextRange( 1192 factory.createCallExpression( 1193 factory.createIdentifier("_superIndex"), 1194 /*typeArguments*/ undefined, 1195 [argumentExpression] 1196 ), 1197 location 1198 ); 1199 } 1200 } 1201 } 1202} 1203