@@ -101,9 +101,10 @@ private import internal.FlowSummaryImpl
101101private import internal.FlowSummaryImpl:: Public
102102private import internal.FlowSummaryImpl:: Private
103103private import internal.FlowSummaryImpl:: Private:: External
104- private import internal.ExternalFlowExtensions as Extensions
104+ private import internal.ExternalFlowExtensions:: Extensions as Extensions
105105private import codeql.mad.ModelValidation as SharedModelVal
106106private import codeql.util.Unit
107+ private import codeql.mad.static.ModelsAsData as SharedMaD
107108
108109/**
109110 * A unit class for adding additional source model rows.
@@ -144,135 +145,82 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
144145/** Holds if `row` is a summary model. */
145146predicate summaryModel ( string row ) { any ( SummaryModelCsv s ) .row ( row ) }
146147
147- /** Holds if a source model exists for the given parameters. */
148- predicate sourceModel (
149- string namespace , string type , boolean subtypes , string name , string signature , string ext ,
150- string output , string kind , string provenance , string model
151- ) {
152- exists ( string row |
153- sourceModel ( row ) and
154- row .splitAt ( ";" , 0 ) = namespace and
155- row .splitAt ( ";" , 1 ) = type and
156- row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
157- subtypes = [ true , false ] and
158- row .splitAt ( ";" , 3 ) = name and
159- row .splitAt ( ";" , 4 ) = signature and
160- row .splitAt ( ";" , 5 ) = ext and
161- row .splitAt ( ";" , 6 ) = output and
162- row .splitAt ( ";" , 7 ) = kind
163- ) and
164- provenance = "manual" and
165- model = ""
166- or
167- exists ( QlBuiltins:: ExtensionId madId |
168- Extensions:: sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind ,
169- provenance , madId ) and
170- model = "MaD:" + madId .toString ( )
171- )
172- }
173-
174- /** Holds if a sink model exists for the given parameters. */
175- predicate sinkModel (
176- string namespace , string type , boolean subtypes , string name , string signature , string ext ,
177- string input , string kind , string provenance , string model
178- ) {
179- exists ( string row |
180- sinkModel ( row ) and
181- row .splitAt ( ";" , 0 ) = namespace and
182- row .splitAt ( ";" , 1 ) = type and
183- row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
184- subtypes = [ true , false ] and
185- row .splitAt ( ";" , 3 ) = name and
186- row .splitAt ( ";" , 4 ) = signature and
187- row .splitAt ( ";" , 5 ) = ext and
188- row .splitAt ( ";" , 6 ) = input and
189- row .splitAt ( ";" , 7 ) = kind
190- ) and
191- provenance = "manual" and
192- model = ""
193- or
194- exists ( QlBuiltins:: ExtensionId madId |
195- Extensions:: sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind , provenance ,
196- madId ) and
197- model = "MaD:" + madId .toString ( )
198- )
199- }
200-
201- /**
202- * Holds if a summary model exists for the given parameters.
203- *
204- * This predicate does not expand `@` to `*`s.
205- */
206- private predicate summaryModel0 (
207- string namespace , string type , boolean subtypes , string name , string signature , string ext ,
208- string input , string output , string kind , string provenance , string model
209- ) {
210- exists ( string row |
211- summaryModel ( row ) and
212- row .splitAt ( ";" , 0 ) = namespace and
213- row .splitAt ( ";" , 1 ) = type and
214- row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
215- subtypes = [ true , false ] and
216- row .splitAt ( ";" , 3 ) = name and
217- row .splitAt ( ";" , 4 ) = signature and
218- row .splitAt ( ";" , 5 ) = ext and
219- row .splitAt ( ";" , 6 ) = input and
220- row .splitAt ( ";" , 7 ) = output and
221- row .splitAt ( ";" , 8 ) = kind
222- ) and
223- provenance = "manual" and
224- model = ""
225- or
226- exists ( QlBuiltins:: ExtensionId madId |
227- Extensions:: summaryModel ( namespace , type , subtypes , name , signature , ext , input , output , kind ,
228- provenance , madId ) and
229- model = "MaD:" + madId .toString ( )
230- )
231- }
232-
233- /**
234- * Holds if the given extension tuple `madId` should pretty-print as `model`.
235- *
236- * This predicate should only be used in tests.
237- */
238- predicate interpretModelForTest ( QlBuiltins:: ExtensionId madId , string model ) {
239- exists (
148+ private module MadInput implements SharedMaD:: InputSig {
149+ /** Holds if a source model exists for the given parameters. */
150+ predicate additionalSourceModel (
240151 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
241- string output , string kind , string provenance
242- |
243- Extensions:: sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind ,
244- provenance , madId )
245- |
246- model =
247- "Source: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; "
248- + ext + "; " + output + "; " + kind + "; " + provenance
249- )
250- or
251- exists (
152+ string output , string kind , string provenance , string model
153+ ) {
154+ exists ( string row |
155+ sourceModel ( row ) and
156+ row .splitAt ( ";" , 0 ) = namespace and
157+ row .splitAt ( ";" , 1 ) = type and
158+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
159+ subtypes = [ true , false ] and
160+ row .splitAt ( ";" , 3 ) = name and
161+ row .splitAt ( ";" , 4 ) = signature and
162+ row .splitAt ( ";" , 5 ) = ext and
163+ row .splitAt ( ";" , 6 ) = output and
164+ row .splitAt ( ";" , 7 ) = kind
165+ ) and
166+ provenance = "manual" and
167+ model = ""
168+ }
169+
170+ /** Holds if a sink model exists for the given parameters. */
171+ predicate additionalSinkModel (
252172 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
253- string input , string kind , string provenance
254- |
255- Extensions:: sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind , provenance ,
256- madId )
257- |
258- model =
259- "Sink: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " +
260- ext + "; " + input + "; " + kind + "; " + provenance
261- )
262- or
263- exists (
173+ string input , string kind , string provenance , string model
174+ ) {
175+ exists ( string row |
176+ sinkModel ( row ) and
177+ row .splitAt ( ";" , 0 ) = namespace and
178+ row .splitAt ( ";" , 1 ) = type and
179+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
180+ subtypes = [ true , false ] and
181+ row .splitAt ( ";" , 3 ) = name and
182+ row .splitAt ( ";" , 4 ) = signature and
183+ row .splitAt ( ";" , 5 ) = ext and
184+ row .splitAt ( ";" , 6 ) = input and
185+ row .splitAt ( ";" , 7 ) = kind
186+ ) and
187+ provenance = "manual" and
188+ model = ""
189+ }
190+
191+ /**
192+ * Holds if a summary model exists for the given parameters.
193+ *
194+ * This predicate does not expand `@` to `*`s.
195+ */
196+ predicate additionalSummaryModel (
264197 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
265- string input , string output , string kind , string provenance
266- |
267- Extensions:: summaryModel ( namespace , type , subtypes , name , signature , ext , input , output , kind ,
268- provenance , madId )
269- |
270- model =
271- "Summary: " + namespace + "; " + type + "; " + subtypes + "; " + name + "; " + signature +
272- "; " + ext + "; " + input + "; " + output + "; " + kind + "; " + provenance
273- )
198+ string input , string output , string kind , string provenance , string model
199+ ) {
200+ exists ( string row |
201+ summaryModel ( row ) and
202+ row .splitAt ( ";" , 0 ) = namespace and
203+ row .splitAt ( ";" , 1 ) = type and
204+ row .splitAt ( ";" , 2 ) = subtypes .toString ( ) and
205+ subtypes = [ true , false ] and
206+ row .splitAt ( ";" , 3 ) = name and
207+ row .splitAt ( ";" , 4 ) = signature and
208+ row .splitAt ( ";" , 5 ) = ext and
209+ row .splitAt ( ";" , 6 ) = input and
210+ row .splitAt ( ";" , 7 ) = output and
211+ row .splitAt ( ";" , 8 ) = kind
212+ ) and
213+ provenance = "manual" and
214+ model = ""
215+ }
216+
217+ string namespaceSegmentSeparator ( ) { result = "::" }
274218}
275219
220+ private module MaD = SharedMaD:: ModelsAsData< Extensions , MadInput > ;
221+
222+ import MaD
223+
276224/**
277225 * Holds if `input` is `input0`, but with all occurrences of `@` replaced
278226 * by `n` repetitions of `*` (and similarly for `output` and `output0`).
@@ -294,69 +242,13 @@ predicate summaryModel(
294242 string input , string output , string kind , string provenance , string model
295243) {
296244 exists ( string input0 , string output0 |
297- summaryModel0 ( namespace , type , subtypes , name , signature , ext , input0 , output0 , kind ,
245+ MaD :: summaryModel ( namespace , type , subtypes , name , signature , ext , input0 , output0 , kind ,
298246 provenance , model ) and
299247 expandInputAndOutput ( input0 , input , output0 , output ,
300248 [ 0 .. Private:: getMaxElementContentIndirectionIndex ( ) - 1 ] )
301249 )
302250}
303251
304- private predicate relevantNamespace ( string namespace ) {
305- sourceModel ( namespace , _, _, _, _, _, _, _, _, _) or
306- sinkModel ( namespace , _, _, _, _, _, _, _, _, _) or
307- summaryModel ( namespace , _, _, _, _, _, _, _, _, _, _)
308- }
309-
310- private predicate namespaceLink ( string shortns , string longns ) {
311- relevantNamespace ( shortns ) and
312- relevantNamespace ( longns ) and
313- longns .prefix ( longns .indexOf ( "::" ) ) = shortns
314- }
315-
316- private predicate canonicalNamespace ( string namespace ) {
317- relevantNamespace ( namespace ) and not namespaceLink ( _, namespace )
318- }
319-
320- private predicate canonicalNamespaceLink ( string namespace , string subns ) {
321- canonicalNamespace ( namespace ) and
322- ( subns = namespace or namespaceLink ( namespace , subns ) )
323- }
324-
325- /**
326- * Holds if MaD framework coverage of `namespace` is `n` api endpoints of the
327- * kind `(kind, part)`, and `namespaces` is the number of subnamespaces of
328- * `namespace` which have MaD framework coverage (including `namespace`
329- * itself).
330- */
331- predicate modelCoverage ( string namespace , int namespaces , string kind , string part , int n ) {
332- namespaces = strictcount ( string subns | canonicalNamespaceLink ( namespace , subns ) ) and
333- (
334- part = "source" and
335- n =
336- strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
337- string ext , string output , string provenance , string model |
338- canonicalNamespaceLink ( namespace , subns ) and
339- sourceModel ( subns , type , subtypes , name , signature , ext , output , kind , provenance , model )
340- )
341- or
342- part = "sink" and
343- n =
344- strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
345- string ext , string input , string provenance , string model |
346- canonicalNamespaceLink ( namespace , subns ) and
347- sinkModel ( subns , type , subtypes , name , signature , ext , input , kind , provenance , model )
348- )
349- or
350- part = "summary" and
351- n =
352- strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
353- string ext , string input , string output , string provenance |
354- canonicalNamespaceLink ( namespace , subns ) and
355- summaryModel ( subns , type , subtypes , name , signature , ext , input , output , kind , provenance , _)
356- )
357- )
358- }
359-
360252/** Provides a query predicate to check the CSV data for validation errors. */
361253module CsvValidation {
362254 private string getInvalidModelInput ( ) {
0 commit comments