@@ -124,6 +124,14 @@ module API {
124124 */
125125 Node getParameter ( int i ) { result = this .getASuccessor ( Label:: parameter ( i ) ) }
126126
127+ /**
128+ * Gets the node representing the parameter named `name` of the function represented by this node.
129+ *
130+ * This predicate may have multiple results when there are multiple invocations of this API component.
131+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
132+ */
133+ Node getNamedParameter ( string name ) { result = this .getASuccessor ( Label:: namedParameter ( name ) ) }
134+
127135 /**
128136 * Gets the number of parameters of the function represented by this node.
129137 */
@@ -491,7 +499,6 @@ module API {
491499 * rhs = m.getAnExportedValue(prop)
492500 * )
493501 * or
494- * // TODO:
495502 */
496503
497504 /*
@@ -503,10 +510,7 @@ module API {
503510 * )
504511 */
505512
506- exists ( int i |
507- lbl = Label:: parameter ( i ) and
508- argumentPassing ( base , i , rhs )
509- )
513+ argumentPassing ( base , lbl , rhs )
510514 or
511515 exists ( DataFlow:: LocalSourceNode src , DataFlow:: AttrWrite pw |
512516 use ( base , src ) and pw = trackUseNode ( src ) .getAnAttributeWrite ( ) and rhs = pw .getValue ( )
@@ -553,23 +557,20 @@ module API {
553557 )
554558 )
555559 or
556- exists ( DataFlow:: Node def , CallableExpr fn , int i |
560+ exists ( DataFlow:: Node def , CallableExpr fn |
557561 rhs ( base , def ) and fn = trackDefNode ( def ) .asExpr ( )
558562 |
559- lbl = Label:: parameter ( i ) and
560- ref .asExpr ( ) = fn .getInnerScope ( ) .getArg ( i )
563+ exists ( int i |
564+ lbl = Label:: parameter ( i ) and
565+ ref .asExpr ( ) = fn .getInnerScope ( ) .getArg ( i )
566+ )
567+ or
568+ exists ( string name |
569+ lbl = Label:: namedParameter ( name ) and
570+ ref .asExpr ( ) = fn .getInnerScope ( ) .getArgByName ( name )
571+ )
561572 )
562573 or
563- /*
564- * or // TODO: Figure out classes.
565- * exists(DataFlow::Node def, DataFlow::ClassNode cls, int i |
566- * rhs(base, def) and cls = trackDefNode(def)
567- * |
568- * lbl = Label::parameter(i) and
569- * ref = cls.getConstructor().getParameter(i)
570- * )
571- */
572-
573574 // Built-ins, treated as members of the module `builtins`
574575 base = MkModuleImport ( "builtins" ) and
575576 lbl = Label:: member ( any ( string name | ref = Builtins:: likelyBuiltin ( name ) ) )
@@ -618,23 +619,25 @@ module API {
618619 }
619620
620621 /**
621- * Holds if `arg` is passed as the `i`th argument to a use of `base`, either by means of a
622- * full invocation, or in a partial function application.
622+ * Holds if `arg` is passed as an argument to a use of `base`.
623+ *
624+ * `lbl` is represents which parameter of the function was passed. Either a numbered parameter, or a named parameter.
623625 *
624626 * The receiver is considered to be argument -1.
625627 */
626- private predicate argumentPassing ( TApiNode base , int i , DataFlow:: Node arg ) {
628+ private predicate argumentPassing ( TApiNode base , Label :: ApiLabel lbl , DataFlow:: Node arg ) {
627629 exists ( DataFlow:: Node use , DataFlow:: LocalSourceNode pred |
628630 use ( base , use ) and pred = trackUseNode ( use , _)
629631 |
630- arg = pred . getACall ( ) . getArg ( i )
631- /*
632- * or // TODO: Figure out self in argument.
633- * arg = pred.getACall().getReceiver() and
634- * i = -1
635- */
636-
632+ exists ( int i |
633+ lbl = Label :: parameter ( i ) and
634+ arg = pred . getACall ( ) . getArg ( i )
635+ )
636+ or
637+ exists ( string name | lbl = Label :: namedParameter ( name ) |
638+ arg = pred . getACall ( ) . getArgByName ( name )
637639 )
640+ )
638641 }
639642
640643 /**
@@ -778,6 +781,11 @@ module API {
778781 or
779782 exists ( any ( Function f ) .getArg ( i ) )
780783 } or
784+ MkLabelNamedParameter ( string name ) {
785+ exists ( any ( DataFlow:: CallCfgNode c ) .getArgByName ( name ) )
786+ or
787+ exists ( any ( Function f ) .getArgByName ( name ) )
788+ } or
781789 MkLabelReturn ( ) or
782790 MkLabelSubclass ( ) or
783791 MkLabelAwait ( )
@@ -819,13 +827,24 @@ module API {
819827
820828 LabelParameter ( ) { this = MkLabelParameter ( i ) }
821829
822- // TODO: Named parameters, spread arguments.
823830 override string toString ( ) { result = "getParameter(" + i + ")" }
824831
825832 /** Gets the index of the parameter for this label. */
826833 int getIndex ( ) { result = i }
827834 }
828835
836+ /** A label for a named parameter `name`. */
837+ class LabelNamedParameter extends ApiLabel {
838+ string name ;
839+
840+ LabelNamedParameter ( ) { this = MkLabelNamedParameter ( name ) }
841+
842+ override string toString ( ) { result = "getNamedParameter(\"" + name + "\")" }
843+
844+ /** Gets the name of the parameter for this label. */
845+ string getName ( ) { result = name }
846+ }
847+
829848 /** A label that gets the return value of a function. */
830849 class LabelReturn extends ApiLabel {
831850 LabelReturn ( ) { this = MkLabelReturn ( ) }
@@ -868,6 +887,9 @@ module API {
868887 /** Gets the `parameter` edge label for parameter `i`. */
869888 LabelParameter parameter ( int i ) { result .getIndex ( ) = i }
870889
890+ /** Gets the `parameter` edge label for the named parameter `name`. */
891+ LabelNamedParameter namedParameter ( string name ) { result .getName ( ) = name }
892+
871893 /** Gets the `return` edge label. */
872894 LabelReturn return ( ) { any ( ) }
873895
0 commit comments