Skip to content

Commit

Permalink
TranspilationPasses.addEs6PostTypecheckPasses()
Browse files Browse the repository at this point in the history
We'll be moving transpilation passes into this method as we make them
safe to run after the typecheck passes.

1. update the type check passes to understand the features they
   transpile.
2. update the transpilation passes to propagate type information as
   part of transpilation

Also renamed related methods consistently.
addEs6Passes() -> addEs6PreTypecheckPasses()
addPostCheckPasses() -> addEs6PostCheckPasses()

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188273749
  • Loading branch information
brad4d authored and lauraharker committed Mar 9, 2018
1 parent b71efdc commit 813feba
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 93 deletions.
169 changes: 85 additions & 84 deletions src/com/google/javascript/jscomp/DefaultPassConfig.java
Expand Up @@ -180,8 +180,9 @@ protected List<PassFactory> getTranspileOnlyPasses() {
// operator. If we split that into its own pass then the needsTranspilationFrom(ES7) call here
// can be removed.
if (options.needsTranspilationFrom(ES6) || options.needsTranspilationFrom(ES7)) {
TranspilationPasses.addEs6Passes(passes);
TranspilationPasses.addPostCheckPasses(passes);
TranspilationPasses.addEs6PreTypecheckPasses(passes);
TranspilationPasses.addEs6PostTypecheckPasses(passes);
TranspilationPasses.addEs6PostCheckPasses(passes);
if (options.rewritePolyfills) {
TranspilationPasses.addRewritePolyfillPass(passes);
}
Expand Down Expand Up @@ -212,13 +213,6 @@ protected List<PassFactory> getWhitespaceOnlyPasses() {
return passes;
}

private void addNewTypeCheckerPasses(List<PassFactory> checks, CompilerOptions options) {
if (options.getNewTypeInference()) {
checks.add(symbolTableForNewTypeInference);
checks.add(newTypeInference);
}
}

private void addOldTypeCheckerPasses(List<PassFactory> checks, CompilerOptions options) {
if (!options.allowsHotswapReplaceScript()) {
checks.add(inlineTypeAliases);
Expand Down Expand Up @@ -388,7 +382,7 @@ protected List<PassFactory> getChecks() {

if (options.needsTranspilationFrom(ES6)) {
checks.add(es6ExternsCheck);
TranspilationPasses.addEs6Passes(checks);
TranspilationPasses.addEs6PreTypecheckPasses(checks);
}

if (options.rewritePolyfills && !options.checksOnly) {
Expand All @@ -403,12 +397,89 @@ protected List<PassFactory> getChecks() {
checks.add(convertStaticInheritance);
}

if (!options.skipNonTranspilationPasses) {
addNonTranspilationCheckPasses(checks);
if (options.skipNonTranspilationPasses) {
TranspilationPasses.addEs6PostTypecheckPasses(checks);
} else {
checks.add(createEmptyPass(PassNames.BEFORE_TYPE_CHECKING));

if (options.getNewTypeInference()) {
// We will not be updating NTI to understand any more new features,
// so transpile those features before running it.
TranspilationPasses.addEs6PostTypecheckPasses(checks);
checks.add(symbolTableForNewTypeInference);
checks.add(newTypeInference);
} else {
addOldTypeCheckerPasses(checks, options);
TranspilationPasses.addEs6PostTypecheckPasses(checks);
}

if (options.j2clPassMode.shouldAddJ2clPasses()) {
checks.add(j2clSourceFileChecker);
}

if (!options.disables(DiagnosticGroups.CHECK_USELESS_CODE)
|| (!options.getNewTypeInference()
&& !options.disables(DiagnosticGroups.MISSING_RETURN))) {
checks.add(checkControlFlow);
}

// CheckAccessControls only works if check types is on.
if (options.isTypecheckingEnabled()
&& (!options.disables(DiagnosticGroups.ACCESS_CONTROLS)
|| options.enables(DiagnosticGroups.CONSTANT_PROPERTY))) {
checks.add(checkAccessControls);
}

if (!options.getNewTypeInference()) {
// NTI performs this check already
checks.add(checkConsts);
}

// Analyzer checks must be run after typechecking.
if (options.enables(DiagnosticGroups.ANALYZER_CHECKS) && options.isTypecheckingEnabled()) {
checks.add(analyzerChecks);
}

if (options.checkGlobalNamesLevel.isOn()) {
checks.add(checkGlobalNames);
}

if (!options.getConformanceConfigs().isEmpty()) {
checks.add(checkConformance);
}

// Replace 'goog.getCssName' before processing defines but after the
// other checks have been done.
if (options.closurePass && !options.shouldPreserveGoogLibraryPrimitives()) {
checks.add(closureReplaceGetCssName);
}

if (options.getTweakProcessing().isOn()) {
checks.add(processTweaks);
}

if (options.instrumentationTemplate != null || options.recordFunctionInformation) {
checks.add(computeFunctionNames);
}

if (options.checksOnly) {
// Run process defines here so that warnings/errors from that pass are emitted as part of
// checks.
// TODO(rluble): Split process defines into two stages, one that performs only checks to be
// run here, and the one that actually changes the AST that would run in the optimization
// phase.
checks.add(processDefines);
}

if (options.j2clPassMode.shouldAddJ2clPasses()) {
checks.add(j2clChecksPass);
}
}

if (options.needsTranspilationFrom(ES6) && !options.checksOnly) {
TranspilationPasses.addPostCheckPasses(checks);
// At this point all checks have been done.
// There's no need to complete transpilation if we're only running checks.
TranspilationPasses.addEs6PostCheckPasses(checks);
}


Expand Down Expand Up @@ -439,76 +510,6 @@ protected List<PassFactory> getChecks() {
return checks;
}

private void addNonTranspilationCheckPasses(List<PassFactory> checks) {
checks.add(createEmptyPass(PassNames.BEFORE_TYPE_CHECKING));
addNewTypeCheckerPasses(checks, options);

if (!options.getNewTypeInference()) {
addOldTypeCheckerPasses(checks, options);
}

if (options.j2clPassMode.shouldAddJ2clPasses()) {
checks.add(j2clSourceFileChecker);
}

if (!options.disables(DiagnosticGroups.CHECK_USELESS_CODE)
|| (!options.getNewTypeInference() && !options.disables(DiagnosticGroups.MISSING_RETURN))) {
checks.add(checkControlFlow);
}

// CheckAccessControls only works if check types is on.
if (options.isTypecheckingEnabled()
&& (!options.disables(DiagnosticGroups.ACCESS_CONTROLS)
|| options.enables(DiagnosticGroups.CONSTANT_PROPERTY))) {
checks.add(checkAccessControls);
}

if (!options.getNewTypeInference()) {
// NTI performs this check already
checks.add(checkConsts);
}

// Analyzer checks must be run after typechecking.
if (options.enables(DiagnosticGroups.ANALYZER_CHECKS) && options.isTypecheckingEnabled()) {
checks.add(analyzerChecks);
}

if (options.checkGlobalNamesLevel.isOn()) {
checks.add(checkGlobalNames);
}

if (!options.getConformanceConfigs().isEmpty()) {
checks.add(checkConformance);
}

// Replace 'goog.getCssName' before processing defines but after the
// other checks have been done.
if (options.closurePass && !options.shouldPreserveGoogLibraryPrimitives()) {
checks.add(closureReplaceGetCssName);
}

if (options.getTweakProcessing().isOn()) {
checks.add(processTweaks);
}

if (options.instrumentationTemplate != null || options.recordFunctionInformation) {
checks.add(computeFunctionNames);
}

if (options.checksOnly) {
// Run process defines here so that warnings/errors from that pass are emitted as part of
// checks.
// TODO(rluble): Split process defines into two stages, one that performs only checks to be
// run here, and the one that actually changes the AST that would run in the optimization
// phase.
checks.add(processDefines);
}

if (options.j2clPassMode.shouldAddJ2clPasses()) {
checks.add(j2clChecksPass);
}
}

@Override
protected List<PassFactory> getOptimizations() {
List<PassFactory> passes = new ArrayList<>();
Expand Down Expand Up @@ -2037,7 +2038,7 @@ protected FeatureSet featureSet() {
new HotSwapPassFactory(PassNames.ANALYZER_CHECKS) {
@Override
protected HotSwapCompilerPass create(AbstractCompiler compiler) {
ImmutableList.Builder<Callback> callbacks = ImmutableList.<Callback>builder();
ImmutableList.Builder<Callback> callbacks = ImmutableList.builder();
if (options.enables(DiagnosticGroups.ANALYZER_CHECKS_INTERNAL)) {
callbacks
.add(new CheckNullableReturn(compiler))
Expand Down
15 changes: 13 additions & 2 deletions src/com/google/javascript/jscomp/TranspilationPasses.java
Expand Up @@ -73,7 +73,7 @@ public static void addEs2016Passes(List<PassFactory> passes) {
passes.add(convertEs7ToEs6);
}

public static void addEs6Passes(List<PassFactory> passes) {
public static void addEs6PreTypecheckPasses(List<PassFactory> passes) {
// Binary and octal literals are effectively transpiled by the parser.
// There's no transpilation we can do for the new regexp flags.
passes.add(
Expand Down Expand Up @@ -460,7 +460,18 @@ static void hotSwapTranspile(
}
}

public static void addPostCheckPasses(List<PassFactory> passes) {
/**
* Adds transpilation passes that should run after type checking is done, but before the other
* checks.
*/
public static void addEs6PostTypecheckPasses(List<PassFactory> passes) {
// TODO(b/73387406): Move passes here as typecheck passes are updated to cope with the features
// they transpile and as the passes themselves are updated to propagate type information to the
// transpiled code.
}

/** Adds transpilation passes that should run after all checks are done. */
public static void addEs6PostCheckPasses(List<PassFactory> passes) {
passes.add(es6ConvertSuperConstructorCalls);
}

Expand Down
6 changes: 4 additions & 2 deletions test/com/google/javascript/jscomp/CompilerTestCase.java
Expand Up @@ -1743,7 +1743,9 @@ private static void transpileToEs5(AbstractCompiler compiler, Node externsRoot,
factories, new PreprocessorSymbolTable.CachedInstanceFactory());
TranspilationPasses.addEs2017Passes(factories);
TranspilationPasses.addEs2016Passes(factories);
TranspilationPasses.addEs6Passes(factories);
TranspilationPasses.addEs6PreTypecheckPasses(factories);
TranspilationPasses.addEs6PostTypecheckPasses(factories);
TranspilationPasses.addEs6PostCheckPasses(factories);
TranspilationPasses.addRewritePolyfillPass(factories);
for (PassFactory factory : factories) {
factory.create(compiler).process(externsRoot, codeRoot);
Expand Down Expand Up @@ -1989,7 +1991,7 @@ public void visit(Node n) {
}
}
},
Predicates.<Node>alwaysTrue());
Predicates.alwaysTrue());
return matches;
}

Expand Down
10 changes: 5 additions & 5 deletions test/com/google/javascript/jscomp/TypeCheckTest.java
Expand Up @@ -8354,7 +8354,7 @@ public void testBug1859535() {
}

public void testBug1940591() {
disableStrictMissingPropertyChecks();;
disableStrictMissingPropertyChecks();
testTypes(
"/** @type {Object} */" +
"var a = {};\n" +
Expand Down Expand Up @@ -10339,7 +10339,7 @@ public void testDefinePropertyOnNullableObject1a() {

public void testDefinePropertyOnObject() {
// checking loose property behavior
disableStrictMissingPropertyChecks();;
disableStrictMissingPropertyChecks();
testTypes(
lines(
"/** @type {!Object} */ var n = {};",
Expand All @@ -10353,7 +10353,7 @@ public void testDefinePropertyOnObject() {

public void testDefinePropertyOnNullableObject2() {
// checking loose property behavior
disableStrictMissingPropertyChecks();;
disableStrictMissingPropertyChecks();
testTypes("/** @constructor */ var T = function() {};\n" +
"/** @param {T} t\n@return {boolean} */function f(t) {\n" +
"t.x = 1; return t.x; }",
Expand Down Expand Up @@ -12349,7 +12349,7 @@ public void testMissingProperty1a() {
}

public void testMissingProperty1b() {
disableStrictMissingPropertyChecks();;
disableStrictMissingPropertyChecks();

testTypes(
"/** @constructor */ function Foo() {}" +
Expand Down Expand Up @@ -19440,7 +19440,7 @@ private TypeCheckResult parseAndTypeCheckWithScope(String externs, String js) {
List<PassFactory> passes = new ArrayList<>();
TranspilationPasses.addEs2017Passes(passes);
TranspilationPasses.addEs2016Passes(passes);
TranspilationPasses.addEs6Passes(passes);
TranspilationPasses.addEs6PreTypecheckPasses(passes);
PhaseOptimizer phaseopt = new PhaseOptimizer(compiler, null);
phaseopt.consume(passes);
phaseopt.process(externsNode, jsNode);
Expand Down

0 comments on commit 813feba

Please sign in to comment.