@@ -1251,9 +1251,7 @@ protected int doRun() throws IOException {
1251
1251
externs = null ;
1252
1252
sources = null ;
1253
1253
1254
- Result result ;
1255
- // We won't want to process results for cases where compilation is only partially done.
1256
- boolean shouldProcessResults = true ;
1254
+ final Result result ;
1257
1255
if (config .skipNormalOutputs ) {
1258
1256
metricsRecorder .recordActionName ("skip normal outputs" );
1259
1257
// TODO(bradfordcsmith): Should we be ignoring possible init/initChunks() errors here?
@@ -1264,43 +1262,26 @@ protected int doRun() throws IOException {
1264
1262
// init() or initChunks() encountered an error.
1265
1263
compiler .generateReport ();
1266
1264
result = compiler .getResult ();
1267
- } else if (options .getInstrumentForCoverageOnly ()) {
1268
- result = instrumentForCoverage (metricsRecorder );
1269
- } else if (config .shouldSaveAfterStage1 ()) {
1270
- result = performStage1andSave (config .getSaveCompilationStateToFilename (), metricsRecorder );
1271
- // Don't output any results, since compilation isn't done yet.
1272
- shouldProcessResults = false ;
1273
- } else if (config .shouldRestoreTypedAstsPerformStage2AndSave ()) {
1274
- result =
1275
- restoreTypedAstsPerformStage2AndSave (
1276
- config .getSaveCompilationStateToFilename (), metricsRecorder );
1277
- // Don't output any results, since compilation isn't done yet.
1278
- shouldProcessResults = false ;
1279
- } else if (config .shouldRestoreTypedAstsPerformStages2And3 ()) {
1280
- result = restoreTypedAstsPerformStages2and3 (metricsRecorder );
1281
- } else if (config .shouldRestoreAndPerformStage2AndSave ()) {
1282
- result =
1283
- restoreAndPerformStage2AndSave (
1284
- config .getContinueSavedCompilationFileName (),
1285
- config .getSaveCompilationStateToFilename (),
1286
- metricsRecorder );
1287
- // Don't output any results, since compilation isn't done yet.
1288
- shouldProcessResults = false ;
1289
- } else if (config .shouldRestoreAndPerformStages2And3 ()) {
1290
- result =
1291
- restoreAndPerformStages2and3 (
1292
- config .getContinueSavedCompilationFileName (), metricsRecorder );
1293
- if (chunks != null ) {
1294
- chunks = ImmutableList .copyOf (compiler .getChunks ());
1295
- }
1296
- } else if (config .shouldRestoreAndPerformStage3 ()) {
1297
- result =
1298
- restoreAndPerformStage3 (config .getContinueSavedCompilationFileName (), metricsRecorder );
1299
- if (chunks != null ) {
1300
- chunks = ImmutableList .copyOf (compiler .getChunks ());
1301
- }
1302
1265
} else {
1303
- result = performFullCompilation (metricsRecorder );
1266
+ try {
1267
+ // This is the common case - we're actually compiling something.
1268
+ performCompilation (metricsRecorder );
1269
+ result = compiler .getResult ();
1270
+ // If we're finished with compilation (i.e. we're not saving state), /and/ the compiler was
1271
+ // restored from a previous state, then we need to re-initialize the set of chunks.
1272
+ // TODO(lharker): figure out if this is still needed.
1273
+ boolean refresh =
1274
+ chunks != null
1275
+ && config .restoredCompilationStage != -1
1276
+ && config .saveAfterCompilationStage == -1 ;
1277
+ if (refresh ) {
1278
+ chunks = ImmutableList .copyOf (compiler .getChunks ());
1279
+ }
1280
+ } finally {
1281
+ // Make sure we generate a report of errors and warnings even if the compiler throws an
1282
+ // exception somewhere.
1283
+ compiler .generateReport ();
1284
+ }
1304
1285
}
1305
1286
1306
1287
if (createCommonJsModules ) {
@@ -1318,6 +1299,8 @@ protected int doRun() throws IOException {
1318
1299
}
1319
1300
}
1320
1301
1302
+ // We won't want to process results for cases where compilation is only partially done.
1303
+ boolean shouldProcessResults = config .getSaveCompilationStateToFilename () == null ;
1321
1304
int exitStatus =
1322
1305
shouldProcessResults
1323
1306
? processResults (result , chunks , options )
@@ -1326,6 +1309,90 @@ protected int doRun() throws IOException {
1326
1309
return exitStatus ;
1327
1310
}
1328
1311
1312
+ private void performCompilation (CompileMetricsRecorderInterface metricsRecorder ) {
1313
+ // Parse, restore from a save file, or initialize from a TypedAST list.
1314
+ initializeStateBeforeCompilation ();
1315
+
1316
+ // Do the interesting work - checks, optimizations, etc.
1317
+ runCompilerPasses (metricsRecorder );
1318
+
1319
+ // Save state unless there was an exception or error - we won't go on to the next stage if there
1320
+ // was an error, and saving state itself might throw an exception if the compiler is in a bad
1321
+ // state.
1322
+ if (!compiler .hasErrors ()) {
1323
+ saveState ();
1324
+ }
1325
+ // Perform post-compilation tasks even if compiler.hasErrors()
1326
+ compiler .performPostCompilationTasks ();
1327
+ }
1328
+
1329
+ private void runCompilerPasses (CompileMetricsRecorderInterface metricsRecorder ) {
1330
+ boolean runStage1 = false ;
1331
+ boolean runStage2 = false ;
1332
+ boolean runStage3 = false ;
1333
+ boolean instrumentForCoverage = false ;
1334
+ final String actionMetricsName ;
1335
+ if (compiler .getOptions ().getInstrumentForCoverageOnly ()) {
1336
+ actionMetricsName = "instrument for coverage" ;
1337
+ instrumentForCoverage = true ;
1338
+ } else if (config .shouldSaveAfterStage1 ()) {
1339
+ actionMetricsName = "stage 1" ;
1340
+ runStage1 = true ;
1341
+ } else if (config .shouldRestoreTypedAstsPerformStage2AndSave ()) {
1342
+ actionMetricsName = "parse & optimize" ;
1343
+ runStage2 = true ;
1344
+ } else if (config .shouldRestoreTypedAstsPerformStages2And3 ()) {
1345
+ actionMetricsName = "skip-checks compile" ;
1346
+ runStage2 = true ;
1347
+ runStage3 = true ;
1348
+ } else if (config .shouldRestoreAndPerformStage2AndSave ()) {
1349
+ actionMetricsName = "stage 2/3" ;
1350
+ runStage2 = true ;
1351
+ } else if (config .shouldRestoreAndPerformStages2And3 ()) {
1352
+ // From the outside this looks like the second stage of a 2-stage compile.
1353
+ actionMetricsName = "stage 2/2" ;
1354
+ runStage2 = true ;
1355
+ runStage3 = true ;
1356
+ } else if (config .shouldRestoreAndPerformStage3 ()) {
1357
+ actionMetricsName = "stage 3/3" ;
1358
+ runStage3 = true ;
1359
+ } else {
1360
+ // This is the code path taken when "building" a library by just checking it for errors
1361
+ // and generating an .ijs file and also when doing a full compilation.
1362
+ actionMetricsName = compiler .getOptions ().checksOnly ? "checks-only" : "full compile" ;
1363
+ runStage1 = true ;
1364
+ runStage2 = true ;
1365
+ runStage3 = true ;
1366
+ }
1367
+
1368
+ metricsRecorder .recordActionName (actionMetricsName );
1369
+ if (compiler .hasErrors ()) {
1370
+ return ;
1371
+ }
1372
+ metricsRecorder .recordStartState (compiler );
1373
+ if (runStage1 ) {
1374
+ compiler .stage1Passes ();
1375
+ if (compiler .hasErrors ()) {
1376
+ return ;
1377
+ }
1378
+ }
1379
+ if (runStage2 ) {
1380
+ compiler .stage2Passes (OptimizationPasses .ALL );
1381
+ if (compiler .hasErrors ()) {
1382
+ return ;
1383
+ }
1384
+ }
1385
+ if (runStage3 ) {
1386
+ compiler .stage3Passes ();
1387
+ if (compiler .hasErrors ()) {
1388
+ return ;
1389
+ }
1390
+ }
1391
+ if (instrumentForCoverage ) {
1392
+ compiler .instrumentForCoverage ();
1393
+ }
1394
+ }
1395
+
1329
1396
/**
1330
1397
* Child classes should override this if they want to actually record metrics about the
1331
1398
* compilation.
@@ -1334,30 +1401,6 @@ protected CompileMetricsRecorderInterface getCompileMetricsRecorder() {
1334
1401
return new DummyCompileMetricsRecorder ();
1335
1402
}
1336
1403
1337
- private Result performStage1andSave (
1338
- String filename , CompileMetricsRecorderInterface metricsRecorder ) {
1339
- metricsRecorder .recordActionName ("stage 1" );
1340
- try (BufferedOutputStream serializedOutputStream =
1341
- new BufferedOutputStream (new FileOutputStream (filename ))) {
1342
- compiler .parseForCompilation ();
1343
- if (!compiler .hasErrors ()) {
1344
- metricsRecorder .recordStartState (compiler );
1345
- compiler .stage1Passes ();
1346
- }
1347
- if (!compiler .hasErrors ()) {
1348
- compiler .saveState (serializedOutputStream );
1349
- }
1350
- compiler .performPostCompilationTasks ();
1351
- } catch (IOException e ) {
1352
- compiler .report (JSError .make (COULD_NOT_SERIALIZE_AST , filename ));
1353
- } finally {
1354
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1355
- // exception somewhere.
1356
- compiler .generateReport ();
1357
- }
1358
- return compiler .getResult ();
1359
- }
1360
-
1361
1404
private void initWithTypedAstFilesystem (
1362
1405
List <SourceFile > externs ,
1363
1406
List <SourceFile > sources ,
@@ -1381,166 +1424,46 @@ private void initChunksWithTypedAstFilesystem(
1381
1424
}
1382
1425
}
1383
1426
1384
- private Result restoreTypedAstsPerformStage2AndSave (
1385
- String outputFilename , CompileMetricsRecorderInterface metricsRecorder ) {
1386
- metricsRecorder .recordActionName ("parse & optimize" );
1387
- try {
1388
- if (!compiler .hasErrors ()) {
1389
- metricsRecorder .recordStartState (compiler );
1390
- compiler .stage2Passes (OptimizationPasses .ALL );
1391
- if (!compiler .hasErrors ()) {
1392
- try (BufferedOutputStream serializedOutputStream =
1393
- new BufferedOutputStream (new FileOutputStream (outputFilename ))) {
1394
- compiler .saveState (serializedOutputStream );
1395
- } catch (IOException e ) {
1396
- compiler .report (JSError .make (COULD_NOT_SERIALIZE_AST , outputFilename ));
1397
- }
1398
- compiler .performPostCompilationTasks ();
1399
- }
1400
- }
1401
- } finally {
1402
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1403
- // exception somewhere.
1404
- compiler .generateReport ();
1405
- }
1406
- return compiler .getResult ();
1407
- }
1408
-
1409
- private Result restoreTypedAstsPerformStages2and3 (
1410
- CompileMetricsRecorderInterface metricsRecorder ) {
1411
- metricsRecorder .recordActionName ("skip-checks compile" );
1412
- try {
1413
- if (!compiler .hasErrors ()) {
1414
- metricsRecorder .recordStartState (compiler );
1415
- compiler .stage2Passes (OptimizationPasses .ALL );
1416
- if (!compiler .hasErrors ()) {
1417
- compiler .stage3Passes ();
1418
- }
1419
- compiler .performPostCompilationTasks ();
1420
- }
1421
- } finally {
1422
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1423
- // exception somewhere.
1424
- compiler .generateReport ();
1425
- }
1426
- return compiler .getResult ();
1427
+ /**
1428
+ * Call at the beginning of compilation to initialize the compiler state.
1429
+ *
1430
+ * <p>Compiler state should be initialized no matter what the compilation stage is, but this
1431
+ * method handles the different ways it might be initialized - whether from parsing actual JS
1432
+ * files, from reading library-level TypedASTs, or from restoring a previous compilation state.
1433
+ */
1434
+ private void initializeStateBeforeCompilation () {
1435
+ if (config .restoredCompilationStage != -1 ) {
1436
+ restoreState (config .getContinueSavedCompilationFileName ());
1437
+ } else if (config .typedAstListInputFilename != null ) {
1438
+ // we did this elsewhere
1439
+ } else {
1440
+ // parsing!
1441
+ compiler .parseForCompilation ();
1427
1442
}
1428
-
1429
- private Result restoreAndPerformStage2AndSave (
1430
- String inputFilename ,
1431
- String outputFilename ,
1432
- CompileMetricsRecorderInterface metricsRecorder ) {
1433
- metricsRecorder .recordActionName ("stage 2/3" );
1434
- try (BufferedInputStream serializedInputStream =
1435
- new BufferedInputStream (new FileInputStream (inputFilename ))) {
1436
- compiler .restoreState (serializedInputStream );
1437
- if (!compiler .hasErrors ()) {
1438
- metricsRecorder .recordStartState (compiler );
1439
- compiler .stage2Passes (OptimizationPasses .ALL );
1440
- if (!compiler .hasErrors ()) {
1441
- try (BufferedOutputStream serializedOutputStream =
1442
- new BufferedOutputStream (new FileOutputStream (outputFilename ))) {
1443
- compiler .saveState (serializedOutputStream );
1444
- } catch (IOException e ) {
1445
- compiler .report (JSError .make (COULD_NOT_SERIALIZE_AST , outputFilename ));
1446
- }
1447
- compiler .performPostCompilationTasks ();
1448
- }
1449
- }
1450
- } catch (IOException | ClassNotFoundException e ) {
1451
- compiler .report (JSError .make (COULD_NOT_DESERIALIZE_AST , inputFilename ));
1452
- } finally {
1453
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1454
- // exception somewhere.
1455
- compiler .generateReport ();
1456
- }
1457
- return compiler .getResult ();
1458
1443
}
1459
1444
1460
- private Result restoreAndPerformStages2and3 (
1461
- String filename , CompileMetricsRecorderInterface metricsRecorder ) {
1462
- // From the outside this looks like the second stage of a 2-stage compile.
1463
- metricsRecorder .recordActionName ("stage 2/2" );
1445
+ private void restoreState (String filename ) {
1464
1446
try (BufferedInputStream serializedInputStream =
1465
1447
new BufferedInputStream (new FileInputStream (filename ))) {
1466
1448
compiler .restoreState (serializedInputStream );
1467
- if (!compiler .hasErrors ()) {
1468
- metricsRecorder .recordStartState (compiler );
1469
- compiler .stage2Passes (OptimizationPasses .ALL );
1470
- if (!compiler .hasErrors ()) {
1471
- compiler .stage3Passes ();
1472
- }
1473
- }
1474
- compiler .performPostCompilationTasks ();
1475
1449
} catch (IOException | ClassNotFoundException e ) {
1476
1450
compiler .report (JSError .make (COULD_NOT_DESERIALIZE_AST , filename ));
1477
- } finally {
1478
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1479
- // exception somewhere.
1480
- compiler .generateReport ();
1481
1451
}
1482
- return compiler .getResult ();
1483
1452
}
1484
1453
1485
- private Result restoreAndPerformStage3 (
1486
- String filename , CompileMetricsRecorderInterface metricsRecorder ) {
1487
- metricsRecorder .recordActionName ("stage 3/3" );
1488
- try (BufferedInputStream serializedInputStream =
1489
- new BufferedInputStream (new FileInputStream (filename ))) {
1490
- compiler .restoreState (serializedInputStream );
1491
- if (!compiler .hasErrors ()) {
1492
- metricsRecorder .recordStartState (compiler );
1493
- compiler .stage3Passes ();
1494
- }
1495
- compiler .performPostCompilationTasks ();
1496
- } catch (IOException | ClassNotFoundException e ) {
1497
- compiler .report (JSError .make (COULD_NOT_DESERIALIZE_AST , filename ));
1498
- } finally {
1499
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1500
- // exception somewhere.
1501
- compiler .generateReport ();
1502
- }
1503
- return compiler .getResult ();
1504
- }
1505
-
1506
- private Result performFullCompilation (CompileMetricsRecorderInterface metricsRecorder ) {
1507
- // This is the code path taken when "building" a library by just checking it for errors
1508
- // and generating an .ijs file and also when doing a full compilation.
1509
- metricsRecorder .recordActionName (
1510
- compiler .getOptions ().checksOnly ? "checks-only" : "full compile" );
1511
- try {
1512
- compiler .parseForCompilation ();
1513
- if (!compiler .hasErrors ()) {
1514
- metricsRecorder .recordStartState (compiler );
1515
- compiler .stage1Passes ();
1516
- if (!compiler .hasErrors ()) {
1517
- compiler .stage2Passes (OptimizationPasses .ALL );
1518
- if (!compiler .hasErrors ()) {
1519
- compiler .stage3Passes ();
1520
- }
1521
- }
1522
- compiler .performPostCompilationTasks ();
1523
- }
1524
- } finally {
1525
- // Make sure we generate a report of errors and warnings even if the compiler throws an
1526
- // exception somewhere.
1527
- compiler .generateReport ();
1454
+ /** Call at the end of compilation to save the compiler state if applicable. */
1455
+ private void saveState () {
1456
+ if (config .getSaveCompilationStateToFilename () == null ) {
1457
+ // nothing to save to.
1458
+ return ;
1528
1459
}
1529
- return compiler .getResult ();
1530
- }
1531
-
1532
- private Result instrumentForCoverage (CompileMetricsRecorderInterface metricsRecorder ) {
1533
- metricsRecorder .recordActionName ("instrument for coverage" );
1534
- try {
1535
- compiler .parseForCompilation ();
1536
- if (!compiler .hasErrors ()) {
1537
- metricsRecorder .recordStartState (compiler );
1538
- compiler .instrumentForCoverage ();
1539
- }
1540
- } finally {
1541
- compiler .generateReport ();
1460
+ String filename = config .getSaveCompilationStateToFilename ();
1461
+ try (BufferedOutputStream serializedOutputStream =
1462
+ new BufferedOutputStream (new FileOutputStream (filename ))) {
1463
+ compiler .saveState (serializedOutputStream );
1464
+ } catch (IOException e ) {
1465
+ compiler .report (JSError .make (COULD_NOT_SERIALIZE_AST , filename ));
1542
1466
}
1543
- return compiler .getResult ();
1544
1467
}
1545
1468
1546
1469
/** Processes the results of the compile job, and returns an error code. */
0 commit comments