@@ -2,22 +2,22 @@ import python
2
2
3
3
/** Gets the comment on the line above `ast` */
4
4
Comment commentFor ( AstNode ast ) {
5
- exists ( int line | line = ast .getLocation ( ) .getStartLine ( ) - 1 |
6
- result
7
- .getLocation ( )
8
- .hasLocationInfo ( ast .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) , line , _, line , _)
9
- )
5
+ exists ( int line | line = ast .getLocation ( ) .getStartLine ( ) - 1 |
6
+ result
7
+ .getLocation ( )
8
+ .hasLocationInfo ( ast .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) , line , _, line , _)
9
+ )
10
10
}
11
11
12
12
/** Gets the value from `tag:value` in the comment for `ast` */
13
13
string getAnnotation ( AstNode ast , string tag ) {
14
- exists ( Comment comment , string match , string theRegex |
15
- theRegex = "([\\w]+):([\\w.]+)" and
16
- comment = commentFor ( ast ) and
17
- match = comment .getText ( ) .regexpFind ( theRegex , _, _) and
18
- tag = match .regexpCapture ( theRegex , 1 ) and
19
- result = match .regexpCapture ( theRegex , 2 )
20
- )
14
+ exists ( Comment comment , string match , string theRegex |
15
+ theRegex = "([\\w]+):([\\w.]+)" and
16
+ comment = commentFor ( ast ) and
17
+ match = comment .getText ( ) .regexpFind ( theRegex , _, _) and
18
+ tag = match .regexpCapture ( theRegex , 1 ) and
19
+ result = match .regexpCapture ( theRegex , 2 )
20
+ )
21
21
}
22
22
23
23
/** Gets a callable annotated with `name:name` */
@@ -27,121 +27,121 @@ Function annotatedCallable(string name) { name = getAnnotation(result, "name") }
27
27
Call annotatedCall ( string name ) { name = getAnnotation ( result , "calls" ) }
28
28
29
29
predicate missingAnnotationForCallable ( string name , Call call ) {
30
- call = annotatedCall ( name ) and
31
- not exists ( annotatedCallable ( name ) )
30
+ call = annotatedCall ( name ) and
31
+ not exists ( annotatedCallable ( name ) )
32
32
}
33
33
34
34
predicate nonUniqueAnnotationForCallable ( string name , Function callable ) {
35
- strictcount ( annotatedCallable ( name ) ) > 1 and
36
- callable = annotatedCallable ( name )
35
+ strictcount ( annotatedCallable ( name ) ) > 1 and
36
+ callable = annotatedCallable ( name )
37
37
}
38
38
39
39
predicate missingAnnotationForCall ( string name , Function callable ) {
40
- not exists ( annotatedCall ( name ) ) and
41
- callable = annotatedCallable ( name )
40
+ not exists ( annotatedCall ( name ) ) and
41
+ callable = annotatedCallable ( name )
42
42
}
43
43
44
44
/** There is an obvious problem with the annotation `name` */
45
45
predicate nameInErrorState ( string name ) {
46
- missingAnnotationForCallable ( name , _)
47
- or
48
- nonUniqueAnnotationForCallable ( name , _)
49
- or
50
- missingAnnotationForCall ( name , _)
46
+ missingAnnotationForCallable ( name , _)
47
+ or
48
+ nonUniqueAnnotationForCallable ( name , _)
49
+ or
50
+ missingAnnotationForCall ( name , _)
51
51
}
52
52
53
53
/** Source code has annotation with `name` showing that `call` will call `callable` */
54
54
predicate annotatedCallEdge ( string name , Call call , Function callable ) {
55
- not nameInErrorState ( name ) and
56
- call = annotatedCall ( name ) and
57
- callable = annotatedCallable ( name )
55
+ not nameInErrorState ( name ) and
56
+ call = annotatedCall ( name ) and
57
+ callable = annotatedCallable ( name )
58
58
}
59
59
60
60
// ------------------------- Annotation debug query predicates -------------------------
61
61
query predicate debug_missingAnnotationForCallable ( Call call , string message ) {
62
- exists ( string name |
63
- message =
64
- "This call is annotated with '" + name +
65
- "', but no callable with that annotation was extracted. Please fix." and
66
- missingAnnotationForCallable ( name , call )
67
- )
62
+ exists ( string name |
63
+ message =
64
+ "This call is annotated with '" + name +
65
+ "', but no callable with that annotation was extracted. Please fix." and
66
+ missingAnnotationForCallable ( name , call )
67
+ )
68
68
}
69
69
70
70
query predicate debug_nonUniqueAnnotationForCallable ( Function callable , string message ) {
71
- exists ( string name |
72
- message = "Multiple callables are annotated with '" + name + "'. Please fix." and
73
- nonUniqueAnnotationForCallable ( name , callable )
74
- )
71
+ exists ( string name |
72
+ message = "Multiple callables are annotated with '" + name + "'. Please fix." and
73
+ nonUniqueAnnotationForCallable ( name , callable )
74
+ )
75
75
}
76
76
77
77
query predicate debug_missingAnnotationForCall ( Function callable , string message ) {
78
- exists ( string name |
79
- message =
80
- "This callable is annotated with '" + name +
81
- "', but no call with that annotation was extracted. Please fix." and
82
- missingAnnotationForCall ( name , callable )
83
- )
78
+ exists ( string name |
79
+ message =
80
+ "This callable is annotated with '" + name +
81
+ "', but no call with that annotation was extracted. Please fix." and
82
+ missingAnnotationForCall ( name , callable )
83
+ )
84
84
}
85
85
86
86
// ------------------------- Call Graph resolution -------------------------
87
87
private newtype TCallGraphResolver =
88
- TPointsToResolver ( ) or
89
- TTypeTrackerResolver ( )
88
+ TPointsToResolver ( ) or
89
+ TTypeTrackerResolver ( )
90
90
91
91
/** Describes a method of call graph resolution */
92
92
abstract class CallGraphResolver extends TCallGraphResolver {
93
- abstract predicate callEdge ( Call call , Function callable ) ;
94
-
95
- /**
96
- * Holds if annotations show that `call` will call `callable`,
97
- * but our call graph resolver was not able to figure that out
98
- */
99
- predicate expectedCallEdgeNotFound ( Call call , Function callable ) {
100
- annotatedCallEdge ( _, call , callable ) and
101
- not this .callEdge ( call , callable )
102
- }
103
-
104
- /**
105
- * Holds if there are no annotations that show that `call` will call `callable` (where at least one of these are annotated),
106
- * but the call graph resolver claims that `call` will call `callable`
107
- */
108
- predicate unexpectedCallEdgeFound ( Call call , Function callable , string message ) {
109
- this .callEdge ( call , callable ) and
110
- not annotatedCallEdge ( _, call , callable ) and
111
- (
112
- exists ( string name |
113
- message = "Call resolved to the callable named '" + name + "' but was not annotated as such" and
114
- callable = annotatedCallable ( name ) and
115
- not nameInErrorState ( name )
116
- )
117
- or
118
- exists ( string name |
119
- message = "Annotated call resolved to unannotated callable" and
120
- call = annotatedCall ( name ) and
121
- not nameInErrorState ( name ) and
122
- not exists ( | callable = annotatedCallable ( _) )
123
- )
124
- )
125
- }
126
-
127
- string toString ( ) { result = "CallGraphResolver" }
93
+ abstract predicate callEdge ( Call call , Function callable ) ;
94
+
95
+ /**
96
+ * Holds if annotations show that `call` will call `callable`,
97
+ * but our call graph resolver was not able to figure that out
98
+ */
99
+ predicate expectedCallEdgeNotFound ( Call call , Function callable ) {
100
+ annotatedCallEdge ( _, call , callable ) and
101
+ not this .callEdge ( call , callable )
102
+ }
103
+
104
+ /**
105
+ * Holds if there are no annotations that show that `call` will call `callable` (where at least one of these are annotated),
106
+ * but the call graph resolver claims that `call` will call `callable`
107
+ */
108
+ predicate unexpectedCallEdgeFound ( Call call , Function callable , string message ) {
109
+ this .callEdge ( call , callable ) and
110
+ not annotatedCallEdge ( _, call , callable ) and
111
+ (
112
+ exists ( string name |
113
+ message = "Call resolved to the callable named '" + name + "' but was not annotated as such" and
114
+ callable = annotatedCallable ( name ) and
115
+ not nameInErrorState ( name )
116
+ )
117
+ or
118
+ exists ( string name |
119
+ message = "Annotated call resolved to unannotated callable" and
120
+ call = annotatedCall ( name ) and
121
+ not nameInErrorState ( name ) and
122
+ not exists ( | callable = annotatedCallable ( _) )
123
+ )
124
+ )
125
+ }
126
+
127
+ string toString ( ) { result = "CallGraphResolver" }
128
128
}
129
129
130
130
/** A call graph resolver based on the existing points-to analysis */
131
131
class PointsToResolver extends CallGraphResolver , TPointsToResolver {
132
- override predicate callEdge ( Call call , Function callable ) {
133
- exists ( PythonFunctionValue funcValue |
134
- funcValue .getScope ( ) = callable and
135
- call = funcValue .getACall ( ) .getNode ( )
136
- )
137
- }
138
-
139
- override string toString ( ) { result = "PointsToResolver" }
132
+ override predicate callEdge ( Call call , Function callable ) {
133
+ exists ( PythonFunctionValue funcValue |
134
+ funcValue .getScope ( ) = callable and
135
+ call = funcValue .getACall ( ) .getNode ( )
136
+ )
137
+ }
138
+
139
+ override string toString ( ) { result = "PointsToResolver" }
140
140
}
141
141
142
142
/** A call graph resolved based on Type Trackers */
143
143
class TypeTrackerResolver extends CallGraphResolver , TTypeTrackerResolver {
144
- override predicate callEdge ( Call call , Function callable ) { none ( ) }
144
+ override predicate callEdge ( Call call , Function callable ) { none ( ) }
145
145
146
- override string toString ( ) { result = "TypeTrackerResolver" }
146
+ override string toString ( ) { result = "TypeTrackerResolver" }
147
147
}
0 commit comments