MCPcopy Create free account
hub / github.com/microsoft/typescript-go / bindContainer

Method bindContainer

internal/binder/binder.go:1477–1625  ·  view source on GitHub ↗

All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function in the type checker to validate that the local name used for a container is unique.

(node *ast.Node, containerFlags ContainerFlags)

Source from the content-addressed store, hash-verified

1475// the getLocalNameOfContainer function in the type checker to validate that the local name
1476// used for a container is unique.
1477func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
1478 // Before we recurse into a node's children, we first save the existing parent, container
1479 // and block-container. Then after we pop out of processing the children, we restore
1480 // these saved values.
1481 saveContainer := b.container
1482 saveThisContainer := b.thisContainer
1483 savedBlockScopeContainer := b.blockScopeContainer
1484 // Depending on what kind of node this is, we may have to adjust the current container
1485 // and block-container. If the current node is a container, then it is automatically
1486 // considered the current block-container as well. Also, for containers that we know
1487 // may contain locals, we eagerly initialize the .locals field. We do this because
1488 // it's highly likely that the .locals will be needed to place some child in (for example,
1489 // a parameter, or variable declaration).
1490 //
1491 // However, we do not proactively create the .locals for block-containers because it's
1492 // totally normal and common for block-containers to never actually have a block-scoped
1493 // variable in them. We don't want to end up allocating an object for every 'block' we
1494 // run into when most of them won't be necessary.
1495 //
1496 // Finally, if this is a block-container, then we clear out any existing .locals object
1497 // it may contain within it. This happens in incremental scenarios. Because we can be
1498 // reusing a node from a previous compilation, that node may have had 'locals' created
1499 // for it. We must clear this so we don't accidentally move any stale data forward from
1500 // a previous compilation.
1501 if containerFlags&ContainerFlagsIsContainer != 0 {
1502 b.container = node
1503 b.blockScopeContainer = node
1504 if containerFlags&ContainerFlagsHasLocals != 0 {
1505 // localsContainer := node
1506 // localsContainer.LocalsContainerData().locals = make(SymbolTable)
1507 b.addToContainerChain(node)
1508 }
1509 } else if containerFlags&ContainerFlagsIsBlockScopedContainer != 0 {
1510 b.blockScopeContainer = node
1511 b.addToContainerChain(node)
1512 }
1513 if containerFlags&ContainerFlagsIsThisContainer != 0 {
1514 b.thisContainer = node
1515 }
1516 if containerFlags&ContainerFlagsIsControlFlowContainer != 0 {
1517 saveCurrentFlow := b.currentFlow
1518 saveBreakTarget := b.currentBreakTarget
1519 saveContinueTarget := b.currentContinueTarget
1520 saveReturnTarget := b.currentReturnTarget
1521 saveExceptionTarget := b.currentExceptionTarget
1522 saveActiveLabelList := b.activeLabelList
1523 saveHasExplicitReturn := b.hasExplicitReturn
1524 saveSeenThisKeyword := b.seenThisKeyword
1525 isImmediatelyInvoked := (containerFlags&ContainerFlagsIsFunctionExpression != 0 &&
1526 !ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) &&
1527 !isGeneratorFunctionExpression(node) &&
1528 ast.GetImmediatelyInvokedFunctionExpression(node) != nil) || node.Kind == ast.KindClassStaticBlockDeclaration
1529 // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
1530 // similarly to break statements that exit to a label just past the statement body.
1531 if !isImmediatelyInvoked {
1532 flowStart := b.newFlowNode(ast.FlowFlagsStart)
1533 b.currentFlow = flowStart
1534 if containerFlags&(ContainerFlagsIsFunctionExpression|ContainerFlagsIsObjectLiteralOrClassExpressionMethodOrAccessor) != 0 {

Callers 1

bindMethod · 0.95

Calls 15

addToContainerChainMethod · 0.95
newFlowNodeMethod · 0.95
bindChildrenMethod · 0.95
addAntecedentMethod · 0.95
finishFlowLabelMethod · 0.95
HasSyntacticModifierFunction · 0.92
NodeIsPresentFunction · 0.92
IsSourceFileFunction · 0.92

Tested by

no test coverage detected