@@ -1714,36 +1714,52 @@ private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl
17141714 * This is also known as the environment part of a closure.
17151715 *
17161716 * This is used for tracking flow through captured variables.
1717- *
1718- * TODO:
1719- * We might want a synthetic node here, but currently that incurs problems
1720- * with non-monotonic recursion, because of the use of `resolveCall` in the
1721- * char pred. This may be solvable by using
1722- * `CallGraphConstruction::Make` in stead of
1723- * `CallGraphConstruction::Simple::Make` appropriately.
17241717 */
1725- class CapturedVariablesArgumentNode extends CfgNode {
1718+ class CapturedVariablesArgumentNode extends Node , TSynthCapturedVariablesArgumentNode {
17261719 CallNode callNode ;
17271720
17281721 CapturedVariablesArgumentNode ( ) {
1729- node = callNode .getFunction ( ) and
1730- exists ( Function target | resolveCall ( callNode , target , _) |
1731- target = any ( VariableCapture:: CapturedVariable v ) .getACapturingScope ( )
1722+ exists ( ControlFlowNode callable |
1723+ this = TSynthCapturedVariablesArgumentNode ( callable ) and callable = callNode .getFunction ( )
17321724 )
17331725 }
17341726
1727+ /** Gets the call node associated with this captured variables argument. */
1728+ CallNode getCallNode ( ) { result = callNode }
1729+
1730+ override Location getLocation ( ) { result = callNode .getLocation ( ) }
1731+
17351732 override string toString ( ) { result = "Capturing closure argument" }
17361733}
17371734
1738- class CapturedVariablesArgumentNodeAsArgumentNode extends CapturedVariablesArgumentNode ,
1739- ArgumentNode
1735+ /** A captured variables argument node viewed as an argument node. Needed because `argumentOf` is a global predicate. */
1736+ class CapturedVariablesArgumentNodeAsArgumentNode extends ArgumentNode instanceof CapturedVariablesArgumentNode
17401737{
17411738 override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
1742- callNode = call .getNode ( ) and
1739+ this . ( CapturedVariablesArgumentNode ) . getCallNode ( ) = call .getNode ( ) and
17431740 pos .isLambdaSelf ( )
17441741 }
17451742}
17461743
1744+ /** A synthetic node representing the values of variables captured by a comprehension after the output has been computed. */
1745+ class SynthCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl ,
1746+ TSynthCapturedVariablesArgumentPostUpdateNode
1747+ {
1748+ ControlFlowNode callable ;
1749+
1750+ SynthCapturedVariablesArgumentPostUpdateNode ( ) {
1751+ this = TSynthCapturedVariablesArgumentPostUpdateNode ( callable )
1752+ }
1753+
1754+ override string toString ( ) { result = "[post] Capturing closure argument" }
1755+
1756+ override Scope getScope ( ) { result = callable .getScope ( ) }
1757+
1758+ override Location getLocation ( ) { result = callable .getLocation ( ) }
1759+
1760+ override Node getPreUpdateNode ( ) { result = TSynthCapturedVariablesArgumentNode ( callable ) }
1761+ }
1762+
17471763/** A synthetic node representing the values of variables captured by a comprehension. */
17481764class SynthCompCapturedVariablesArgumentNode extends Node , TSynthCompCapturedVariablesArgumentNode {
17491765 Comp comp ;
0 commit comments