@@ -315,7 +315,10 @@ private Node update(Node node) {
315315 */
316316module ArgumentPassing {
317317 /**
318- * Holds if `call` is a call to `callable`.
318+ * Holds if `call` represents a `DataFlowCall` to a `DataFlowCallable` represented by `callable`.
319+ *
320+ * It _may not_ be the case that `call = callable.getACall()`, i.e. if `call` represents a `ClassCall`.
321+ *
319322 * Used to limit the size of predicates.
320323 */
321324 predicate connects ( CallNode call , CallableValue callable ) {
@@ -352,38 +355,45 @@ module ArgumentPassing {
352355 }
353356
354357 /**
355- * Gets the argument to `call` that is passed to the parameter at position `paramNr` in `callable`.
356- * If it is a positional argument, it must appear at position `argNr` in `call`.
357- * `argNr` will differ from `paramNr` for method- or constructor calls, where the first parameter
358+ * Gets the node representing the argument to `call` that is passed to the parameter at
359+ * (zero-based) index `paramN` in `callable`. If this is a positional argument, it must appear
360+ * at index `argN` in `call`.
361+ *
362+ * `argN` will differ from `paramN` for method- or constructor calls, where the first parameter
358363 * is `self` and the first positional argument is passed to the second positional parameter.
364+ * Similarly for classmethod calls, where the first parameter is `cls`.
365+ *
366+ * NOT SUPPORTED: Keyword-only parameters.
359367 */
360- Node getArg ( CallNode call , int argNr , CallableValue callable , int paramNr ) {
368+ Node getArg ( CallNode call , int argN , CallableValue callable , int paramN ) {
361369 connects ( call , callable ) and
362- paramNr - argNr in [ 0 , 1 ] and // constrain for now to limit the size of the predicate; we only use it to insert one argument (self).
370+ paramN - argN in [ 0 , 1 ] and // constrain for now to limit the size of the predicate; we only use it to insert one argument (self).
363371 (
364372 // positional argument
365- result = TCfgNode ( call .getArg ( argNr ) )
373+ result = TCfgNode ( call .getArg ( argN ) )
366374 or
367375 // keyword argument
376+ // TODO: Since `getArgName` have no results for keyword-only parameters,
377+ // these are currently not supported.
368378 exists ( Function f , string argName |
369379 f = callable .getScope ( ) and
370- f .getArgName ( paramNr ) = argName and
380+ f .getArgName ( paramN ) = argName and
371381 result = TCfgNode ( call .getArgByName ( argName ) )
372382 )
373383 or
374384 // a synthezised argument passed to the starred parameter (at position -1)
375385 callable .getScope ( ) .hasVarArg ( ) and
376- paramNr = - 1 and
386+ paramN = - 1 and
377387 result = TPosOverflowNode ( call , callable )
378388 or
379389 // a synthezised argument passed to the doubly starred parameter (at position -2)
380390 callable .getScope ( ) .hasKwArg ( ) and
381- paramNr = - 2 and
391+ paramN = - 2 and
382392 result = TKwOverflowNode ( call , callable )
383393 or
384394 // argument unpacked from dict
385395 exists ( string name |
386- call_unpacks ( call , argNr , callable , name , paramNr ) and
396+ call_unpacks ( call , argN , callable , name , paramN ) and
387397 result = TKwUnpacked ( call , callable , name )
388398 )
389399 )
@@ -425,6 +435,7 @@ module ArgumentPassing {
425435 not exists ( call .getArg ( argNr ) ) and // no positional arguement available
426436 name = f .getArgName ( n ) and
427437 // not exists(call.getArgByName(name)) and // only matches keyword arguments not preceded by **
438+ // TODO: make the below logic respect control flow splitting (by not going to the AST).
428439 not call .getNode ( ) .getANamedArg ( ) .( Keyword ) .getArg ( ) = name and // no keyword argument available
429440 n >= 0 and
430441 n < f .getPositionalParameterCount ( ) + f .getKeywordOnlyParameterCount ( ) and
@@ -519,6 +530,8 @@ class DataFlowModuleScope extends DataFlowCallable, TModule {
519530 * as the class call will synthesize an argument node to be mapped to the `self` parameter.
520531 *
521532 * A call corresponding to a special method call is handled by the corresponding `SpecialMethodCallNode`.
533+ *
534+ * TODO: Add `TClassMethodCall` mapping `cls` appropriately.
522535 */
523536newtype TDataFlowCall =
524537 TFunctionCall ( CallNode call ) { call = any ( FunctionValue f ) .getAFunctionCall ( ) } or
0 commit comments