|
10 | 10 | overlay[local] |
11 | 11 | predicate isOverlay() { databaseMetadata("isOverlay", "true") } |
12 | 12 |
|
13 | | -/** Gets the file path for a location. */ |
14 | 13 | overlay[local] |
15 | 14 | private string getLocationFilePath(@location_default loc) { |
16 | 15 | exists(@file file | locations_default(loc, file, _, _, _, _) | files(file, result)) |
17 | 16 | } |
18 | 17 |
|
| 18 | +/** |
| 19 | + * An element with a single location. Discard if in a changed file. |
| 20 | + */ |
19 | 21 | overlay[local] |
20 | | -private class DiscardableEntityBase extends @element { |
21 | | - /** Gets the path to the file in which this element occurs. */ |
| 22 | +abstract private class Discardable extends @element { |
22 | 23 | abstract string getFilePath(); |
23 | 24 |
|
24 | | - /** Holds if this element exists in the base variant. */ |
25 | 25 | predicate existsInBase() { not isOverlay() } |
26 | 26 |
|
27 | | - /** Gets a textual representation of this discardable element. */ |
28 | 27 | string toString() { none() } |
29 | 28 | } |
30 | 29 |
|
| 30 | +overlay[discard_entity] |
| 31 | +private predicate discardable(@element e) { |
| 32 | + e = any(Discardable d | d.existsInBase() and overlayChangedFiles(d.getFilePath())) |
| 33 | +} |
| 34 | + |
31 | 35 | /** |
32 | | - * Discard an entity from the base if all its locations are in changed files. |
33 | | - * Entities with at least one location in an unchanged file are kept. |
| 36 | + * An element with potentially multiple locations, e.g., variables, functions and types. |
| 37 | + * Discard only if all locations are in changed files. |
34 | 38 | */ |
| 39 | +overlay[local] |
| 40 | +abstract private class MultiDiscardable extends @element { |
| 41 | + abstract string getFilePath(); |
| 42 | + |
| 43 | + predicate existsInBase() { not isOverlay() } |
| 44 | + |
| 45 | + string toString() { none() } |
| 46 | +} |
| 47 | + |
35 | 48 | overlay[discard_entity] |
36 | | -private predicate discardEntity(@element e) { |
| 49 | +private predicate multiDiscardable(@element e) { |
37 | 50 | e = |
38 | | - any(DiscardableEntityBase de | |
39 | | - de.existsInBase() and |
40 | | - overlayChangedFiles(de.getFilePath()) and |
41 | | - // Only discard if ALL file paths are in changed files |
42 | | - forall(string path | path = de.getFilePath() | overlayChangedFiles(path)) |
| 51 | + any(MultiDiscardable d | |
| 52 | + d.existsInBase() and |
| 53 | + forall(string path | path = d.getFilePath() | overlayChangedFiles(path)) |
43 | 54 | ) |
44 | 55 | } |
45 | 56 |
|
46 | | -/** A discardable variable declaration entry. */ |
47 | 57 | overlay[local] |
48 | | -private class DiscardableVarDecl extends DiscardableEntityBase instanceof @var_decl { |
| 58 | +private class DiscardableVarDecl extends Discardable instanceof @var_decl { |
49 | 59 | override string getFilePath() { |
50 | 60 | exists(@location_default loc | var_decls(this, _, _, _, loc) | |
51 | 61 | result = getLocationFilePath(loc) |
52 | 62 | ) |
53 | 63 | } |
54 | 64 | } |
55 | 65 |
|
56 | | -/** A discardable variable. */ |
57 | 66 | overlay[local] |
58 | | -private class DiscardableVariable extends DiscardableEntityBase instanceof @variable { |
| 67 | +private class DiscardableVariable extends MultiDiscardable instanceof @variable { |
59 | 68 | override string getFilePath() { |
60 | 69 | exists(@var_decl vd, @location_default loc | var_decls(vd, this, _, _, loc) | |
61 | 70 | result = getLocationFilePath(loc) |
|
0 commit comments