@@ -14,30 +14,54 @@ overlay[local]
1414predicate isOverlay ( ) { databaseMetadata ( "isOverlay" , "true" ) }
1515
1616overlay [ local]
17- private string getRawPathForLocation ( @location loc ) {
17+ private string getPathForLocation ( @location loc ) {
1818 exists ( @file file | locations_default ( loc , file , _, _, _, _) | files ( file , result ) )
1919 or
20- exists ( @py_Module mod | locations_ast ( loc , mod , _, _, _, _) | result = getRawPathForModule ( mod ) )
20+ exists ( @py_Module mod | locations_ast ( loc , mod , _, _, _, _) | result = getPathForModule ( mod ) )
2121}
2222
2323overlay [ local]
24- private string getRawPathForModule ( @py_Module mod ) {
24+ private string getPathForModule ( @py_Module mod ) {
2525 exists ( @container fileOrFolder | py_module_path ( mod , fileOrFolder ) |
26- result = getRawPathForContainer ( fileOrFolder )
26+ result = getPathForContainer ( fileOrFolder )
2727 )
2828}
2929
3030overlay [ local]
31- private string getRawPathForContainer ( @container fileOrFolder ) {
31+ private string getPathForContainer ( @container fileOrFolder ) {
3232 files ( fileOrFolder , result ) or folders ( fileOrFolder , result )
3333}
3434
35- /*- Source elements -*/
35+ /*- Discardable entities and their discard predicates -*/
36+ /** Python database entities that use named TRAP IDs; the rest use *-ids. */
37+ overlay [ local]
38+ private class NamedEntity = @py_Module or @container or @py_cobject;
39+
40+ overlay [ discard_entity]
41+ private predicate discardNamedEntity ( @top el ) {
42+ el instanceof NamedEntity and
43+ // Entities with named IDs can exist both in base, overlay, or both.
44+ exists ( Discardable d | d = el |
45+ overlayChangedFiles ( d .getPath ( ) ) and
46+ not d .existsInOverlay ( )
47+ )
48+ }
49+
50+ overlay [ discard_entity]
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 |
55+ overlayChangedFiles ( d .getPath ( ) ) and
56+ d .existsInBase ( )
57+ )
58+ }
59+
3660/**
3761 * An abstract base class for all elements that can be discarded from the base.
3862 */
3963overlay [ local]
40- abstract private class Discardable extends @py_source_element {
64+ abstract private class Discardable extends @top {
4165 /** Gets the path to the file in which this element occurs. */
4266 abstract string getPath ( ) ;
4367
@@ -51,98 +75,51 @@ abstract private class Discardable extends @py_source_element {
5175 string toString ( ) { none ( ) }
5276}
5377
54- overlay [ discard_entity]
55- private predicate discardEntity ( @py_source_element el ) {
56- exists ( Discardable d | d = el |
57- overlayChangedFiles ( d .getPath ( ) ) and
58- d .existsInBase ( ) and
59- not d .existsInOverlay ( )
60- )
61- }
62-
6378/**
64- * Discard all locatable AST nodes (`@py_location_parent`) in modified files
65- * since they use *-ids and hence cannot be referenced across TRAP files.
79+ * Discardable locatable AST nodes (`@py_location_parent`).
6680 */
6781overlay [ local]
6882final private class DiscardableLocatable extends Discardable instanceof @py_location_parent {
6983 override string getPath ( ) {
70- exists ( @location loc | py_locations ( loc , this ) | result = getRawPathForLocation ( loc ) )
84+ exists ( @location loc | py_locations ( loc , this ) | result = getPathForLocation ( loc ) )
7185 }
7286}
7387
7488/**
75- * Discard scopes (classes, functions, modules) that were deleted in the overlay .
89+ * Discardable scopes (classes, functions, modules).
7690 */
7791overlay [ local]
7892final private class DiscardableScope extends Discardable instanceof @py_scope {
7993 override string getPath ( ) {
80- exists ( @location loc | py_scope_location ( loc , this ) | result = getRawPathForLocation ( loc ) )
94+ exists ( @location loc | py_scope_location ( loc , this ) | result = getPathForLocation ( loc ) )
8195 or
82- result = getRawPathForModule ( this )
96+ result = getPathForModule ( this )
8397 }
8498}
8599
86100/**
87- * Discard files and folders that were deleted in the overlay .
101+ * Discardable files and folders.
88102 */
89103overlay [ local]
90104final private class DiscardableContainer extends Discardable instanceof @container {
91- override string getPath ( ) { result = getRawPathForContainer ( this ) }
105+ override string getPath ( ) { result = getPathForContainer ( this ) }
92106}
93107
94- /*- CFG Nodes -*/
95108/** Discardable control flow nodes */
96109overlay [ local]
97- final private class DiscardableCfgNode instanceof @py_flow_node {
98- string getPath ( ) {
110+ final private class DiscardableCfgNode extends Discardable instanceof @py_flow_node {
111+ override string getPath ( ) {
99112 exists ( Discardable d | result = d .getPath ( ) |
100113 py_flow_bb_node ( this , d .( @py_ast_node) , _, _)
101114 or
102115 py_scope_flow ( this , d .( @py_scope) , _)
103116 )
104117 }
105-
106- predicate existsInBase ( ) { not isOverlay ( ) and exists ( this ) }
107-
108- predicate existsInOverlay ( ) { isOverlay ( ) and exists ( this ) }
109-
110- string toString ( ) { none ( ) }
111- }
112-
113- overlay [ discard_entity]
114- private predicate discardCfgNode ( @py_flow_node n ) {
115- exists ( DiscardableCfgNode d | d = n |
116- overlayChangedFiles ( d .getPath ( ) ) and
117- d .existsInBase ( ) and
118- not d .existsInOverlay ( )
119- )
120118}
121119
122- /*- Variables -*/
123- /** Discardable (normal and SSA) variables */
120+ /** Discardable Python variables. */
124121overlay [ local]
125- abstract private class DiscardableBaseVar instanceof @py_base_var {
126- abstract string getPath ( ) ;
127-
128- predicate existsInBase ( ) { not isOverlay ( ) and exists ( this ) }
129-
130- predicate existsInOverlay ( ) { isOverlay ( ) and exists ( this ) }
131-
132- string toString ( ) { none ( ) }
133- }
134-
135- overlay [ discard_entity]
136- private predicate discardVar ( @py_base_var n ) {
137- exists ( DiscardableVar d | d = n |
138- overlayChangedFiles ( d .getPath ( ) ) and
139- d .existsInBase ( ) and
140- not d .existsInOverlay ( )
141- )
142- }
143-
144- overlay [ local]
145- final private class DiscardableVar extends DiscardableBaseVar instanceof @py_variable {
122+ final private class DiscardableVar extends Discardable instanceof @py_variable {
146123 override string getPath ( ) {
147124 exists ( Discardable parent | result = parent .getPath ( ) |
148125 variable ( this , parent .( @py_scope) , _)
@@ -152,8 +129,9 @@ final private class DiscardableVar extends DiscardableBaseVar instanceof @py_var
152129 }
153130}
154131
132+ /** Discardable SSA variables. */
155133overlay [ local]
156- final private class DiscardableSsaVar extends DiscardableBaseVar instanceof @py_ssa_var {
134+ final private class DiscardableSsaVar extends Discardable instanceof @py_ssa_var {
157135 override string getPath ( ) {
158136 exists ( DiscardableSsaVar other | result = other .getPath ( ) |
159137 py_ssa_phi ( this , other .( @py_ssa_var) )
@@ -169,18 +147,180 @@ final private class DiscardableSsaVar extends DiscardableBaseVar instanceof @py_
169147 }
170148}
171149
172- /*- Locations - */
150+ /** Discardable locations. */
173151overlay [ local]
174- private predicate locationExistsInBase ( @location loc ) { not isOverlay ( ) and exists ( loc ) }
152+ final private class DiscardableLocation extends Discardable instanceof @location {
153+ override string getPath ( ) { result = getPathForLocation ( this ) }
154+ }
175155
156+ /** Discardable lines. */
176157overlay [ local]
177- private predicate locationExistsInOverlay ( @location loc ) { isOverlay ( ) and exists ( loc ) }
158+ final private class DiscardableLine extends Discardable instanceof @py_line {
159+ override string getPath ( ) {
160+ exists ( Discardable d | result = d .getPath ( ) | py_line_lengths ( this , d .( @py_Module) , _, _) )
161+ }
162+ }
178163
179- overlay [ discard_entity]
180- private predicate discardLocation ( @location loc ) {
181- overlayChangedFiles ( getRawPathForLocation ( loc ) ) and
182- locationExistsInBase ( loc ) and
183- not locationExistsInOverlay ( loc )
164+ /** Discardable string part lists. */
165+ overlay [ local]
166+ final private class DiscardableStringPartList extends Discardable instanceof @py_StringPart_list {
167+ override string getPath ( ) {
168+ exists ( Discardable d | result = d .getPath ( ) | py_StringPart_lists ( this , d .( @py_Bytes_or_Str) ) )
169+ }
170+ }
171+
172+ /** Discardable alias */
173+ overlay [ local]
174+ final private class DiscardableAlias extends Discardable instanceof @py_alias {
175+ override string getPath ( ) {
176+ exists ( DiscardableAliasList d | result = d .getPath ( ) | py_aliases ( this , d , _) )
177+ }
178+ }
179+
180+ /** Discardable alias list */
181+ overlay [ local]
182+ final private class DiscardableAliasList extends Discardable instanceof @py_alias_list {
183+ override string getPath ( ) {
184+ exists ( Discardable d | result = d .getPath ( ) | py_alias_lists ( this , d .( @py_Import) ) )
185+ }
186+ }
187+
188+ /** Discardable arguments */
189+ overlay [ local]
190+ final private class DiscardableArguments extends Discardable instanceof @py_arguments {
191+ override string getPath ( ) {
192+ exists ( Discardable d | result = d .getPath ( ) | py_arguments ( this , d .( @py_arguments_parent) ) )
193+ }
194+ }
195+
196+ /** Discardable boolop */
197+ overlay [ local]
198+ final private class DiscardableBoolOp extends Discardable instanceof @py_boolop {
199+ override string getPath ( ) {
200+ exists ( Discardable d | result = d .getPath ( ) | py_boolops ( this , _, d .( @py_BoolExpr) ) )
201+ }
202+ }
203+
204+ /** Discardable cmpop */
205+ overlay [ local]
206+ final private class DiscardableCmpOp extends Discardable instanceof @py_cmpop {
207+ override string getPath ( ) {
208+ exists ( DiscardableCmpOpList d | result = d .getPath ( ) | py_cmpops ( this , _, d , _) )
209+ }
210+ }
211+
212+ /** Discardable cmpop list */
213+ overlay [ local]
214+ final private class DiscardableCmpOpList extends Discardable instanceof @py_cmpop_list {
215+ override string getPath ( ) {
216+ exists ( Discardable d | result = d .getPath ( ) | py_cmpop_lists ( this , d .( @py_Compare) ) )
217+ }
218+ }
219+
220+ /** Discardable comprehension list */
221+ overlay [ local]
222+ final private class DiscardableComprehensionList extends Discardable instanceof @py_comprehension_list
223+ {
224+ override string getPath ( ) {
225+ exists ( Discardable d | result = d .getPath ( ) | py_comprehension_lists ( this , d .( @py_ListComp) ) )
226+ }
227+ }
228+
229+ /** Discardable dict item list */
230+ overlay [ local]
231+ final private class DiscardableDictItemList extends Discardable instanceof @py_dict_item_list {
232+ override string getPath ( ) {
233+ exists ( Discardable d | result = d .getPath ( ) |
234+ py_dict_item_lists ( this , d .( @py_dict_item_list_parent) )
235+ )
236+ }
237+ }
238+
239+ /** Discardable expr context */
240+ overlay [ local]
241+ final private class DiscardableExprContext extends Discardable instanceof @py_expr_context {
242+ override string getPath ( ) {
243+ exists ( Discardable d | result = d .getPath ( ) |
244+ py_expr_contexts ( this , _, d .( @py_expr_context_parent) )
245+ )
246+ }
247+ }
248+
249+ /** Discardable expr list */
250+ overlay [ local]
251+ final private class DiscardableExprList extends Discardable instanceof @py_expr_list {
252+ override string getPath ( ) {
253+ exists ( Discardable d | result = d .getPath ( ) | py_expr_lists ( this , d .( @py_expr_list_parent) , _) )
254+ }
255+ }
256+
257+ /** Discardable operator */
258+ overlay [ local]
259+ final private class DiscardableOperator extends Discardable instanceof @py_operator {
260+ override string getPath ( ) {
261+ exists ( Discardable d | result = d .getPath ( ) | py_operators ( this , _, d .( @py_BinaryExpr) ) )
262+ }
263+ }
264+
265+ /** Discardable parameter list */
266+ overlay [ local]
267+ final private class DiscardableParameterList extends Discardable instanceof @py_parameter_list {
268+ override string getPath ( ) {
269+ exists ( Discardable d | result = d .getPath ( ) | py_parameter_lists ( this , d .( @py_Function) ) )
270+ }
271+ }
272+
273+ /** Discardable pattern list */
274+ overlay [ local]
275+ final private class DiscardablePatternList extends Discardable instanceof @py_pattern_list {
276+ override string getPath ( ) {
277+ exists ( Discardable d | result = d .getPath ( ) |
278+ py_pattern_lists ( this , d .( @py_pattern_list_parent) , _)
279+ )
280+ }
281+ }
282+
283+ /** Discardable stmt list */
284+ overlay [ local]
285+ final private class DiscardableStmtList extends Discardable instanceof @py_stmt_list {
286+ override string getPath ( ) {
287+ exists ( Discardable d | result = d .getPath ( ) | py_stmt_lists ( this , d .( @py_stmt_list_parent) , _) )
288+ }
289+ }
290+
291+ /** Discardable str list */
292+ overlay [ local]
293+ final private class DiscardableStrList extends Discardable instanceof @py_str_list {
294+ override string getPath ( ) {
295+ exists ( Discardable d | result = d .getPath ( ) | py_str_lists ( this , d .( @py_str_list_parent) ) )
296+ }
297+ }
298+
299+ /** Discardable type parameter list */
300+ overlay [ local]
301+ final private class DiscardableTypeParameterList extends Discardable instanceof @py_type_parameter_list
302+ {
303+ override string getPath ( ) {
304+ exists ( Discardable d | result = d .getPath ( ) |
305+ py_type_parameter_lists ( this , d .( @py_type_parameter_list_parent) )
306+ )
307+ }
308+ }
309+
310+ /** Discardable unaryop */
311+ overlay [ local]
312+ final private class DiscardableUnaryOp extends Discardable instanceof @py_unaryop {
313+ override string getPath ( ) {
314+ exists ( Discardable d | result = d .getPath ( ) | py_unaryops ( this , _, d .( @py_UnaryExpr) ) )
315+ }
316+ }
317+
318+ /** Discardable comment */
319+ overlay [ local]
320+ final private class DiscardableComment extends Discardable instanceof @py_comment {
321+ override string getPath ( ) {
322+ exists ( DiscardableLocation d | result = d .getPath ( ) | py_comments ( this , _, d ) )
323+ }
184324}
185325
186326/*- XML -*/
0 commit comments