Skip to content

Commit 20d4e42

Browse files
committed
Add consistency query (exactly one path for every entity)
1 parent 7174d4c commit 20d4e42

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import semmle.python.internal.OverlayDiscardConsistencyQuery
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Provides consistency queries for checking that every database entity
3+
* that can be discarded (i.e. everything but `@py_cobject`) in an overlay
4+
* database is indeed discarded, by proxy of having exactly one `Discardable.getPath()`.
5+
*/
6+
7+
import python
8+
import semmle.python.Overlay
9+
10+
class TopWithToString instanceof @top {
11+
string getDbType() {
12+
this instanceof @py_source_element and result = "@source_element"
13+
or
14+
this instanceof @py_object and result = "@py_object"
15+
or
16+
this instanceof @py_base_var and result = "@py_base_var"
17+
or
18+
this instanceof @location and result = "@location"
19+
or
20+
this instanceof @py_line and result = "@py_line"
21+
or
22+
this instanceof @py_comment and result = "@py_comment"
23+
or
24+
this instanceof @py_expr_parent and result = "@py_expr_parent"
25+
or
26+
this instanceof @py_expr_context and result = "@py_expr_context"
27+
or
28+
this instanceof @py_operator and result = "@py_operator"
29+
or
30+
this instanceof @py_boolop and result = "@py_boolop"
31+
or
32+
this instanceof @py_cmpop and result = "@py_cmpop"
33+
or
34+
this instanceof @py_unaryop and result = "@py_unaryop"
35+
or
36+
this instanceof @py_cmpop_list and result = "@py_cmpop_list"
37+
or
38+
this instanceof @py_alias_list and result = "@py_alias_list"
39+
or
40+
this instanceof @py_StringPart_list and result = "@py_StringPart_list"
41+
or
42+
this instanceof @py_comprehension_list and result = "@py_comprehension_list"
43+
or
44+
this instanceof @py_dict_item_list and result = "@py_dict_item_list"
45+
or
46+
this instanceof @py_pattern_list and result = "@py_pattern_list"
47+
or
48+
this instanceof @py_stmt_list and result = "@py_stmt_list"
49+
or
50+
this instanceof @py_str_list and result = "@py_str_list"
51+
or
52+
this instanceof @py_type_parameter_list and result = "@py_type_parameter_list"
53+
or
54+
this instanceof @externalDefect and result = "@externalDefect"
55+
or
56+
this instanceof @externalMetric and result = "@externalMetric"
57+
or
58+
this instanceof @externalDataElement and result = "@externalDataElement"
59+
or
60+
this instanceof @duplication_or_similarity and result = "@duplication_or_similarity"
61+
or
62+
this instanceof @svnentry and result = "@svnentry"
63+
or
64+
this instanceof @xmllocatable and result = "@xmllocatable"
65+
or
66+
this instanceof @yaml_locatable and result = "@yaml_locatable"
67+
}
68+
69+
string toString() {
70+
result = this.getDbType()
71+
or
72+
not exists(this.getDbType()) and
73+
result = "Unknown type"
74+
}
75+
}
76+
77+
query predicate consistencyTest(TopWithToString el, string message) {
78+
not el instanceof Discardable and
79+
not el instanceof @py_cobject and // cannot be linked to a path
80+
not el instanceof @externalDataElement and // cannot be linked to a path
81+
message = "Not Discardable"
82+
or
83+
exists(Discardable d, int numPaths | d = el and numPaths = count(d.getPath()) |
84+
numPaths = 0 and
85+
message = "Discardable but no path found"
86+
or
87+
numPaths > 1 and
88+
message = "Discardable but multiple paths found (" + concat(d.getPath(), ", ") + ")"
89+
)
90+
}

0 commit comments

Comments
 (0)