@@ -114,13 +114,13 @@ module API {
114
114
* Gets a node such that there is an edge in the API graph between this node and the other
115
115
* one, and that edge is labeled with `lbl`.
116
116
*/
117
- Node getASuccessor ( string lbl ) { Impl:: edge ( this , lbl , result ) }
117
+ Node getASuccessor ( Label :: ApiLabel lbl ) { Impl:: edge ( this , lbl , result ) }
118
118
119
119
/**
120
120
* Gets a node such that there is an edge in the API graph between that other node and
121
121
* this one, and that edge is labeled with `lbl`
122
122
*/
123
- Node getAPredecessor ( string lbl ) { this = result .getASuccessor ( lbl ) }
123
+ Node getAPredecessor ( Label :: ApiLabel lbl ) { this = result .getASuccessor ( lbl ) }
124
124
125
125
/**
126
126
* Gets a node such that there is an edge in the API graph between this node and the other
@@ -174,9 +174,8 @@ module API {
174
174
length = 0 and
175
175
result = ""
176
176
or
177
- exists ( Node pred , string lbl , string predpath |
177
+ exists ( Node pred , Label :: ApiLabel lbl , string predpath |
178
178
Impl:: edge ( pred , lbl , this ) and
179
- lbl != "" and
180
179
predpath = pred .getAPath ( length - 1 ) and
181
180
exists ( string dot | if length = 1 then dot = "" else dot = "." |
182
181
result = predpath + dot + lbl and
@@ -335,7 +334,8 @@ module API {
335
334
*
336
335
* For instance, `prefix_member("foo.bar", "baz", "foo.bar.baz")` would hold.
337
336
*/
338
- private predicate prefix_member ( TApiNode base , string member , TApiNode sub ) {
337
+ cached
338
+ predicate prefix_member ( TApiNode base , string member , TApiNode sub ) {
339
339
exists ( string sub_str , string regexp |
340
340
regexp = "(.+)[.]([^.]+)" and
341
341
base = MkModuleImport ( sub_str .regexpCapture ( regexp , 1 ) ) and
@@ -386,7 +386,7 @@ module API {
386
386
* `lbl` in the API graph.
387
387
*/
388
388
cached
389
- predicate use ( TApiNode base , string lbl , DataFlow:: Node ref ) {
389
+ predicate use ( TApiNode base , Label :: ApiLabel lbl , DataFlow:: Node ref ) {
390
390
exists ( DataFlow:: LocalSourceNode src , DataFlow:: LocalSourceNode pred |
391
391
// First, we find a predecessor of the node `ref` that we want to determine. The predecessor
392
392
// is any node that is a type-tracked use of a data flow node (`src`), which is itself a
@@ -481,7 +481,7 @@ module API {
481
481
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
482
482
*/
483
483
cached
484
- predicate edge ( TApiNode pred , string lbl , TApiNode succ ) {
484
+ predicate edge ( TApiNode pred , Label :: ApiLabel lbl , TApiNode succ ) {
485
485
/* There's an edge from the root node for each imported module. */
486
486
exists ( string m |
487
487
pred = MkRoot ( ) and
@@ -514,36 +514,126 @@ module API {
514
514
cached
515
515
int distanceFromRoot ( TApiNode nd ) = shortestDistances( MkRoot / 0 , edge / 2 ) ( _, nd , result )
516
516
}
517
- }
518
517
519
- private module Label {
520
- /** Gets the edge label for the module `m`. */
521
- bindingset [ m]
522
- bindingset [ result ]
523
- string mod ( string m ) { result = "moduleImport(\"" + m + "\")" }
524
-
525
- /** Gets the `member` edge label for member `m`. */
526
- bindingset [ m]
527
- bindingset [ result ]
528
- string member ( string m ) { result = "getMember(\"" + m + "\")" }
529
-
530
- /** Gets the `member` edge label for the unknown member. */
531
- string unknownMember ( ) { result = "getUnknownMember()" }
532
-
533
- /** Gets the `member` edge label for the given attribute reference. */
534
- string memberFromRef ( DataFlow:: AttrRef pr ) {
535
- result = member ( pr .getAttributeName ( ) )
536
- or
537
- not exists ( pr .getAttributeName ( ) ) and
538
- result = unknownMember ( )
539
- }
518
+ /** Provides classes modeling the various edges (labels) in the API graph. */
519
+ module Label {
520
+ /** A label in the API-graph */
521
+ class ApiLabel extends TLabel {
522
+ /** Gets a string representation of this label. */
523
+ string toString ( ) { result = "???" }
524
+ }
525
+
526
+ private import LabelImpl
527
+
528
+ private module LabelImpl {
529
+ private import semmle.python.dataflow.new.internal.Builtins
530
+ private import semmle.python.dataflow.new.internal.ImportStar
531
+
532
+ newtype TLabel =
533
+ MkLabelModule ( string mod ) { exists ( Impl:: MkModuleImport ( mod ) ) } or
534
+ MkLabelMember ( string member ) {
535
+ member = any ( DataFlow:: AttrRef pr ) .getAttributeName ( ) or
536
+ exists ( Builtins:: likelyBuiltin ( member ) ) or
537
+ ImportStar:: namePossiblyDefinedInImportStar ( _, member , _) or
538
+ Impl:: prefix_member ( _, member , _)
539
+ } or
540
+ MkLabelUnknownMember ( ) or
541
+ MkLabelParameter ( int i ) {
542
+ none ( ) // TODO: Fill in when adding def nodes
543
+ } or
544
+ MkLabelReturn ( ) or
545
+ MkLabelSubclass ( ) or
546
+ MkLabelAwait ( )
547
+
548
+ /** A label for a module. */
549
+ class LabelModule extends ApiLabel {
550
+ string mod ;
551
+
552
+ LabelModule ( ) { this = MkLabelModule ( mod ) }
553
+
554
+ /** Gets the module associated with this label. */
555
+ string getMod ( ) { result = mod }
556
+
557
+ override string toString ( ) { result = "moduleImport(\"" + mod + "\")" }
558
+ }
559
+
560
+ /** A label for the member named `prop`. */
561
+ class LabelMember extends ApiLabel {
562
+ string member ;
563
+
564
+ LabelMember ( ) { this = MkLabelMember ( member ) }
565
+
566
+ /** Gets the property associated with this label. */
567
+ string getMember ( ) { result = member }
568
+
569
+ override string toString ( ) { result = "getMember(\"" + member + "\")" }
570
+ }
571
+
572
+ /** A label for a member with an unknown name. */
573
+ class LabelUnknownMember extends ApiLabel {
574
+ LabelUnknownMember ( ) { this = MkLabelUnknownMember ( ) }
575
+
576
+ override string toString ( ) { result = "getUnknownMember()" }
577
+ }
578
+
579
+ /** A label for parameter `i`. */
580
+ class LabelParameter extends ApiLabel {
581
+ int i ;
540
582
541
- /** Gets the `return` edge label. */
542
- string return ( ) { result = "getReturn()" }
583
+ LabelParameter ( ) { this = MkLabelParameter ( i ) }
543
584
544
- /** Gets the `subclass` edge label. */
545
- string subclass ( ) { result = "getASubclass()" }
585
+ override string toString ( ) { result = "getParameter(" + i + ")" }
546
586
547
- /** Gets the `await` edge label. */
548
- string await ( ) { result = "getAwaited()" }
587
+ /** Gets the index of the parameter for this label. */
588
+ int getIndex ( ) { result = i }
589
+ }
590
+
591
+ /** A label that gets the return value of a function. */
592
+ class LabelReturn extends ApiLabel {
593
+ LabelReturn ( ) { this = MkLabelReturn ( ) }
594
+
595
+ override string toString ( ) { result = "getReturn()" }
596
+ }
597
+
598
+ /** A label that gets the subclass of a class. */
599
+ class LabelSubclass extends ApiLabel {
600
+ LabelSubclass ( ) { this = MkLabelSubclass ( ) }
601
+
602
+ override string toString ( ) { result = "getASubclass()" }
603
+ }
604
+
605
+ /** A label for awaited values. */
606
+ class LabelAwait extends ApiLabel {
607
+ LabelAwait ( ) { this = MkLabelAwait ( ) }
608
+
609
+ override string toString ( ) { result = "getAwaited()" }
610
+ }
611
+ }
612
+
613
+ /** Gets the edge label for the module `m`. */
614
+ LabelModule mod ( string m ) { result .getMod ( ) = m }
615
+
616
+ /** Gets the `member` edge label for member `m`. */
617
+ LabelMember member ( string m ) { result .getMember ( ) = m }
618
+
619
+ /** Gets the `member` edge label for the unknown member. */
620
+ LabelUnknownMember unknownMember ( ) { any ( ) }
621
+
622
+ /** Gets the `member` edge label for the given attribute reference. */
623
+ ApiLabel memberFromRef ( DataFlow:: AttrRef pr ) {
624
+ result = member ( pr .getAttributeName ( ) )
625
+ or
626
+ not exists ( pr .getAttributeName ( ) ) and
627
+ result = unknownMember ( )
628
+ }
629
+
630
+ /** Gets the `return` edge label. */
631
+ LabelReturn return ( ) { any ( ) }
632
+
633
+ /** Gets the `subclass` edge label. */
634
+ LabelSubclass subclass ( ) { any ( ) }
635
+
636
+ /** Gets the `await` edge label. */
637
+ LabelAwait await ( ) { any ( ) }
638
+ }
549
639
}
0 commit comments