Skip to content

Commit afb78e3

Browse files
committed
Add consistency query (exactly one path for every entity)
1 parent cde31c2 commit afb78e3

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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 ToString instanceof @top {
11+
string toString() {
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+
70+
from @top el, string message
71+
where
72+
not el instanceof Discardable and
73+
not el instanceof @py_cobject and
74+
message = "Not Discardable"
75+
or
76+
exists(Discardable d, int numPaths | d = el and numPaths = count(d.getPath()) |
77+
numPaths = 0 and
78+
message = "Discardable but no path found"
79+
or
80+
numPaths > 1 and
81+
message = "Discardable but multiple paths found (" + concat(d.getPath(), ", ") + ")"
82+
)
83+
select el.(ToString), message

python/ql/lib/semmle/python/Overlay.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private predicate discardStarEntity(@top el) {
6161
* An abstract base class for all elements that can be discarded from the base.
6262
*/
6363
overlay[local]
64-
abstract private class Discardable extends @top {
64+
abstract class Discardable extends @top {
6565
/** Gets the path to the file in which this element occurs. */
6666
abstract string getPath();
6767

0 commit comments

Comments
 (0)