Skip to content

Commit 87be3a5

Browse files
rishipalcopybara-github
authored andcommitted
Add a post-transpile pass that asserts that the compiler's featureSet after transpile matches the output featureSet
PiperOrigin-RevId: 552619591
1 parent 9c24690 commit 87be3a5

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/com/google/javascript/jscomp/TranspilationPasses.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
/** Provides a single place to manage transpilation passes. */
2626
public class TranspilationPasses {
27+
2728
private TranspilationPasses() {}
2829

2930
public static void addEs6ModulePass(
@@ -230,6 +231,9 @@ public static void addPostNormalizationTranspilationPasses(
230231
if (options.needsTranspilationOf(Feature.GENERATORS)) {
231232
passes.maybeAdd(rewriteGenerators);
232233
}
234+
passes.maybeAdd(
235+
TranspilationPasses.createPostTranspileUnsupportedFeaturesRemovedCheck(
236+
"postTranspileUnsupportedFeaturesRemovedCheck"));
233237
}
234238

235239
/** Adds the pass to inject ES2015 polyfills, which goes after the late ES2015 passes. */
@@ -498,6 +502,33 @@ static void maybeMarkFeaturesAsTranspiledAway(
498502
}
499503
}
500504

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+
501532
/**
502533
* Returns a pass that just removes features from the AST FeatureSet.
503534
*
@@ -515,4 +546,17 @@ private static PassFactory createFeatureRemovalPass(
515546
compiler, featureToRemove, moreFeaturesToRemove)))
516547
.build();
517548
}
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+
}
518562
}

0 commit comments

Comments
 (0)