Skip to content

Commit b28b067

Browse files
committed
Overlay.qll: streamline discard predicates down to two
1 parent 2f814c0 commit b28b067

File tree

1 file changed

+10
-254
lines changed

1 file changed

+10
-254
lines changed

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

Lines changed: 10 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -33,227 +33,25 @@ private string getPathForContainer(@container fileOrFolder) {
3333
}
3434

3535
/*- Discardable entities and their discard predicates -*/
36+
/** Python database entities that use named TRAP IDs; the rest use *-ids. */
3637
overlay[local]
37-
private class Discardable_ =
38-
@py_source_element or @py_flow_node or @py_base_var or @location or @py_line or
39-
@py_StringPart_list or @py_alias or @py_alias_list or @py_arguments or @py_boolop or
40-
@py_cmpop or @py_cmpop_list or @py_comprehension_list or @py_dict_item_list or
41-
@py_expr_context or @py_expr_list or @py_operator or @py_parameter_list or @py_pattern_list or
42-
@py_stmt_list or @py_str_list or @py_type_parameter_list or @py_unaryop or @py_comment;
38+
private class NamedEntity = @py_Module or @container or @py_cobject;
4339

4440
overlay[discard_entity]
45-
private predicate discardEntity(@py_source_element el) {
46-
// Within `@py_source_element`, only `@py_Module` and `@container`
47-
// use named IDs; the rest use *-ids.
41+
private predicate discardNamedEntity(@top el) {
42+
el instanceof NamedEntity and
43+
// Entities with named IDs can exist both in base, overlay, or both.
4844
exists(Discardable d | d = el |
4945
overlayChangedFiles(d.getPath()) and
50-
d.existsInBase() and
5146
not d.existsInOverlay()
5247
)
5348
}
5449

5550
overlay[discard_entity]
56-
private predicate discardCfgNode(@py_flow_node n) {
57-
// `@py_flow_node`s use *-ids, so cannot exist both in base and overlay.
58-
exists(Discardable d | d = n |
59-
overlayChangedFiles(d.getPath()) and
60-
d.existsInBase()
61-
)
62-
}
63-
64-
overlay[discard_entity]
65-
private predicate discardVar(@py_base_var n) {
66-
// `@py_base_var`s use *-ids, so cannot exist both in base and overlay.
67-
exists(Discardable d | d = n |
68-
overlayChangedFiles(d.getPath()) and
69-
d.existsInBase()
70-
)
71-
}
72-
73-
overlay[discard_entity]
74-
private predicate discardLocation(@location loc) {
75-
// Locations use *-ids, so cannot exist both in base and overlay.
76-
exists(DiscardableLocation d | d = loc |
77-
overlayChangedFiles(d.getPath()) and
78-
d.existsInBase()
79-
)
80-
}
81-
82-
overlay[discard_entity]
83-
private predicate discardLine(@py_line line) {
84-
// Lines use *-ids, so cannot exist both in base and overlay.
85-
exists(DiscardableLine d | d = line |
86-
overlayChangedFiles(d.getPath()) and
87-
d.existsInBase()
88-
)
89-
}
90-
91-
overlay[discard_entity]
92-
private predicate discardStringPartList(@py_StringPart_list list) {
93-
// String part lists use *-ids, so cannot exist both in base and overlay.
94-
exists(DiscardableStringPartList d | d = list |
95-
overlayChangedFiles(d.getPath()) and
96-
d.existsInBase()
97-
)
98-
}
99-
100-
overlay[discard_entity]
101-
private predicate discardAlias(@py_alias alias) {
102-
// Aliases use *-ids, so cannot exist both in base and overlay.
103-
exists(DiscardableAlias d | d = alias |
104-
overlayChangedFiles(d.getPath()) and
105-
d.existsInBase()
106-
)
107-
}
108-
109-
overlay[discard_entity]
110-
private predicate discardAliasList(@py_alias_list list) {
111-
// Alias lists use *-ids, so cannot exist both in base and overlay.
112-
exists(DiscardableAliasList d | d = list |
113-
overlayChangedFiles(d.getPath()) and
114-
d.existsInBase()
115-
)
116-
}
117-
118-
overlay[discard_entity]
119-
private predicate discardArguments(@py_arguments args) {
120-
// Arguments use *-ids, so cannot exist both in base and overlay.
121-
exists(DiscardableArguments d | d = args |
122-
overlayChangedFiles(d.getPath()) and
123-
d.existsInBase()
124-
)
125-
}
126-
127-
overlay[discard_entity]
128-
private predicate discardBoolOp(@py_boolop op) {
129-
// Boolops use *-ids, so cannot exist both in base and overlay.
130-
exists(DiscardableBoolOp d | d = op |
131-
overlayChangedFiles(d.getPath()) and
132-
d.existsInBase()
133-
)
134-
}
135-
136-
overlay[discard_entity]
137-
private predicate discardCmpOp(@py_cmpop op) {
138-
// Cmpops use *-ids, so cannot exist both in base and overlay.
139-
exists(DiscardableCmpOp d | d = op |
140-
overlayChangedFiles(d.getPath()) and
141-
d.existsInBase()
142-
)
143-
}
144-
145-
overlay[discard_entity]
146-
private predicate discardCmpOpList(@py_cmpop_list list) {
147-
// Cmpop lists use *-ids, so cannot exist both in base and overlay.
148-
exists(DiscardableCmpOpList d | d = list |
149-
overlayChangedFiles(d.getPath()) and
150-
d.existsInBase()
151-
)
152-
}
153-
154-
overlay[discard_entity]
155-
private predicate discardComprehensionList(@py_comprehension_list list) {
156-
// Comprehension lists use *-ids, so cannot exist both in base and overlay.
157-
exists(DiscardableComprehensionList d | d = list |
158-
overlayChangedFiles(d.getPath()) and
159-
d.existsInBase()
160-
)
161-
}
162-
163-
overlay[discard_entity]
164-
private predicate discardDictItemList(@py_dict_item_list list) {
165-
// Dict item lists use *-ids, so cannot exist both in base and overlay.
166-
exists(DiscardableDictItemList d | d = list |
167-
overlayChangedFiles(d.getPath()) and
168-
d.existsInBase()
169-
)
170-
}
171-
172-
overlay[discard_entity]
173-
private predicate discardExprContext(@py_expr_context ctx) {
174-
// Expr contexts use *-ids, so cannot exist both in base and overlay.
175-
exists(DiscardableExprContext d | d = ctx |
176-
overlayChangedFiles(d.getPath()) and
177-
d.existsInBase()
178-
)
179-
}
180-
181-
overlay[discard_entity]
182-
private predicate discardExprList(@py_expr_list list) {
183-
// Expr lists use *-ids, so cannot exist both in base and overlay.
184-
exists(DiscardableExprList d | d = list |
185-
overlayChangedFiles(d.getPath()) and
186-
d.existsInBase()
187-
)
188-
}
189-
190-
overlay[discard_entity]
191-
private predicate discardOperator(@py_operator op) {
192-
// Operators use *-ids, so cannot exist both in base and overlay.
193-
exists(DiscardableOperator d | d = op |
194-
overlayChangedFiles(d.getPath()) and
195-
d.existsInBase()
196-
)
197-
}
198-
199-
overlay[discard_entity]
200-
private predicate discardParameterList(@py_parameter_list list) {
201-
// Parameter lists use *-ids, so cannot exist both in base and overlay.
202-
exists(DiscardableParameterList d | d = list |
203-
overlayChangedFiles(d.getPath()) and
204-
d.existsInBase()
205-
)
206-
}
207-
208-
overlay[discard_entity]
209-
private predicate discardPatternList(@py_pattern_list list) {
210-
// Pattern lists use *-ids, so cannot exist both in base and overlay.
211-
exists(DiscardablePatternList d | d = list |
212-
overlayChangedFiles(d.getPath()) and
213-
d.existsInBase()
214-
)
215-
}
216-
217-
overlay[discard_entity]
218-
private predicate discardStmtList(@py_stmt_list list) {
219-
// Stmt lists use *-ids, so cannot exist both in base and overlay.
220-
exists(DiscardableStmtList d | d = list |
221-
overlayChangedFiles(d.getPath()) and
222-
d.existsInBase()
223-
)
224-
}
225-
226-
overlay[discard_entity]
227-
private predicate discardStrList(@py_str_list list) {
228-
// Str lists use *-ids, so cannot exist both in base and overlay.
229-
exists(DiscardableStrList d | d = list |
230-
overlayChangedFiles(d.getPath()) and
231-
d.existsInBase()
232-
)
233-
}
234-
235-
overlay[discard_entity]
236-
private predicate discardTypeParameterList(@py_type_parameter_list list) {
237-
// Type parameter lists use *-ids, so cannot exist both in base and overlay.
238-
exists(DiscardableTypeParameterList d | d = list |
239-
overlayChangedFiles(d.getPath()) and
240-
d.existsInBase()
241-
)
242-
}
243-
244-
overlay[discard_entity]
245-
private predicate discardUnaryOp(@py_unaryop op) {
246-
// Unaryops use *-ids, so cannot exist both in base and overlay.
247-
exists(DiscardableUnaryOp d | d = op |
248-
overlayChangedFiles(d.getPath()) and
249-
d.existsInBase()
250-
)
251-
}
252-
253-
overlay[discard_entity]
254-
private predicate discardComment(@py_comment c) {
255-
// Comments use *-ids, so cannot exist both in base and overlay.
256-
exists(DiscardableComment d | d = c |
51+
private predicate discardStarEntity(@top el) {
52+
not el instanceof NamedEntity and
53+
// Entities with *-ids can exist either in base or overlay, but not both.
54+
exists(Discardable d | d = el |
25755
overlayChangedFiles(d.getPath()) and
25856
d.existsInBase()
25957
)
@@ -263,7 +61,7 @@ private predicate discardComment(@py_comment c) {
26361
* An abstract base class for all elements that can be discarded from the base.
26462
*/
26563
overlay[local]
266-
abstract private class Discardable extends Discardable_ {
64+
abstract private class Discardable extends @top {
26765
/** Gets the path to the file in which this element occurs. */
26866
abstract string getPath();
26967

@@ -564,45 +362,3 @@ private predicate discardBaseYamlLocatable(@yaml_locatable el) {
564362
// should be discarded.
565363
baseYamlLocatable(el) and overlayHasYamlLocatable()
566364
}
567-
///////////////////////////////////////////////////////////////////////////////
568-
// predicate locations_default_withoutPath(@location_default x) { not exists(x.(Discardable).getPath()) }
569-
// predicate locations_ast_withoutPath(@location_ast x) { not exists(x.(Discardable).getPath()) }
570-
// predicate files_withoutPath(@file x) { not exists(x.(Discardable).getPath()) }
571-
// predicate folders_withoutPath(@folder x) { not exists(x.(Discardable).getPath()) }
572-
// predicate variable_withoutPath(@py_variable x) { not exists(x.(Discardable).getPath()) }
573-
// predicate py_line_lengths_withoutPath(@py_line x) { not exists(x.(Discardable).getPath()) }
574-
// predicate py_Classes_withoutPath(@py_Class x) { not exists(x.(Discardable).getPath()) }
575-
// predicate py_Functions_withoutPath(@py_Function x) { not exists(x.(Discardable).getPath()) }
576-
// predicate py_Modules_withoutPath(@py_Module x) { not exists(x.(Discardable).getPath()) }
577-
// predicate py_StringPart_withoutPath(@py_StringPart x) { not exists(x.(Discardable).getPath()) }
578-
// predicate py_StringPart_lists_withoutPath(@py_StringPart_list x) { not exists(x.(Discardable).getPath()) }
579-
// predicate py_aliases_withoutPath(@py_alias x) { not exists(x.(Discardable).getPath()) }
580-
// predicate py_alias_lists_withoutPath(@py_alias_list x) { not exists(x.(Discardable).getPath()) }
581-
// predicate py_arguments_withoutPath(@py_arguments x) { not exists(x.(Discardable).getPath()) }
582-
// predicate py_boolops_withoutPath(@py_boolop x) { not exists(x.(Discardable).getPath()) }
583-
// predicate py_cmpops_withoutPath(@py_cmpop x) { not exists(x.(Discardable).getPath()) }
584-
// predicate py_cmpop_lists_withoutPath(@py_cmpop_list x) { not exists(x.(Discardable).getPath()) }
585-
// predicate py_comprehensions_withoutPath(@py_comprehension x) { not exists(x.(Discardable).getPath()) }
586-
// predicate py_comprehension_lists_withoutPath(@py_comprehension_list x) { not exists(x.(Discardable).getPath()) }
587-
// predicate py_dict_item_withoutPath(@py_dict_item x) { not exists(x.(Discardable).getPath()) }
588-
// predicate py_dict_item_lists_withoutPath(@py_dict_item_list x) { not exists(x.(Discardable).getPath()) }
589-
// predicate py_exprs_withoutPath(@py_expr x) { not exists(x.(Discardable).getPath()) }
590-
// predicate py_expr_contexts_withoutPath(@py_expr_context x) { not exists(x.(Discardable).getPath()) }
591-
// predicate py_expr_lists_withoutPath(@py_expr_list x) { not exists(x.(Discardable).getPath()) }
592-
// predicate py_operators_withoutPath(@py_operator x) { not exists(x.(Discardable).getPath()) }
593-
// predicate py_parameter_lists_withoutPath(@py_parameter_list x) { not exists(x.(Discardable).getPath()) }
594-
// predicate py_patterns_withoutPath(@py_pattern x) { not exists(x.(Discardable).getPath()) }
595-
// predicate py_pattern_lists_withoutPath(@py_pattern_list x) { not exists(x.(Discardable).getPath()) }
596-
// predicate py_stmts_withoutPath(@py_stmt x) { not exists(x.(Discardable).getPath()) }
597-
// predicate py_stmt_lists_withoutPath(@py_stmt_list x) { not exists(x.(Discardable).getPath()) }
598-
// predicate py_str_lists_withoutPath(@py_str_list x) { not exists(x.(Discardable).getPath()) }
599-
// predicate py_type_parameters_withoutPath(@py_type_parameter x) { not exists(x.(Discardable).getPath()) }
600-
// predicate py_type_parameter_lists_withoutPath(@py_type_parameter_list x) { not exists(x.(Discardable).getPath()) }
601-
// predicate py_unaryops_withoutPath(@py_unaryop x) { not exists(x.(Discardable).getPath()) }
602-
// predicate py_flow_bb_node_withoutPath(@py_flow_node x) { not exists(x.(Discardable).getPath()) }
603-
// predicate py_ssa_var_withoutPath(@py_ssa_var x) { not exists(x.(Discardable).getPath()) }
604-
// predicate py_comments_withoutPath(@py_comment x) { not exists(x.(Discardable).getPath()) }
605-
// predicate py_source_element_withoutPath(@py_source_element x) { not exists(x.(Discardable).getPath()) }
606-
// predicate py_flow_node_withoutPath(@py_flow_node x) { not exists(x.(Discardable).getPath()) }
607-
// predicate py_base_var_withoutPath(@py_base_var x) { not exists(x.(Discardable).getPath()) }
608-
// predicate py_location_withoutPath(@location x) { not exists(x.(Discardable).getPath()) }

0 commit comments

Comments
 (0)