24
24
25
25
/** Provides a single place to manage transpilation passes. */
26
26
public class TranspilationPasses {
27
+
27
28
private TranspilationPasses () {}
28
29
29
30
public static void addEs6ModulePass (
@@ -230,6 +231,9 @@ public static void addPostNormalizationTranspilationPasses(
230
231
if (options .needsTranspilationOf (Feature .GENERATORS )) {
231
232
passes .maybeAdd (rewriteGenerators );
232
233
}
234
+ passes .maybeAdd (
235
+ TranspilationPasses .createPostTranspileUnsupportedFeaturesRemovedCheck (
236
+ "postTranspileUnsupportedFeaturesRemovedCheck" ));
233
237
}
234
238
235
239
/** Adds the pass to inject ES2015 polyfills, which goes after the late ES2015 passes. */
@@ -498,6 +502,33 @@ static void maybeMarkFeaturesAsTranspiledAway(
498
502
}
499
503
}
500
504
505
+ static void postTranspileCheckUnsupportedFeaturesRemoved (AbstractCompiler compiler ) {
506
+ FeatureSet outputFeatures = compiler .getOptions ().getOutputFeatureSet ();
507
+ FeatureSet currentFeatures = compiler .getAllowableFeatures ();
508
+ // features modules, importMeta and Dynamic module import may exist in the output even though
509
+ // unsupported
510
+ if (compiler .getOptions ().getChunkOutputType () == ChunkOutputType .ES_MODULES ) {
511
+ currentFeatures =
512
+ currentFeatures
513
+ .without (Feature .MODULES )
514
+ .without (Feature .IMPORT_META )
515
+ .without (Feature .DYNAMIC_IMPORT );
516
+ }
517
+
518
+ if (outputFeatures .getFeatures ().isEmpty ()) {
519
+ // In some cases (e.g. targets built using `gen_closurized_js`), the outputFeatures is not
520
+ // set. Only when set, confirm that the output featureSet is respected by JSCompiler.
521
+ return ;
522
+ }
523
+
524
+ if (!outputFeatures .contains (currentFeatures )) {
525
+ // Confirm that the output featureSet is respected by JSCompiler.
526
+ FeatureSet diff = currentFeatures .without (outputFeatures );
527
+ throw new IllegalStateException (
528
+ "Unsupported feature(s) leaked to output code:" + diff .getFeatures ());
529
+ }
530
+ }
531
+
501
532
/**
502
533
* Returns a pass that just removes features from the AST FeatureSet.
503
534
*
@@ -515,4 +546,17 @@ private static PassFactory createFeatureRemovalPass(
515
546
compiler , featureToRemove , moreFeaturesToRemove )))
516
547
.build ();
517
548
}
549
+
550
+ /**
551
+ * Returns a pass that just checks that post-transpile only supported features exist in the code.
552
+ */
553
+ private static PassFactory createPostTranspileUnsupportedFeaturesRemovedCheck (String passName ) {
554
+ return PassFactory .builder ()
555
+ .setName (passName )
556
+ .setInternalFactory (
557
+ (compiler ) ->
558
+ ((Node externs , Node root ) ->
559
+ postTranspileCheckUnsupportedFeaturesRemoved (compiler )))
560
+ .build ();
561
+ }
518
562
}
0 commit comments