@@ -15,13 +15,28 @@ private string getLocationFilePath(@location_default loc) {
1515 exists ( @file file | locations_default ( loc , file , _, _, _, _) | files ( file , result ) )
1616}
1717
18+ overlay [ local]
19+ private class DiscardableEntityBase extends @locatable {
20+ /** Gets the path to the file in which this element occurs. */
21+ abstract string getFilePath ( ) ;
22+
23+ /** Holds if this element exists in the base variant. */
24+ predicate existsInBase ( ) { not isOverlay ( ) }
25+
26+ /** Holds if this element exists in the overlay variant. */
27+ predicate existsInOverlay ( ) { isOverlay ( ) }
28+
29+ /** Gets a textual representation of this discardable element. */
30+ string toString ( ) { none ( ) }
31+ }
32+
1833/**
1934 * A class of elements that can be discarded from the base.
2035 */
2136overlay [ local]
22- private class DiscardableEntity extends @locatable {
37+ private class DiscardableEntity extends DiscardableEntityBase {
2338 /** Gets the path to the file in which this element occurs. */
24- string getFilePath ( ) {
39+ override string getFilePath ( ) {
2540 exists ( @location_default loc | result = getLocationFilePath ( loc ) |
2641 expr_location ( this , loc ) or
2742 stmt_location ( this , loc ) or
@@ -50,15 +65,6 @@ private class DiscardableEntity extends @locatable {
5065 extractor_messages ( this , _, _, _, _, loc , _)
5166 )
5267 }
53-
54- /** Holds if this element exists in the base variant. */
55- predicate existsInBase ( ) { not isOverlay ( ) }
56-
57- /** Holds if this element exists in the overlay variant. */
58- predicate existsInOverlay ( ) { isOverlay ( ) }
59-
60- /** Gets a textual representation of this discardable element. */
61- string toString ( ) { none ( ) }
6268}
6369
6470/**
@@ -103,3 +109,33 @@ overlay[discard_entity]
103109private predicate discardLocation ( @location_default loc ) {
104110 exists ( string path | discardableLocation ( loc , path ) | overlayChangedFiles ( path ) )
105111}
112+
113+ /**
114+ * A class of Xml locatables that can be discarded from the base.
115+ */
116+ overlay [ local]
117+ private class DiscardableXmlEntity extends DiscardableEntityBase instanceof @xmllocatable {
118+ /** Gets the path to the file in which this element occurs. */
119+ override string getFilePath ( ) {
120+ exists ( @location_default loc | result = getLocationFilePath ( loc ) | xmllocations ( this , loc ) )
121+ }
122+ }
123+
124+ overlay [ local]
125+ private predicate overlayXmlExtracted ( string file ) {
126+ exists ( DiscardableXmlEntity dxe |
127+ dxe .existsInOverlay ( ) and
128+ file = dxe .getFilePath ( ) and
129+ not files ( dxe , _) and
130+ not xmlNs ( dxe , _, _, _)
131+ )
132+ }
133+
134+ overlay [ discard_entity]
135+ private predicate discardXmlEntity ( @xmllocatable xml ) {
136+ overlayChangedFiles ( xml .( DiscardableXmlEntity ) .getFilePath ( ) )
137+ or
138+ // The XML extractor is not incremental and may extract more
139+ // XML files than those included in overlayChangedFiles.
140+ overlayXmlExtracted ( xml .( DiscardableXmlEntity ) .getFilePath ( ) )
141+ }
0 commit comments