@@ -465,10 +465,11 @@ public int run() throws IOException {
465465 try {
466466 CompletableFuture <?> sourceFuture = extractSource ();
467467 sourceFuture .join (); // wait for source extraction to complete
468- if (hasSeenCode ()) { // don't bother with the externs if no code was seen
468+ if (hasSeenCode () && ! isOverlayChangeMode () ) { // don't bother with the externs if no code was seen
469469 extractExterns ();
470470 }
471471 extractXml ();
472+ writeOverlayMetadata ();
472473 } catch (OutOfMemoryError oom ) {
473474 System .err .println ("Out of memory while extracting the project." );
474475 return 137 ; // the CodeQL CLI will interpret this as an out-of-memory error
@@ -509,6 +510,21 @@ public int run() throws IOException {
509510 return 0 ;
510511 }
511512
513+ private void writeOverlayMetadata () {
514+ String file = getEnvVar ("CODEQL_EXTRACTOR_JAVASCRIPT_OVERLAY_BASE_METADATA_OUT" );
515+ if (file == null ) {
516+ // no overlay metadata file specified, so nothing to do
517+ return ;
518+ }
519+ // Write an empty string to the file as we currently have no metadata to emit.
520+ // The file must be created for the database to recognized as an overlay base.
521+ try {
522+ Files .writeString (Paths .get (file ), "" , StandardCharsets .UTF_8 );
523+ } catch (IOException e ) {
524+ throw new ResourceError ("Could not write overlay metadata to " + file , e );
525+ }
526+ }
527+
512528 /**
513529 * A kind of error that can happen during extraction of JavaScript or TypeScript
514530 * code.
@@ -734,6 +750,17 @@ private CompletableFuture<?> extractSource() throws IOException {
734750 List <Path > tsconfigFiles = new ArrayList <>();
735751 findFilesToExtract (defaultExtractor , filesToExtract , tsconfigFiles );
736752
753+ OverlayChanges overlay = getOverlayChanges ();
754+ if (overlay != null ) {
755+ Set <Path > changedFiles = overlay .changes .stream ()
756+ .map (file -> Paths .get (file ).toAbsolutePath ())
757+ .collect (Collectors .toSet ());
758+ int before = filesToExtract .size ();
759+ filesToExtract .retainAll (changedFiles );
760+ int after = filesToExtract .size ();
761+ System .out .println ("Overlay filter removed " + (before - after ) + " out of " + before + " files from extraction." );
762+ }
763+
737764 tsconfigFiles = tsconfigFiles .stream ()
738765 .sorted (PATH_ORDERING )
739766 .collect (Collectors .toList ());
@@ -1338,6 +1365,18 @@ protected void extractXml() throws IOException {
13381365 }
13391366 }
13401367
1368+ private boolean isOverlayChangeMode () {
1369+ return getEnvVar ("CODEQL_EXTRACTOR_JAVASCRIPT_OVERLAY_CHANGES" ) != null ;
1370+ }
1371+
1372+ private OverlayChanges getOverlayChanges () throws IOException {
1373+ String jsonFile = getEnvVar ("CODEQL_EXTRACTOR_JAVASCRIPT_OVERLAY_CHANGES" );
1374+ if (jsonFile == null ) {
1375+ return null ;
1376+ }
1377+ return new Gson ().fromJson (Files .newBufferedReader (Paths .get (jsonFile )), OverlayChanges .class );
1378+ }
1379+
13411380 public static void main (String [] args ) {
13421381 try {
13431382 System .exit (new AutoBuild ().run ());
0 commit comments