@@ -152,17 +152,29 @@ module LocalFlow {
152152/** An argument of a call (including qualifier arguments, excluding block arguments). */
153153private class Argument extends CfgNodes:: ExprCfgNode {
154154 private CfgNodes:: ExprNodes:: CallCfgNode call ;
155- private int arg ;
155+ private ArgumentPosition arg ;
156156
157157 Argument ( ) {
158- this = call .getArgument ( arg ) and
159- not this .getExpr ( ) instanceof BlockArgument
158+ exists ( int i |
159+ this = call .getArgument ( i ) and
160+ not this .getExpr ( ) instanceof BlockArgument and
161+ not exists ( this .getExpr ( ) .( Pair ) .getKey ( ) .getValueText ( ) ) and
162+ arg .isPositional ( i )
163+ )
164+ or
165+ exists ( CfgNodes:: ExprNodes:: PairCfgNode p |
166+ p = call .getArgument ( _) and
167+ this = p .getValue ( ) and
168+ arg .isKeyword ( p .getKey ( ) .getValueText ( ) )
169+ )
160170 or
161- this = call .getReceiver ( ) and arg = - 1
171+ this = call .getReceiver ( ) and arg . isSelf ( )
162172 }
163173
164174 /** Holds if this expression is the `i`th argument of `c`. */
165- predicate isArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode c , int i ) { c = call and i = arg }
175+ predicate isArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode c , ArgumentPosition pos ) {
176+ c = call and pos = arg
177+ }
166178}
167179
168180/** A collection of cached types and predicates to be evaluated in the same stage. */
@@ -179,7 +191,11 @@ private module Cached {
179191 )
180192 } or
181193 TSsaDefinitionNode ( Ssa:: Definition def ) or
182- TNormalParameterNode ( Parameter p ) { not p instanceof BlockParameter } or
194+ TNormalParameterNode ( Parameter p ) {
195+ p instanceof SimpleParameter or
196+ p instanceof OptionalParameter or
197+ p instanceof KeywordParameter
198+ } or
183199 TSelfParameterNode ( MethodBase m ) or
184200 TBlockParameterNode ( MethodBase m ) or
185201 TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) { n instanceof Argument } or
@@ -189,8 +205,8 @@ private module Cached {
189205 ) {
190206 FlowSummaryImpl:: Private:: summaryNodeRange ( c , state )
191207 } or
192- TSummaryParameterNode ( FlowSummaryImpl:: Public:: SummarizedCallable c , int i ) {
193- FlowSummaryImpl:: Private:: summaryParameterNodeRange ( c , i )
208+ TSummaryParameterNode ( FlowSummaryImpl:: Public:: SummarizedCallable c , ParameterPosition pos ) {
209+ FlowSummaryImpl:: Private:: summaryParameterNodeRange ( c , pos )
194210 }
195211
196212 class TParameterNode =
@@ -331,10 +347,10 @@ private module ParameterNodes {
331347 abstract class ParameterNodeImpl extends NodeImpl {
332348 abstract Parameter getParameter ( ) ;
333349
334- abstract predicate isSourceParameterOf ( Callable c , int i ) ;
350+ abstract predicate isSourceParameterOf ( Callable c , ParameterPosition pos ) ;
335351
336- predicate isParameterOf ( DataFlowCallable c , int i ) {
337- this .isSourceParameterOf ( c .asCallable ( ) , i )
352+ predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
353+ this .isSourceParameterOf ( c .asCallable ( ) , pos )
338354 }
339355 }
340356
@@ -349,10 +365,22 @@ private module ParameterNodes {
349365
350366 override Parameter getParameter ( ) { result = parameter }
351367
352- override predicate isSourceParameterOf ( Callable c , int i ) { c .getParameter ( i ) = parameter }
368+ override predicate isSourceParameterOf ( Callable c , ParameterPosition pos ) {
369+ exists ( int i | pos .isPositional ( i ) and c .getParameter ( i ) = parameter |
370+ parameter instanceof SimpleParameter
371+ or
372+ parameter instanceof OptionalParameter
373+ )
374+ or
375+ parameter =
376+ any ( KeywordParameter kp |
377+ c .getAParameter ( ) = kp and
378+ pos .isKeyword ( kp .getName ( ) )
379+ )
380+ }
353381
354- override predicate isParameterOf ( DataFlowCallable c , int i ) {
355- this .isSourceParameterOf ( c .asCallable ( ) , i )
382+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
383+ this .isSourceParameterOf ( c .asCallable ( ) , pos )
356384 }
357385
358386 override CfgScope getCfgScope ( ) { result = parameter .getCallable ( ) }
@@ -375,10 +403,12 @@ private module ParameterNodes {
375403
376404 override Parameter getParameter ( ) { none ( ) }
377405
378- override predicate isSourceParameterOf ( Callable c , int i ) { method = c and i = - 1 }
406+ override predicate isSourceParameterOf ( Callable c , ParameterPosition pos ) {
407+ method = c and pos .isSelf ( )
408+ }
379409
380- override predicate isParameterOf ( DataFlowCallable c , int i ) {
381- this .isSourceParameterOf ( c .asCallable ( ) , i )
410+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
411+ this .isSourceParameterOf ( c .asCallable ( ) , pos )
382412 }
383413
384414 override CfgScope getCfgScope ( ) { result = method }
@@ -403,10 +433,12 @@ private module ParameterNodes {
403433 result = method .getAParameter ( ) and result instanceof BlockParameter
404434 }
405435
406- override predicate isSourceParameterOf ( Callable c , int i ) { c = method and i = - 2 }
436+ override predicate isSourceParameterOf ( Callable c , ParameterPosition pos ) {
437+ c = method and pos .isBlock ( )
438+ }
407439
408- override predicate isParameterOf ( DataFlowCallable c , int i ) {
409- this .isSourceParameterOf ( c .asCallable ( ) , i )
440+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
441+ this .isSourceParameterOf ( c .asCallable ( ) , pos )
410442 }
411443
412444 override CfgScope getCfgScope ( ) { result = method }
@@ -427,23 +459,25 @@ private module ParameterNodes {
427459 /** A parameter for a library callable with a flow summary. */
428460 class SummaryParameterNode extends ParameterNodeImpl , TSummaryParameterNode {
429461 private FlowSummaryImpl:: Public:: SummarizedCallable sc ;
430- private int pos ;
462+ private ParameterPosition pos_ ;
431463
432- SummaryParameterNode ( ) { this = TSummaryParameterNode ( sc , pos ) }
464+ SummaryParameterNode ( ) { this = TSummaryParameterNode ( sc , pos_ ) }
433465
434466 override Parameter getParameter ( ) { none ( ) }
435467
436- override predicate isSourceParameterOf ( Callable c , int i ) { none ( ) }
468+ override predicate isSourceParameterOf ( Callable c , ParameterPosition pos ) { none ( ) }
437469
438- override predicate isParameterOf ( DataFlowCallable c , int i ) { sc = c and i = pos }
470+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
471+ sc = c and pos = pos_
472+ }
439473
440474 override CfgScope getCfgScope ( ) { none ( ) }
441475
442476 override DataFlowCallable getEnclosingCallable ( ) { result = sc }
443477
444478 override EmptyLocation getLocationImpl ( ) { any ( ) }
445479
446- override string toStringImpl ( ) { result = "parameter " + pos + " of " + sc }
480+ override string toStringImpl ( ) { result = "parameter " + pos_ + " of " + sc }
447481 }
448482}
449483
@@ -468,9 +502,9 @@ class SummaryNode extends NodeImpl, TSummaryNode {
468502/** A data-flow node that represents a call argument. */
469503abstract class ArgumentNode extends Node {
470504 /** Holds if this argument occurs at the given position in the given call. */
471- abstract predicate argumentOf ( DataFlowCall call , int pos ) ;
505+ abstract predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) ;
472506
473- abstract predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) ;
507+ abstract predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) ;
474508
475509 /** Gets the call in which this node is an argument. */
476510 final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
@@ -483,18 +517,18 @@ private module ArgumentNodes {
483517
484518 ExplicitArgumentNode ( ) { this .asExpr ( ) = arg }
485519
486- override predicate argumentOf ( DataFlowCall call , int pos ) {
520+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
487521 this .sourceArgumentOf ( call .asCall ( ) , pos )
488522 }
489523
490- override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) {
524+ override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) {
491525 arg .isArgumentOf ( call , pos )
492526 }
493527 }
494528
495529 /** A data-flow node that represents the `self` argument of a call. */
496530 class SelfArgumentNode extends ExplicitArgumentNode {
497- SelfArgumentNode ( ) { arg .isArgumentOf ( _, - 1 ) }
531+ SelfArgumentNode ( ) { arg .isArgumentOf ( _, any ( ArgumentPosition pos | pos . isSelf ( ) ) ) }
498532 }
499533
500534 /** A data-flow node that represents a block argument. */
@@ -504,12 +538,12 @@ private module ArgumentNodes {
504538 exists ( CfgNodes:: ExprNodes:: CallCfgNode c | c .getBlock ( ) = this .asExpr ( ) )
505539 }
506540
507- override predicate argumentOf ( DataFlowCall call , int pos ) {
541+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
508542 this .sourceArgumentOf ( call .asCall ( ) , pos )
509543 }
510544
511- override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) {
512- pos = - 2 and
545+ override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) {
546+ pos . isBlock ( ) and
513547 (
514548 this .asExpr ( ) = call .getBlock ( )
515549 or
@@ -525,9 +559,11 @@ private module ArgumentNodes {
525559 private class SummaryArgumentNode extends SummaryNode , ArgumentNode {
526560 SummaryArgumentNode ( ) { FlowSummaryImpl:: Private:: summaryArgumentNode ( _, this , _) }
527561
528- override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) { none ( ) }
562+ override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) {
563+ none ( )
564+ }
529565
530- override predicate argumentOf ( DataFlowCall call , int pos ) {
566+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
531567 FlowSummaryImpl:: Private:: summaryArgumentNode ( call , this , pos )
532568 }
533569 }
@@ -838,7 +874,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
838874 )
839875 or
840876 receiver = call .( SummaryCall ) .getReceiver ( ) and
841- if receiver .( ParameterNodeImpl ) .isParameterOf ( _, - 2 )
877+ if receiver .( ParameterNodeImpl ) .isParameterOf ( _, any ( ParameterPosition pos | pos . isBlock ( ) ) )
842878 then kind = TYieldCallKind ( )
843879 else kind = TLambdaCallKind ( )
844880}
0 commit comments