|
5 | 5 | * |
6 | 6 | * The CSV specification has the following columns: |
7 | 7 | * - Sources: |
8 | | - * `namespace; type; subtypes; name; signature; ext; output; kind` |
| 8 | + * `namespace; type; subtypes; name; signature; ext; output; kind; provenance` |
9 | 9 | * - Sinks: |
10 | | - * `namespace; type; subtypes; name; signature; ext; input; kind` |
| 10 | + * `namespace; type; subtypes; name; signature; ext; input; kind; provenance` |
11 | 11 | * - Summaries: |
12 | | - * `namespace; type; subtypes; name; signature; ext; input; output; kind` |
| 12 | + * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance` |
| 13 | + * - Negative Summaries: |
| 14 | + * `namespace; type; name; signature; provenance` |
13 | 15 | * |
14 | 16 | * The interpretation of a row is similar to API-graphs with a left-to-right |
15 | 17 | * reading. |
@@ -182,6 +184,16 @@ class SummaryModelCsv extends Unit { |
182 | 184 | abstract predicate row(string row); |
183 | 185 | } |
184 | 186 |
|
| 187 | +/** |
| 188 | + * A unit class for adding negative summary model rows. |
| 189 | + * |
| 190 | + * Extend this class to add additional flow summary definitions. |
| 191 | + */ |
| 192 | +class NegativeSummaryModelCsv extends Unit { |
| 193 | + /** Holds if `row` specifies a negative summary definition. */ |
| 194 | + abstract predicate row(string row); |
| 195 | +} |
| 196 | + |
185 | 197 | private class SourceModelCsvBase extends SourceModelCsv { |
186 | 198 | override predicate row(string row) { |
187 | 199 | row = |
@@ -422,6 +434,8 @@ private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) } |
422 | 434 |
|
423 | 435 | private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } |
424 | 436 |
|
| 437 | +private predicate negativeSummaryModel(string row) { any(NegativeSummaryModelCsv s).row(row) } |
| 438 | + |
425 | 439 | /** Holds if a source model exists for the given parameters. */ |
426 | 440 | predicate sourceModel( |
427 | 441 | string namespace, string type, boolean subtypes, string name, string signature, string ext, |
@@ -489,6 +503,20 @@ predicate summaryModel( |
489 | 503 | row.splitAt(";", 9) = provenance |
490 | 504 | } |
491 | 505 |
|
| 506 | +/** Holds is a summary model exists indicating there is no flow for the given parameters. */ |
| 507 | +predicate negativeSummaryModel( |
| 508 | + string namespace, string type, string name, string signature, string provenance |
| 509 | +) { |
| 510 | + exists(string row | |
| 511 | + negativeSummaryModel(row) and |
| 512 | + row.splitAt(";", 0) = namespace and |
| 513 | + row.splitAt(";", 1) = type and |
| 514 | + row.splitAt(";", 2) = name and |
| 515 | + row.splitAt(";", 3) = signature and |
| 516 | + row.splitAt(";", 4) = provenance |
| 517 | + ) |
| 518 | +} |
| 519 | + |
492 | 520 | private predicate relevantPackage(string package) { |
493 | 521 | sourceModel(package, _, _, _, _, _, _, _, _) or |
494 | 522 | sinkModel(package, _, _, _, _, _, _, _, _) or |
@@ -557,6 +585,10 @@ module CsvValidation { |
557 | 585 | or |
558 | 586 | summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and |
559 | 587 | pred = "summary" |
| 588 | + or |
| 589 | + negativeSummaryModel(namespace, type, name, signature, provenance) and |
| 590 | + ext = "" and |
| 591 | + pred = "nonesummary" |
560 | 592 | | |
561 | 593 | not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and |
562 | 594 | msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model." |
@@ -660,9 +692,13 @@ pragma[nomagic] |
660 | 692 | private predicate elementSpec( |
661 | 693 | string namespace, string type, boolean subtypes, string name, string signature, string ext |
662 | 694 | ) { |
663 | | - sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or |
664 | | - sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or |
| 695 | + sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) |
| 696 | + or |
| 697 | + sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) |
| 698 | + or |
665 | 699 | summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) |
| 700 | + or |
| 701 | + negativeSummaryModel(namespace, type, name, signature, _) and ext = "" and subtypes = false |
666 | 702 | } |
667 | 703 |
|
668 | 704 | private string paramsStringPart(Callable c, int i) { |
@@ -711,7 +747,7 @@ private Element interpretElement0( |
711 | 747 | ) |
712 | 748 | } |
713 | 749 |
|
714 | | -/** Gets the source/sink/summary element corresponding to the supplied parameters. */ |
| 750 | +/** Gets the source/sink/summary/negativesummary element corresponding to the supplied parameters. */ |
715 | 751 | Element interpretElement( |
716 | 752 | string namespace, string type, boolean subtypes, string name, string signature, string ext |
717 | 753 | ) { |
|
0 commit comments