@@ -171,13 +171,13 @@ module API {
171
171
* Gets a node such that there is an edge in the API graph between this node and the other
172
172
* one, and that edge is labeled with `lbl`.
173
173
*/
174
- Node getASuccessor ( string lbl ) { Impl:: edge ( this , lbl , result ) }
174
+ Node getASuccessor ( Label :: ApiLabel lbl ) { Impl:: edge ( this , lbl , result ) }
175
175
176
176
/**
177
177
* Gets a node such that there is an edge in the API graph between that other node and
178
178
* this one, and that edge is labeled with `lbl`
179
179
*/
180
- Node getAPredecessor ( string lbl ) { this = result .getASuccessor ( lbl ) }
180
+ Node getAPredecessor ( Label :: ApiLabel lbl ) { this = result .getASuccessor ( lbl ) }
181
181
182
182
/**
183
183
* Gets a node such that there is an edge in the API graph between this node and the other
@@ -225,9 +225,8 @@ module API {
225
225
length = 0 and
226
226
result = ""
227
227
or
228
- exists ( Node pred , string lbl , string predpath |
228
+ exists ( Node pred , Label :: ApiLabel lbl , string predpath |
229
229
Impl:: edge ( pred , lbl , this ) and
230
- lbl != "" and
231
230
predpath = pred .getAPath ( length - 1 ) and
232
231
exists ( string dot | if length = 1 then dot = "" else dot = "." |
233
232
result = predpath + dot + lbl and
@@ -306,7 +305,7 @@ module API {
306
305
* shortest length.
307
306
*/
308
307
cached
309
- private module Impl {
308
+ module Impl {
310
309
cached
311
310
newtype TApiNode =
312
311
/** The root of the API graph. */
@@ -328,7 +327,7 @@ module API {
328
327
* node labeled `lbl` in the API graph.
329
328
*/
330
329
pragma [ nomagic]
331
- private predicate useRoot ( string lbl , DataFlow:: Node ref ) {
330
+ private predicate useRoot ( Label :: ApiLabel lbl , DataFlow:: Node ref ) {
332
331
exists ( string name , ConstantReadAccess read |
333
332
read = ref .asExpr ( ) .getExpr ( ) and
334
333
lbl = Label:: member ( read .getName ( ) )
@@ -345,7 +344,7 @@ module API {
345
344
* Holds if `ref` is a use of a node that should have an incoming edge labeled `lbl`,
346
345
* from a use node that flows to `node`.
347
346
*/
348
- private predicate useStep ( string lbl , DataFlow:: Node node , DataFlow:: Node ref ) {
347
+ private predicate useStep ( Label :: ApiLabel lbl , DataFlow:: Node node , DataFlow:: Node ref ) {
349
348
// // Referring to an attribute on a node that is a use of `base`:
350
349
// pred = `Rails` part of `Rails::Whatever`
351
350
// lbl = `Whatever`
@@ -433,7 +432,7 @@ module API {
433
432
/** Gets a data flow node that flows to the RHS of a def-node. */
434
433
private DataFlow:: LocalSourceNode defCand ( ) { result = defCand ( TypeBackTracker:: end ( ) ) }
435
434
436
- private string getLabelFromArgumentPosition ( DataFlowDispatch:: ArgumentPosition pos ) {
435
+ private Label :: ApiLabel getLabelFromArgumentPosition ( DataFlowDispatch:: ArgumentPosition pos ) {
437
436
exists ( int n |
438
437
pos .isPositional ( n ) and
439
438
result = Label:: parameter ( n )
@@ -448,7 +447,7 @@ module API {
448
447
result = Label:: blockParameter ( )
449
448
}
450
449
451
- private string getLabelFromParameterPosition ( DataFlowDispatch:: ParameterPosition pos ) {
450
+ private Label :: ApiLabel getLabelFromParameterPosition ( DataFlowDispatch:: ParameterPosition pos ) {
452
451
exists ( int n |
453
452
pos .isPositional ( n ) and
454
453
result = Label:: parameter ( n )
@@ -468,7 +467,7 @@ module API {
468
467
*/
469
468
pragma [ nomagic]
470
469
private predicate argumentStep (
471
- string lbl , DataFlow:: CallNode call , DataFlowPrivate:: ArgumentNode argument
470
+ Label :: ApiLabel lbl , DataFlow:: CallNode call , DataFlowPrivate:: ArgumentNode argument
472
471
) {
473
472
exists ( DataFlowDispatch:: ArgumentPosition argPos |
474
473
argument .sourceArgumentOf ( call .asExpr ( ) , argPos ) and
@@ -481,7 +480,7 @@ module API {
481
480
*/
482
481
pragma [ nomagic]
483
482
private predicate parameterStep (
484
- string lbl , DataFlow:: Node callable , DataFlowPrivate:: ParameterNodeImpl paramNode
483
+ Label :: ApiLabel lbl , DataFlow:: Node callable , DataFlowPrivate:: ParameterNodeImpl paramNode
485
484
) {
486
485
exists ( DataFlowDispatch:: ParameterPosition paramPos |
487
486
paramNode .isSourceParameterOf ( callable .asExpr ( ) .getExpr ( ) , paramPos ) and
@@ -541,7 +540,7 @@ module API {
541
540
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
542
541
*/
543
542
cached
544
- predicate edge ( TApiNode pred , string lbl , TApiNode succ ) {
543
+ predicate edge ( TApiNode pred , Label :: ApiLabel lbl , TApiNode succ ) {
545
544
/* Every node that is a use of an API component is itself added to the API graph. */
546
545
exists ( DataFlow:: LocalSourceNode ref | succ = MkUse ( ref ) |
547
546
pred = MkRoot ( ) and
@@ -602,48 +601,133 @@ module API {
602
601
cached
603
602
int distanceFromRoot ( TApiNode nd ) = shortestDistances( MkRoot / 0 , edge / 2 ) ( _, nd , result )
604
603
}
605
- }
606
604
607
- private module Label {
608
- /** Gets the `member` edge label for member `m`. */
609
- bindingset [ m]
610
- bindingset [ result ]
611
- string member ( string m ) { result = "getMember(\"" + m + "\")" }
612
-
613
- /** Gets the `member` edge label for the unknown member. */
614
- string unknownMember ( ) { result = "getUnknownMember()" }
615
-
616
- /** Gets the `method` edge label. */
617
- bindingset [ m]
618
- bindingset [ result ]
619
- string method ( string m ) { result = "getMethod(\"" + m + "\")" }
620
-
621
- /** Gets the `return` edge label. */
622
- string return ( ) { result = "getReturn()" }
623
-
624
- string subclass ( ) { result = "getASubclass()" }
625
-
626
- /** Gets the label representing the given keword argument/parameter. */
627
- bindingset [ name]
628
- bindingset [ result ]
629
- string keywordParameter ( string name ) { result = "getKeywordParameter(\"" + name + "\")" }
630
-
631
- /** Gets the label representing the `n`th positional argument/parameter. */
632
- bindingset [ n]
633
- bindingset [ result ]
634
- string parameter ( int n ) {
635
- exists ( string s |
636
- result = parameterByStr ( s ) and
637
- n = s .toInt ( ) and
638
- s = n .toString ( )
639
- )
640
- }
605
+ module Label {
606
+ /** A label in the API-graph */
607
+ class ApiLabel extends TLabel {
608
+ /** Gets a string representation of this label. */
609
+ string toString ( ) { result = "???" }
610
+ }
611
+
612
+ private import LabelImpl
613
+
614
+ private module LabelImpl {
615
+ newtype TLabel =
616
+ MkLabelMember ( string member ) { member = any ( ConstantReadAccess a ) .getName ( ) } or
617
+ MkLabelUnknownMember ( ) or
618
+ MkLabelMethod ( string m ) { m = any ( DataFlow:: CallNode c ) .getMethodName ( ) } or
619
+ MkLabelReturn ( ) or
620
+ MkLabelSubclass ( ) or
621
+ MkLabelKeywordParameter ( string name ) {
622
+ any ( DataFlowDispatch:: ArgumentPosition arg ) .isKeyword ( name )
623
+ or
624
+ any ( DataFlowDispatch:: ParameterPosition arg ) .isKeyword ( name )
625
+ } or
626
+ MkLabelParameter ( int n ) {
627
+ any ( DataFlowDispatch:: ArgumentPosition c ) .isPositional ( n )
628
+ or
629
+ any ( DataFlowDispatch:: ParameterPosition c ) .isPositional ( n )
630
+ } or
631
+ MkLabelBlockParameter ( )
632
+
633
+ /** A label for the member named `prop`. */
634
+ class LabelMember extends ApiLabel {
635
+ string member ;
636
+
637
+ LabelMember ( ) { this = MkLabelMember ( member ) }
638
+
639
+ /** Gets the property associated with this label. */
640
+ string getMember ( ) { result = member }
641
+
642
+ override string toString ( ) { result = "getMember(\"" + member + "\")" }
643
+ }
644
+
645
+ /** A label for a member with an unknown name. */
646
+ class LabelUnknownMember extends ApiLabel {
647
+ LabelUnknownMember ( ) { this = MkLabelUnknownMember ( ) }
648
+
649
+ override string toString ( ) { result = "getUnknownMember()" }
650
+ }
651
+
652
+ /** A label for the method named `method`. */
653
+ class LabelMethod extends ApiLabel {
654
+ string method ;
655
+
656
+ LabelMethod ( ) { this = MkLabelMethod ( method ) }
657
+
658
+ /** Gets the method name associated with this label. */
659
+ string getMethod ( ) { result = method }
660
+
661
+ override string toString ( ) { result = "getMethod(\"" + method + "\")" }
662
+ }
663
+
664
+ /** A label for the return value of a method. */
665
+ class LabelReturn extends ApiLabel {
666
+ LabelReturn ( ) { this = MkLabelReturn ( ) }
667
+
668
+ override string toString ( ) { result = "getReturn()" }
669
+ }
670
+
671
+ /** A label for the subclass relationship. */
672
+ class LabelSubclass extends ApiLabel {
673
+ LabelSubclass ( ) { this = MkLabelSubclass ( ) }
641
674
642
- /** Gets the label representing the `n`th positional argument/parameter. */
643
- bindingset [ n]
644
- bindingset [ result ]
645
- string parameterByStr ( string n ) { result = "getParameter(" + n + ")" }
675
+ override string toString ( ) { result = "getASubclass()" }
676
+ }
646
677
647
- /** Gets the label representing the block argument/parameter. */
648
- string blockParameter ( ) { result = "getBlock()" }
678
+ /** A label for a keyword parameter. */
679
+ class LabelKeywordParameter extends ApiLabel {
680
+ string name ;
681
+
682
+ LabelKeywordParameter ( ) { this = MkLabelKeywordParameter ( name ) }
683
+
684
+ /** Gets the name of the keyword parameter associated with this label. */
685
+ string getName ( ) { result = name }
686
+
687
+ override string toString ( ) { result = "getKeywordParameter(\"" + name + "\")" }
688
+ }
689
+
690
+ /** A label for a parameter. */
691
+ class LabelParameter extends ApiLabel {
692
+ int n ;
693
+
694
+ LabelParameter ( ) { this = MkLabelParameter ( n ) }
695
+
696
+ /** Gets the parameter number associated with this label. */
697
+ int getIndex ( ) { result = n }
698
+
699
+ override string toString ( ) { result = "getParameter(" + n + ")" }
700
+ }
701
+
702
+ /** A label for a block parameter. */
703
+ class LabelBlockParameter extends ApiLabel {
704
+ LabelBlockParameter ( ) { this = MkLabelBlockParameter ( ) }
705
+
706
+ override string toString ( ) { result = "getBlock()" }
707
+ }
708
+ }
709
+
710
+ /** Gets the `member` edge label for member `m`. */
711
+ LabelMember member ( string m ) { result .getMember ( ) = m }
712
+
713
+ /** Gets the `member` edge label for the unknown member. */
714
+ LabelUnknownMember unknownMember ( ) { any ( ) }
715
+
716
+ /** Gets the `method` edge label. */
717
+ LabelMethod method ( string m ) { result .getMethod ( ) = m }
718
+
719
+ /** Gets the `return` edge label. */
720
+ LabelReturn return ( ) { any ( ) }
721
+
722
+ LabelSubclass subclass ( ) { any ( ) }
723
+
724
+ /** Gets the label representing the given keword argument/parameter. */
725
+ LabelKeywordParameter keywordParameter ( string name ) { result .getName ( ) = name }
726
+
727
+ /** Gets the label representing the `n`th positional argument/parameter. */
728
+ LabelParameter parameter ( int n ) { result .getIndex ( ) = n }
729
+
730
+ /** Gets the label representing the block argument/parameter. */
731
+ LabelBlockParameter blockParameter ( ) { any ( ) }
732
+ }
649
733
}
0 commit comments