@@ -116,19 +116,23 @@ private module Cached {
116116 cached
117117 DataFlowCallable viableCallable ( DataFlowCall call ) { result = call .getARuntimeTarget ( ) }
118118
119- private int parameterPosition ( ) {
120- result =
121- [
122- - 1 , any ( Parameter p ) .getPosition ( ) ,
123- ImplicitCapturedParameterNodeImpl:: getParameterPosition ( _)
124- ]
119+ private predicate capturedWithFlowIn ( LocalScopeVariable v ) {
120+ exists ( Ssa:: ExplicitDefinition def | def .isCapturedVariableDefinitionFlowIn ( _, _, _) |
121+ v = def .getSourceVariable ( ) .getAssignable ( )
122+ )
125123 }
126124
127125 cached
128- newtype TParameterPosition = MkParameterPosition ( int i ) { i = parameterPosition ( ) }
126+ newtype TParameterPosition =
127+ TPositionalParameterPosition ( int i ) { i = any ( Parameter p ) .getPosition ( ) } or
128+ TThisParameterPosition ( ) or
129+ TImplicitCapturedParameterPosition ( LocalScopeVariable v ) { capturedWithFlowIn ( v ) }
129130
130131 cached
131- newtype TArgumentPosition = MkArgumentPosition ( int i ) { i = parameterPosition ( ) }
132+ newtype TArgumentPosition =
133+ TPositionalArgumentPosition ( int i ) { i = any ( Parameter p ) .getPosition ( ) } or
134+ TQualifierArgumentPosition ( ) or
135+ TImplicitCapturedArgumentPosition ( LocalScopeVariable v ) { capturedWithFlowIn ( v ) }
132136}
133137
134138import Cached
@@ -268,8 +272,8 @@ abstract class DataFlowCall extends TDataFlowCall {
268272 /** Gets the underlying expression, if any. */
269273 final DotNet:: Expr getExpr ( ) { result = this .getNode ( ) .asExpr ( ) }
270274
271- /** Gets the `i`th argument of this call. */
272- final ArgumentNode getArgument ( int i ) { result .argumentOf ( this , i ) }
275+ /** Gets the argument at position `pos` of this call. */
276+ final ArgumentNode getArgument ( ArgumentPosition pos ) { result .argumentOf ( this , pos ) }
273277
274278 /** Gets a textual representation of this call. */
275279 abstract string toString ( ) ;
@@ -425,36 +429,64 @@ class SummaryCall extends DelegateDataFlowCall, TSummaryCall {
425429 override Location getLocation ( ) { result = c .getLocation ( ) }
426430}
427431
428- /** A parameter position represented by an integer. */
429- class ParameterPosition extends MkParameterPosition {
430- private int i ;
432+ /** A parameter position. */
433+ class ParameterPosition extends TParameterPosition {
434+ /** Gets the underlying integer position, if any. */
435+ int getPosition ( ) { this = TPositionalParameterPosition ( result ) }
431436
432- ParameterPosition ( ) { this = MkParameterPosition ( i ) }
437+ /** Holds if this position represents a `this` parameter. */
438+ predicate isThisParameter ( ) { this = TThisParameterPosition ( ) }
433439
434- /** Gets the underlying integer. */
435- int getPosition ( ) { result = i }
440+ /** Holds if this position is used to model flow through captured variables. */
441+ predicate isImplicitCapturedParameterPosition ( LocalScopeVariable v ) {
442+ this = TImplicitCapturedParameterPosition ( v )
443+ }
436444
437445 /** Gets a textual representation of this position. */
438- string toString ( ) { result = i .toString ( ) }
446+ string toString ( ) {
447+ result = "position " + this .getPosition ( )
448+ or
449+ this .isThisParameter ( ) and result = "this"
450+ or
451+ exists ( LocalScopeVariable v |
452+ this .isImplicitCapturedParameterPosition ( v ) and result = "captured " + v
453+ )
454+ }
439455}
440456
441- /** An argument position represented by an integer. */
442- class ArgumentPosition extends MkArgumentPosition {
443- private int i ;
457+ /** An argument position. */
458+ class ArgumentPosition extends TArgumentPosition {
459+ /** Gets the underlying integer position, if any. */
460+ int getPosition ( ) { this = TPositionalArgumentPosition ( result ) }
444461
445- ArgumentPosition ( ) { this = MkArgumentPosition ( i ) }
462+ /** Holds if this position represents a qualifier. */
463+ predicate isQualifier ( ) { this = TQualifierArgumentPosition ( ) }
446464
447- /** Gets the underlying integer. */
448- int getPosition ( ) { result = i }
465+ /** Holds if this position is used to model flow through captured variables. */
466+ predicate isImplicitCapturedArgumentPosition ( LocalScopeVariable v ) {
467+ this = TImplicitCapturedArgumentPosition ( v )
468+ }
449469
450470 /** Gets a textual representation of this position. */
451- string toString ( ) { result = i .toString ( ) }
471+ string toString ( ) {
472+ result = "position " + this .getPosition ( )
473+ or
474+ this .isQualifier ( ) and result = "qualifier"
475+ or
476+ exists ( LocalScopeVariable v |
477+ this .isImplicitCapturedArgumentPosition ( v ) and result = "captured " + v
478+ )
479+ }
452480}
453481
454482/** Holds if arguments at position `apos` match parameters at position `ppos`. */
455483predicate parameterMatch ( ParameterPosition ppos , ArgumentPosition apos ) {
456- exists ( int i |
457- ppos = MkParameterPosition ( i ) and
458- apos = MkArgumentPosition ( i )
484+ ppos .getPosition ( ) = apos .getPosition ( )
485+ or
486+ ppos .isThisParameter ( ) and apos .isQualifier ( )
487+ or
488+ exists ( LocalScopeVariable v |
489+ ppos .isImplicitCapturedParameterPosition ( v ) and
490+ apos .isImplicitCapturedArgumentPosition ( v )
459491 )
460492}
0 commit comments