Esempio n. 1
0
bool migrator::updateCodeAndEmitRemap(CompilerInstance *Instance,
                                      const CompilerInvocation &Invocation) {
  // Delete the remap file, in case someone is re-running the Migrator. If the
  // file fails to compile and we don't get a chance to overwrite it, the old
  // changes may get picked up.
  llvm::sys::fs::remove(Invocation.getMigratorOptions().EmitRemapFilePath);

  Migrator M { Instance, Invocation }; // Provide inputs and configuration

  // Phase 1: Pre Fix-it passes
  // These uses the initial frontend invocation to apply any obvious fix-its
  // to see if we can get an error-free AST to get to Phase 2.
  std::unique_ptr<swift::CompilerInstance> PreFixItInstance;
  if (Instance->getASTContext().hadError()) {
    PreFixItInstance = M.repeatFixitMigrations(2,
      Invocation.getLangOptions().EffectiveLanguageVersion);

    // If we still couldn't fix all of the errors, give up.
    if (PreFixItInstance == nullptr ||
        !PreFixItInstance->hasASTContext() ||
        PreFixItInstance->getASTContext().hadError()) {
      return true;
    }
    M.StartInstance = PreFixItInstance.get();
  }

  // Phase 2: Syntactic Transformations
  auto FailedSyntacticPasses = M.performSyntacticPasses();
  if (FailedSyntacticPasses) {
    return true;
  }

  // Phase 3: Post Fix-it Passes
  // Perform fix-it based migrations on the compiler, some number of times in
  // order to give the compiler an opportunity to
  // take its time reaching a fixed point.
  // This is the end of the pipeline, so we throw away the compiler instance(s)
  // we used in these fix-it runs.

  if (M.getMigratorOptions().EnableMigratorFixits) {
    M.repeatFixitMigrations(Migrator::MaxCompilerFixitPassIterations,
                            {4, 0, 0});
  }

  // OK, we have a final resulting text. Now we compare against the input
  // to calculate a replacement map describing the changes to the input
  // necessary to get the output.
  // TODO: Document replacement map format.


  auto EmitRemapFailed = M.emitRemap();
  auto EmitMigratedFailed = M.emitMigratedFile();
  auto DumpMigrationStatesFailed = M.dumpStates();
  return EmitRemapFailed || EmitMigratedFailed || DumpMigrationStatesFailed;
}