1
+ /**
2
+ * INTERNAL use only. This is an experimental API subject to change without notice.
3
+ *
4
+ * Provides classes and predicates for dealing with flow models specified in CSV format.
5
+ */
6
+
1
7
import java
2
8
private import semmle.code.java.dataflow.DataFlow:: DataFlow
3
9
private import internal.DataFlowPrivate
@@ -32,15 +38,33 @@ private predicate sinkModelCsv(string row) { none() }
32
38
33
39
private predicate summaryModelCsv ( string row ) { none ( ) }
34
40
41
+ /**
42
+ * A unit class for adding additional source model rows.
43
+ *
44
+ * Extend this class to add additional source definitions.
45
+ */
35
46
class SourceModelCsv extends Unit {
47
+ /** Holds if `row` specifies a source definition. */
36
48
abstract predicate row ( string row ) ;
37
49
}
38
50
51
+ /**
52
+ * A unit class for adding additional sink model rows.
53
+ *
54
+ * Extend this class to add additional sink definitions.
55
+ */
39
56
class SinkModelCsv extends Unit {
57
+ /** Holds if `row` specifies a sink definition. */
40
58
abstract predicate row ( string row ) ;
41
59
}
42
60
61
+ /**
62
+ * A unit class for adding additional summary model rows.
63
+ *
64
+ * Extend this class to add additional flow summary definitions.
65
+ */
43
66
class SummaryModelCsv extends Unit {
67
+ /** Holds if `row` specifies a summary definition. */
44
68
abstract predicate row ( string row ) ;
45
69
}
46
70
@@ -60,15 +84,15 @@ private predicate summaryModel(string row) {
60
84
}
61
85
62
86
private predicate sourceModel (
63
- string namespace , string type , boolean overrides , string name , string signature , string ext ,
87
+ string namespace , string type , boolean subtypes , string name , string signature , string ext ,
64
88
string output , string kind
65
89
) {
66
90
exists ( string row |
67
91
sourceModel ( row ) and
68
92
row .splitAt ( ";" , 0 ) = namespace and
69
93
row .splitAt ( ";" , 1 ) = type and
70
- row .splitAt ( ";" , 2 ) = overrides .toString ( ) and
71
- overrides = [ true , false ] and
94
+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
95
+ subtypes = [ true , false ] and
72
96
row .splitAt ( ";" , 3 ) = name and
73
97
row .splitAt ( ";" , 4 ) = signature and
74
98
row .splitAt ( ";" , 5 ) = ext and
@@ -78,15 +102,15 @@ private predicate sourceModel(
78
102
}
79
103
80
104
private predicate sinkModel (
81
- string namespace , string type , boolean overrides , string name , string signature , string ext ,
105
+ string namespace , string type , boolean subtypes , string name , string signature , string ext ,
82
106
string input , string kind
83
107
) {
84
108
exists ( string row |
85
109
sinkModel ( row ) and
86
110
row .splitAt ( ";" , 0 ) = namespace and
87
111
row .splitAt ( ";" , 1 ) = type and
88
- row .splitAt ( ";" , 2 ) = overrides .toString ( ) and
89
- overrides = [ true , false ] and
112
+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
113
+ subtypes = [ true , false ] and
90
114
row .splitAt ( ";" , 3 ) = name and
91
115
row .splitAt ( ";" , 4 ) = signature and
92
116
row .splitAt ( ";" , 5 ) = ext and
@@ -96,15 +120,15 @@ private predicate sinkModel(
96
120
}
97
121
98
122
private predicate summaryModel (
99
- string namespace , string type , boolean overrides , string name , string signature , string ext ,
123
+ string namespace , string type , boolean subtypes , string name , string signature , string ext ,
100
124
string input , string output , string kind
101
125
) {
102
126
exists ( string row |
103
127
summaryModel ( row ) and
104
128
row .splitAt ( ";" , 0 ) = namespace and
105
129
row .splitAt ( ";" , 1 ) = type and
106
- row .splitAt ( ";" , 2 ) = overrides .toString ( ) and
107
- overrides = [ true , false ] and
130
+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
131
+ subtypes = [ true , false ] and
108
132
row .splitAt ( ";" , 3 ) = name and
109
133
row .splitAt ( ";" , 4 ) = signature and
110
134
row .splitAt ( ";" , 5 ) = ext and
@@ -114,7 +138,9 @@ private predicate summaryModel(
114
138
)
115
139
}
116
140
141
+ /** Provides a query predicate to check the CSV data for validation errors. */
117
142
module CsvValidation {
143
+ /** Holds if some row in a CSV-based flow model appears to contain typos. */
118
144
query predicate invalidModelRow ( string msg ) {
119
145
exists ( string pred , string namespace , string type , string name , string signature , string ext |
120
146
sourceModel ( namespace , type , _, name , signature , ext , _, _) and pred = "source"
@@ -187,18 +213,18 @@ module CsvValidation {
187
213
}
188
214
189
215
private predicate elementSpec (
190
- string namespace , string type , boolean overrides , string name , string signature , string ext
216
+ string namespace , string type , boolean subtypes , string name , string signature , string ext
191
217
) {
192
- sourceModel ( namespace , type , overrides , name , signature , ext , _, _) or
193
- sinkModel ( namespace , type , overrides , name , signature , ext , _, _) or
194
- summaryModel ( namespace , type , overrides , name , signature , ext , _, _, _)
218
+ sourceModel ( namespace , type , subtypes , name , signature , ext , _, _) or
219
+ sinkModel ( namespace , type , subtypes , name , signature , ext , _, _) or
220
+ summaryModel ( namespace , type , subtypes , name , signature , ext , _, _, _)
195
221
}
196
222
197
- bindingset [ namespace, type, overrides ]
198
- private RefType interpretType ( string namespace , string type , boolean overrides ) {
223
+ bindingset [ namespace, type, subtypes ]
224
+ private RefType interpretType ( string namespace , string type , boolean subtypes ) {
199
225
exists ( RefType t |
200
226
t .hasQualifiedName ( namespace , type ) and
201
- if overrides = true then result .getASourceSupertype * ( ) = t else result = t
227
+ if subtypes = true then result .getASourceSupertype * ( ) = t else result = t
202
228
)
203
229
}
204
230
@@ -219,10 +245,10 @@ private string paramsString(Callable c) {
219
245
}
220
246
221
247
private Element interpretElement0 (
222
- string namespace , string type , boolean overrides , string name , string signature
248
+ string namespace , string type , boolean subtypes , string name , string signature
223
249
) {
224
- elementSpec ( namespace , type , overrides , name , signature , _) and
225
- exists ( RefType t | t = interpretType ( namespace , type , overrides ) |
250
+ elementSpec ( namespace , type , subtypes , name , signature , _) and
251
+ exists ( RefType t | t = interpretType ( namespace , type , subtypes ) |
226
252
exists ( Member m |
227
253
result = m and
228
254
m .getDeclaringType ( ) = t and
@@ -240,10 +266,10 @@ private Element interpretElement0(
240
266
}
241
267
242
268
private Element interpretElement (
243
- string namespace , string type , boolean overrides , string name , string signature , string ext
269
+ string namespace , string type , boolean subtypes , string name , string signature , string ext
244
270
) {
245
- elementSpec ( namespace , type , overrides , name , signature , ext ) and
246
- exists ( Element e | e = interpretElement0 ( namespace , type , overrides , name , signature ) |
271
+ elementSpec ( namespace , type , subtypes , name , signature , ext ) and
272
+ exists ( Element e | e = interpretElement0 ( namespace , type , subtypes , name , signature ) |
247
273
ext = "" and result = e
248
274
or
249
275
ext = "Annotated" and result .( Annotatable ) .getAnAnnotation ( ) .getType ( ) = e
@@ -252,28 +278,28 @@ private Element interpretElement(
252
278
253
279
private predicate sourceElement ( Element e , string output , string kind ) {
254
280
exists (
255
- string namespace , string type , boolean overrides , string name , string signature , string ext
281
+ string namespace , string type , boolean subtypes , string name , string signature , string ext
256
282
|
257
- sourceModel ( namespace , type , overrides , name , signature , ext , output , kind ) and
258
- e = interpretElement ( namespace , type , overrides , name , signature , ext )
283
+ sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind ) and
284
+ e = interpretElement ( namespace , type , subtypes , name , signature , ext )
259
285
)
260
286
}
261
287
262
288
private predicate sinkElement ( Element e , string input , string kind ) {
263
289
exists (
264
- string namespace , string type , boolean overrides , string name , string signature , string ext
290
+ string namespace , string type , boolean subtypes , string name , string signature , string ext
265
291
|
266
- sinkModel ( namespace , type , overrides , name , signature , ext , input , kind ) and
267
- e = interpretElement ( namespace , type , overrides , name , signature , ext )
292
+ sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind ) and
293
+ e = interpretElement ( namespace , type , subtypes , name , signature , ext )
268
294
)
269
295
}
270
296
271
297
private predicate summaryElement ( Element e , string input , string output , string kind ) {
272
298
exists (
273
- string namespace , string type , boolean overrides , string name , string signature , string ext
299
+ string namespace , string type , boolean subtypes , string name , string signature , string ext
274
300
|
275
- summaryModel ( namespace , type , overrides , name , signature , ext , input , output , kind ) and
276
- e = interpretElement ( namespace , type , overrides , name , signature , ext )
301
+ summaryModel ( namespace , type , subtypes , name , signature , ext , input , output , kind ) and
302
+ e = interpretElement ( namespace , type , subtypes , name , signature , ext )
277
303
)
278
304
}
279
305
@@ -396,20 +422,32 @@ private predicate interpretInput(string input, int idx, Top ref, TAstOrNode node
396
422
)
397
423
}
398
424
425
+ /**
426
+ * Holds if `node` is specified as a source with the given kind in a CSV flow
427
+ * model.
428
+ */
399
429
predicate sourceNode ( Node node , string kind ) {
400
430
exists ( Top ref , string output |
401
431
sourceElementRef ( ref , output , kind ) and
402
432
interpretOutput ( output , 0 , ref , TNode ( node ) )
403
433
)
404
434
}
405
435
436
+ /**
437
+ * Holds if `node` is specified as a sink with the given kind in a CSV flow
438
+ * model.
439
+ */
406
440
predicate sinkNode ( Node node , string kind ) {
407
441
exists ( Top ref , string input |
408
442
sinkElementRef ( ref , input , kind ) and
409
443
interpretInput ( input , 0 , ref , TNode ( node ) )
410
444
)
411
445
}
412
446
447
+ /**
448
+ * Holds if `node1` to `node2` is specified as a flow step with the given kind
449
+ * in a CSV flow model.
450
+ */
413
451
predicate summaryStep ( Node node1 , Node node2 , string kind ) {
414
452
exists ( Top ref , string input , string output |
415
453
summaryElementRef ( ref , input , output , kind ) and
0 commit comments