(node, symbol)
| 71817 | return ts.findAncestor(node, function (n) { return (!n || ts.nodeStartsNewLexicalEnvironment(n)) ? "quit" : ts.isIterationStatement(n, /*lookInLabeledStatements*/ false); }); |
| 71818 | } |
| 71819 | function checkNestedBlockScopedBinding(node, symbol) { |
| 71820 | if (languageVersion >= 2 /* ScriptTarget.ES2015 */ || |
| 71821 | (symbol.flags & (2 /* SymbolFlags.BlockScopedVariable */ | 32 /* SymbolFlags.Class */)) === 0 || |
| 71822 | !symbol.valueDeclaration || |
| 71823 | ts.isSourceFile(symbol.valueDeclaration) || |
| 71824 | symbol.valueDeclaration.parent.kind === 292 /* SyntaxKind.CatchClause */) { |
| 71825 | return; |
| 71826 | } |
| 71827 | // 1. walk from the use site up to the declaration and check |
| 71828 | // if there is anything function like between declaration and use-site (is binding/class is captured in function). |
| 71829 | // 2. walk from the declaration up to the boundary of lexical environment and check |
| 71830 | // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement) |
| 71831 | var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration); |
| 71832 | var isCaptured = isInsideFunctionOrInstancePropertyInitializer(node, container); |
| 71833 | var enclosingIterationStatement = getEnclosingIterationStatement(container); |
| 71834 | if (enclosingIterationStatement) { |
| 71835 | if (isCaptured) { |
| 71836 | // mark iteration statement as containing block-scoped binding captured in some function |
| 71837 | var capturesBlockScopeBindingInLoopBody = true; |
| 71838 | if (ts.isForStatement(container)) { |
| 71839 | var varDeclList = ts.getAncestor(symbol.valueDeclaration, 255 /* SyntaxKind.VariableDeclarationList */); |
| 71840 | if (varDeclList && varDeclList.parent === container) { |
| 71841 | var part = getPartOfForStatementContainingNode(node.parent, container); |
| 71842 | if (part) { |
| 71843 | var links = getNodeLinks(part); |
| 71844 | links.flags |= 131072 /* NodeCheckFlags.ContainsCapturedBlockScopeBinding */; |
| 71845 | var capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []); |
| 71846 | ts.pushIfUnique(capturedBindings, symbol); |
| 71847 | if (part === container.initializer) { |
| 71848 | capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body |
| 71849 | } |
| 71850 | } |
| 71851 | } |
| 71852 | } |
| 71853 | if (capturesBlockScopeBindingInLoopBody) { |
| 71854 | getNodeLinks(enclosingIterationStatement).flags |= 65536 /* NodeCheckFlags.LoopWithCapturedBlockScopedBinding */; |
| 71855 | } |
| 71856 | } |
| 71857 | // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement. |
| 71858 | // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back. |
| 71859 | if (ts.isForStatement(container)) { |
| 71860 | var varDeclList = ts.getAncestor(symbol.valueDeclaration, 255 /* SyntaxKind.VariableDeclarationList */); |
| 71861 | if (varDeclList && varDeclList.parent === container && isAssignedInBodyOfForStatement(node, container)) { |
| 71862 | getNodeLinks(symbol.valueDeclaration).flags |= 4194304 /* NodeCheckFlags.NeedsLoopOutParameter */; |
| 71863 | } |
| 71864 | } |
| 71865 | // set 'declared inside loop' bit on the block-scoped binding |
| 71866 | getNodeLinks(symbol.valueDeclaration).flags |= 524288 /* NodeCheckFlags.BlockScopedBindingInLoop */; |
| 71867 | } |
| 71868 | if (isCaptured) { |
| 71869 | getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* NodeCheckFlags.CapturedBlockScopedBinding */; |
| 71870 | } |
| 71871 | } |
| 71872 | function isBindingCapturedByNode(node, decl) { |
| 71873 | var links = getNodeLinks(node); |
| 71874 | return !!links && ts.contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl)); |
no test coverage detected
searching dependent graphs…