(node, containerFlags)
| 45089 | // the getLocalNameOfContainer function in the type checker to validate that the local name |
| 45090 | // used for a container is unique. |
| 45091 | function bindContainer(node, containerFlags) { |
| 45092 | // Before we recurse into a node's children, we first save the existing parent, container |
| 45093 | // and block-container. Then after we pop out of processing the children, we restore |
| 45094 | // these saved values. |
| 45095 | var saveContainer = container; |
| 45096 | var saveThisParentContainer = thisParentContainer; |
| 45097 | var savedBlockScopeContainer = blockScopeContainer; |
| 45098 | // Depending on what kind of node this is, we may have to adjust the current container |
| 45099 | // and block-container. If the current node is a container, then it is automatically |
| 45100 | // considered the current block-container as well. Also, for containers that we know |
| 45101 | // may contain locals, we eagerly initialize the .locals field. We do this because |
| 45102 | // it's highly likely that the .locals will be needed to place some child in (for example, |
| 45103 | // a parameter, or variable declaration). |
| 45104 | // |
| 45105 | // However, we do not proactively create the .locals for block-containers because it's |
| 45106 | // totally normal and common for block-containers to never actually have a block-scoped |
| 45107 | // variable in them. We don't want to end up allocating an object for every 'block' we |
| 45108 | // run into when most of them won't be necessary. |
| 45109 | // |
| 45110 | // Finally, if this is a block-container, then we clear out any existing .locals object |
| 45111 | // it may contain within it. This happens in incremental scenarios. Because we can be |
| 45112 | // reusing a node from a previous compilation, that node may have had 'locals' created |
| 45113 | // for it. We must clear this so we don't accidentally move any stale data forward from |
| 45114 | // a previous compilation. |
| 45115 | if (containerFlags & 1 /* ContainerFlags.IsContainer */) { |
| 45116 | if (node.kind !== 214 /* SyntaxKind.ArrowFunction */) { |
| 45117 | thisParentContainer = container; |
| 45118 | } |
| 45119 | container = blockScopeContainer = node; |
| 45120 | if (containerFlags & 32 /* ContainerFlags.HasLocals */) { |
| 45121 | container.locals = ts.createSymbolTable(); |
| 45122 | } |
| 45123 | addToContainerChain(container); |
| 45124 | } |
| 45125 | else if (containerFlags & 2 /* ContainerFlags.IsBlockScopedContainer */) { |
| 45126 | blockScopeContainer = node; |
| 45127 | blockScopeContainer.locals = undefined; |
| 45128 | } |
| 45129 | if (containerFlags & 4 /* ContainerFlags.IsControlFlowContainer */) { |
| 45130 | var saveCurrentFlow = currentFlow; |
| 45131 | var saveBreakTarget = currentBreakTarget; |
| 45132 | var saveContinueTarget = currentContinueTarget; |
| 45133 | var saveReturnTarget = currentReturnTarget; |
| 45134 | var saveExceptionTarget = currentExceptionTarget; |
| 45135 | var saveActiveLabelList = activeLabelList; |
| 45136 | var saveHasExplicitReturn = hasExplicitReturn; |
| 45137 | var isImmediatelyInvoked = (containerFlags & 16 /* ContainerFlags.IsFunctionExpression */ && |
| 45138 | !ts.hasSyntacticModifier(node, 256 /* ModifierFlags.Async */) && |
| 45139 | !node.asteriskToken && |
| 45140 | !!ts.getImmediatelyInvokedFunctionExpression(node)) || |
| 45141 | node.kind === 170 /* SyntaxKind.ClassStaticBlockDeclaration */; |
| 45142 | // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave |
| 45143 | // similarly to break statements that exit to a label just past the statement body. |
| 45144 | if (!isImmediatelyInvoked) { |
| 45145 | currentFlow = initFlowNode({ flags: 2 /* FlowFlags.Start */ }); |
| 45146 | if (containerFlags & (16 /* ContainerFlags.IsFunctionExpression */ | 128 /* ContainerFlags.IsObjectLiteralOrClassExpressionMethodOrAccessor */)) { |
| 45147 | currentFlow.node = node; |
| 45148 | } |
no test coverage detected