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+
17import java
28private import semmle.code.java.dataflow.DataFlow:: DataFlow
39private import internal.DataFlowPrivate
@@ -32,15 +38,33 @@ private predicate sinkModelCsv(string row) { none() }
3238
3339private predicate summaryModelCsv ( string row ) { none ( ) }
3440
41+ /**
42+ * A unit class for adding additional source model rows.
43+ *
44+ * Extend this class to add additional source definitions.
45+ */
3546class SourceModelCsv extends Unit {
47+ /** Holds if `row` specifies a source definition. */
3648 abstract predicate row ( string row ) ;
3749}
3850
51+ /**
52+ * A unit class for adding additional sink model rows.
53+ *
54+ * Extend this class to add additional sink definitions.
55+ */
3956class SinkModelCsv extends Unit {
57+ /** Holds if `row` specifies a sink definition. */
4058 abstract predicate row ( string row ) ;
4159}
4260
61+ /**
62+ * A unit class for adding additional summary model rows.
63+ *
64+ * Extend this class to add additional flow summary definitions.
65+ */
4366class SummaryModelCsv extends Unit {
67+ /** Holds if `row` specifies a summary definition. */
4468 abstract predicate row ( string row ) ;
4569}
4670
@@ -60,15 +84,15 @@ private predicate summaryModel(string row) {
6084}
6185
6286private 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 ,
6488 string output , string kind
6589) {
6690 exists ( string row |
6791 sourceModel ( row ) and
6892 row .splitAt ( ";" , 0 ) = namespace and
6993 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
7296 row .splitAt ( ";" , 3 ) = name and
7397 row .splitAt ( ";" , 4 ) = signature and
7498 row .splitAt ( ";" , 5 ) = ext and
@@ -78,15 +102,15 @@ private predicate sourceModel(
78102}
79103
80104private 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 ,
82106 string input , string kind
83107) {
84108 exists ( string row |
85109 sinkModel ( row ) and
86110 row .splitAt ( ";" , 0 ) = namespace and
87111 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
90114 row .splitAt ( ";" , 3 ) = name and
91115 row .splitAt ( ";" , 4 ) = signature and
92116 row .splitAt ( ";" , 5 ) = ext and
@@ -96,15 +120,15 @@ private predicate sinkModel(
96120}
97121
98122private 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 ,
100124 string input , string output , string kind
101125) {
102126 exists ( string row |
103127 summaryModel ( row ) and
104128 row .splitAt ( ";" , 0 ) = namespace and
105129 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
108132 row .splitAt ( ";" , 3 ) = name and
109133 row .splitAt ( ";" , 4 ) = signature and
110134 row .splitAt ( ";" , 5 ) = ext and
@@ -114,7 +138,9 @@ private predicate summaryModel(
114138 )
115139}
116140
141+ /** Provides a query predicate to check the CSV data for validation errors. */
117142module CsvValidation {
143+ /** Holds if some row in a CSV-based flow model appears to contain typos. */
118144 query predicate invalidModelRow ( string msg ) {
119145 exists ( string pred , string namespace , string type , string name , string signature , string ext |
120146 sourceModel ( namespace , type , _, name , signature , ext , _, _) and pred = "source"
@@ -187,18 +213,18 @@ module CsvValidation {
187213}
188214
189215private 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
191217) {
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 , _, _, _)
195221}
196222
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 ) {
199225 exists ( RefType t |
200226 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
202228 )
203229}
204230
@@ -219,10 +245,10 @@ private string paramsString(Callable c) {
219245}
220246
221247private Element interpretElement0 (
222- string namespace , string type , boolean overrides , string name , string signature
248+ string namespace , string type , boolean subtypes , string name , string signature
223249) {
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 ) |
226252 exists ( Member m |
227253 result = m and
228254 m .getDeclaringType ( ) = t and
@@ -240,10 +266,10 @@ private Element interpretElement0(
240266}
241267
242268private 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
244270) {
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 ) |
247273 ext = "" and result = e
248274 or
249275 ext = "Annotated" and result .( Annotatable ) .getAnAnnotation ( ) .getType ( ) = e
@@ -252,28 +278,28 @@ private Element interpretElement(
252278
253279private predicate sourceElement ( Element e , string output , string kind ) {
254280 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
256282 |
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 )
259285 )
260286}
261287
262288private predicate sinkElement ( Element e , string input , string kind ) {
263289 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
265291 |
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 )
268294 )
269295}
270296
271297private predicate summaryElement ( Element e , string input , string output , string kind ) {
272298 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
274300 |
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 )
277303 )
278304}
279305
@@ -396,20 +422,32 @@ private predicate interpretInput(string input, int idx, Top ref, TAstOrNode node
396422 )
397423}
398424
425+ /**
426+ * Holds if `node` is specified as a source with the given kind in a CSV flow
427+ * model.
428+ */
399429predicate sourceNode ( Node node , string kind ) {
400430 exists ( Top ref , string output |
401431 sourceElementRef ( ref , output , kind ) and
402432 interpretOutput ( output , 0 , ref , TNode ( node ) )
403433 )
404434}
405435
436+ /**
437+ * Holds if `node` is specified as a sink with the given kind in a CSV flow
438+ * model.
439+ */
406440predicate sinkNode ( Node node , string kind ) {
407441 exists ( Top ref , string input |
408442 sinkElementRef ( ref , input , kind ) and
409443 interpretInput ( input , 0 , ref , TNode ( node ) )
410444 )
411445}
412446
447+ /**
448+ * Holds if `node1` to `node2` is specified as a flow step with the given kind
449+ * in a CSV flow model.
450+ */
413451predicate summaryStep ( Node node1 , Node node2 , string kind ) {
414452 exists ( Top ref , string input , string output |
415453 summaryElementRef ( ref , input , output , kind ) and
0 commit comments