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

Method bindTryStatement

internal/binder/binder.go:1993–2072  ·  view source on GitHub ↗
(node *ast.Node)

Source from the content-addressed store, hash-verified

1991}
1992
1993func (b *Binder) bindTryStatement(node *ast.Node) {
1994 // We conservatively assume that *any* code in the try block can cause an exception, but we only need
1995 // to track code that causes mutations (because only mutations widen the possible control flow type of
1996 // a variable). The exceptionLabel is the target label for control flows that result from exceptions.
1997 // We add all mutation flow nodes as antecedents of this label such that we can analyze them as possible
1998 // antecedents of the start of catch or finally blocks. Furthermore, we add the current control flow to
1999 // represent exceptions that occur before any mutations.
2000 stmt := node.AsTryStatement()
2001 saveReturnTarget := b.currentReturnTarget
2002 saveExceptionTarget := b.currentExceptionTarget
2003 normalExitLabel := b.createBranchLabel()
2004 returnLabel := b.createBranchLabel()
2005 exceptionLabel := b.createBranchLabel()
2006 if stmt.FinallyBlock != nil {
2007 b.currentReturnTarget = returnLabel
2008 }
2009 b.addAntecedent(exceptionLabel, b.currentFlow)
2010 b.currentExceptionTarget = exceptionLabel
2011 b.bind(stmt.TryBlock)
2012 b.addAntecedent(normalExitLabel, b.currentFlow)
2013 if stmt.CatchClause != nil {
2014 // Start of catch clause is the target of exceptions from try block.
2015 b.currentFlow = b.finishFlowLabel(exceptionLabel)
2016 // The currentExceptionTarget now represents control flows from exceptions in the catch clause.
2017 // Effectively, in a try-catch-finally, if an exception occurs in the try block, the catch block
2018 // acts like a second try block.
2019 exceptionLabel = b.createBranchLabel()
2020 b.addAntecedent(exceptionLabel, b.currentFlow)
2021 b.currentExceptionTarget = exceptionLabel
2022 b.bind(stmt.CatchClause)
2023 b.addAntecedent(normalExitLabel, b.currentFlow)
2024 }
2025 b.currentReturnTarget = saveReturnTarget
2026 b.currentExceptionTarget = saveExceptionTarget
2027 if stmt.FinallyBlock != nil {
2028 // Possible ways control can reach the finally block:
2029 // 1) Normal completion of try block of a try-finally or try-catch-finally
2030 // 2) Normal completion of catch block (following exception in try block) of a try-catch-finally
2031 // 3) Return in try or catch block of a try-finally or try-catch-finally
2032 // 4) Exception in try block of a try-finally
2033 // 5) Exception in catch block of a try-catch-finally
2034 // When analyzing a control flow graph that starts inside a finally block we want to consider all
2035 // five possibilities above. However, when analyzing a control flow graph that starts outside (past)
2036 // the finally block, we only want to consider the first two (if we're past a finally block then it
2037 // must have completed normally). Likewise, when analyzing a control flow graph from return statements
2038 // in try or catch blocks in an IIFE, we only want to consider the third. To make this possible, we
2039 // inject a ReduceLabel node into the control flow graph. This node contains an alternate reduced
2040 // set of antecedents for the pre-finally label. As control flow analysis passes by a ReduceLabel
2041 // node, the pre-finally label is temporarily switched to the reduced antecedent set.
2042 finallyLabel := b.createBranchLabel()
2043 finallyLabel.Antecedents = b.combineFlowLists(normalExitLabel.Antecedents, b.combineFlowLists(exceptionLabel.Antecedents, returnLabel.Antecedents))
2044 b.currentFlow = finallyLabel
2045 b.bind(stmt.FinallyBlock)
2046 if b.currentFlow.Flags&ast.FlowFlagsUnreachable != 0 {
2047 // If the end of the finally block is unreachable, the end of the entire try statement is unreachable.
2048 b.currentFlow = b.unreachableFlow
2049 } else {
2050 // If we have an IIFE return target and return statements in the try or catch blocks, add a control

Callers 1

bindChildrenMethod · 0.95

Calls 7

createBranchLabelMethod · 0.95
addAntecedentMethod · 0.95
bindMethod · 0.95
finishFlowLabelMethod · 0.95
combineFlowListsMethod · 0.95
createReduceLabelMethod · 0.95
AsTryStatementMethod · 0.80

Tested by

no test coverage detected