@@ -124,6 +124,14 @@ module API {
124
124
*/
125
125
Node getParameter ( int i ) { result = this .getASuccessor ( Label:: parameter ( i ) ) }
126
126
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
+
127
135
/**
128
136
* Gets the number of parameters of the function represented by this node.
129
137
*/
@@ -491,7 +499,6 @@ module API {
491
499
* rhs = m.getAnExportedValue(prop)
492
500
* )
493
501
* or
494
- * // TODO:
495
502
*/
496
503
497
504
/*
@@ -503,10 +510,7 @@ module API {
503
510
* )
504
511
*/
505
512
506
- exists ( int i |
507
- lbl = Label:: parameter ( i ) and
508
- argumentPassing ( base , i , rhs )
509
- )
513
+ argumentPassing ( base , lbl , rhs )
510
514
or
511
515
exists ( DataFlow:: LocalSourceNode src , DataFlow:: AttrWrite pw |
512
516
use ( base , src ) and pw = trackUseNode ( src ) .getAnAttributeWrite ( ) and rhs = pw .getValue ( )
@@ -553,23 +557,20 @@ module API {
553
557
)
554
558
)
555
559
or
556
- exists ( DataFlow:: Node def , CallableExpr fn , int i |
560
+ exists ( DataFlow:: Node def , CallableExpr fn |
557
561
rhs ( base , def ) and fn = trackDefNode ( def ) .asExpr ( )
558
562
|
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
+ )
561
572
)
562
573
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
-
573
574
// Built-ins, treated as members of the module `builtins`
574
575
base = MkModuleImport ( "builtins" ) and
575
576
lbl = Label:: member ( any ( string name | ref = Builtins:: likelyBuiltin ( name ) ) )
@@ -618,23 +619,25 @@ module API {
618
619
}
619
620
620
621
/**
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.
623
625
*
624
626
* The receiver is considered to be argument -1.
625
627
*/
626
- private predicate argumentPassing ( TApiNode base , int i , DataFlow:: Node arg ) {
628
+ private predicate argumentPassing ( TApiNode base , Label :: ApiLabel lbl , DataFlow:: Node arg ) {
627
629
exists ( DataFlow:: Node use , DataFlow:: LocalSourceNode pred |
628
630
use ( base , use ) and pred = trackUseNode ( use , _)
629
631
|
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 )
637
639
)
640
+ )
638
641
}
639
642
640
643
/**
@@ -778,6 +781,11 @@ module API {
778
781
or
779
782
exists ( any ( Function f ) .getArg ( i ) )
780
783
} or
784
+ MkLabelNamedParameter ( string name ) {
785
+ exists ( any ( DataFlow:: CallCfgNode c ) .getArgByName ( name ) )
786
+ or
787
+ exists ( any ( Function f ) .getArgByName ( name ) )
788
+ } or
781
789
MkLabelReturn ( ) or
782
790
MkLabelSubclass ( ) or
783
791
MkLabelAwait ( )
@@ -819,13 +827,24 @@ module API {
819
827
820
828
LabelParameter ( ) { this = MkLabelParameter ( i ) }
821
829
822
- // TODO: Named parameters, spread arguments.
823
830
override string toString ( ) { result = "getParameter(" + i + ")" }
824
831
825
832
/** Gets the index of the parameter for this label. */
826
833
int getIndex ( ) { result = i }
827
834
}
828
835
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
+
829
848
/** A label that gets the return value of a function. */
830
849
class LabelReturn extends ApiLabel {
831
850
LabelReturn ( ) { this = MkLabelReturn ( ) }
@@ -868,6 +887,9 @@ module API {
868
887
/** Gets the `parameter` edge label for parameter `i`. */
869
888
LabelParameter parameter ( int i ) { result .getIndex ( ) = i }
870
889
890
+ /** Gets the `parameter` edge label for the named parameter `name`. */
891
+ LabelNamedParameter namedParameter ( string name ) { result .getName ( ) = name }
892
+
871
893
/** Gets the `return` edge label. */
872
894
LabelReturn return ( ) { any ( ) }
873
895
0 commit comments