Future _createKernelIfNeeded()

in build_runner/lib/src/build_script_generate/bootstrap.dart [136:217]


Future<int> _createKernelIfNeeded(Logger logger) async {
  var assetGraphFile = File(assetGraphPathFor(scriptKernelLocation));
  var kernelFile = File(scriptKernelLocation);
  var kernelCacheFile = File(scriptKernelCachedLocation);

  if (await kernelFile.exists()) {
    // If we failed to serialize an asset graph for the snapshot, then we don't
    // want to re-use it because we can't check if it is up to date.
    if (!await assetGraphFile.exists()) {
      await kernelFile.rename(scriptKernelCachedLocation);
      logger.warning(
          'Invalidated precompiled build script due to missing asset graph.');
    } else if (!await _checkImportantPackageDeps()) {
      await kernelFile.rename(scriptKernelCachedLocation);
      logger.warning(
          'Invalidated precompiled build script due to core package update');
    }
  }

  if (!await kernelFile.exists()) {
    final client = await FrontendServerClient.start(
      scriptLocation,
      scriptKernelCachedLocation,
      'lib/_internal/vm_platform_strong.dill',
      printIncrementalDependencies: false,
    );

    var hadOutput = false;
    var hadErrors = false;
    await logTimedAsync(logger, 'Precompiling build script...', () async {
      try {
        final result = await client.compile();
        hadErrors = result == null ||
            result.errorCount > 0 ||
            !(await kernelCacheFile.exists());

        // Note: We're logging all output with a single log call to keep
        // annotated source spans intact.
        final logOutput = result?.compilerOutputLines.join('\n');
        if (logOutput != null && logOutput.isNotEmpty) {
          hadOutput = true;
          if (hadErrors) {
            // Always show compiler output if there were errors
            logger.warning(logOutput);
          } else {
            logger.fine(logOutput);
          }
        }
      } finally {
        client.kill();
      }
    });

    // For some compilation errors, the frontend inserts an "invalid
    // expression" which throws at runtime. When running those kernel files
    // with an onError receive port, the VM can crash (dartbug.com/45865).
    //
    // In this case we leave the cached kernel file in tact so future compiles
    // are faster, but don't copy it over to the real location.
    if (!hadErrors) {
      await kernelCacheFile.rename(scriptKernelLocation);
      if (hadOutput) {
        logger.info(
          'There was output on stdout while precompiling the build script; run '
          'with `--verbose` to see it (you will need to run a `clean` first to '
          're-generate it).\n',
        );
      }
    }

    if (!await kernelFile.exists()) {
      logger.severe('''
Failed to precompile build script $scriptLocation.
This is likely caused by a misconfigured builder definition.
''');
      return ExitCode.config.code;
    }
    // Create _previousLocationsFile.
    await _checkImportantPackageDeps();
  }
  return 0;
}