bool applyReplacements(const FileToReplacementsMap &GroupedReplacements,
                       clang::Rewriter &Rewrites) {

  // Apply all changes
  //
  // FIXME: No longer certain GroupedReplacements is really the best kind of
  // data structure for applying replacements. Rewriter certainly doesn't care.
  // However, until we nail down the design of ReplacementGroups, might as well
  // leave this as is.
  for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
                                             E = GroupedReplacements.end();
       I != E; ++I) {
    if (!tooling::applyAllReplacements(I->getValue(), Rewrites))
      return false;
  }

  return true;
}
예제 #2
0
int main(int argc, char **argv) {
  // Only include our options in -help output.
  StringMap<cl::Option*> OptMap;
  cl::getRegisteredOptions(OptMap);
  const char **EndOpts = OptionsToShow + array_lengthof(OptionsToShow);
  for (StringMap<cl::Option *>::iterator I = OptMap.begin(), E = OptMap.end();
       I != E; ++I) {
    if (std::find(OptionsToShow, EndOpts, I->getKey()) == EndOpts)
      I->getValue()->setHiddenFlag(cl::ReallyHidden);
  }

  cl::SetVersionPrinter(&printVersion);
  cl::ParseCommandLineOptions(argc, argv);

  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
      DiagOpts.getPtr());

  // Determine a formatting style from options.
  format::FormatStyle FormatStyle;
  if (DoFormat)
    FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig, "LLVM");

  TUReplacements TUs;
  TUReplacementFiles TURFiles;

  std::error_code ErrorCode =
      collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics);

  if (ErrorCode) {
    errs() << "Trouble iterating over directory '" << Directory
           << "': " << ErrorCode.message() << "\n";
    return 1;
  }

  // Remove the TUReplacementFiles (triggered by "remove-change-desc-files"
  // command line option) when exiting main().
  std::unique_ptr<ScopedFileRemover> Remover;
  if (RemoveTUReplacementFiles)
    Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics));

  FileManager Files((FileSystemOptions()));
  SourceManager SM(Diagnostics, Files);

  FileToReplacementsMap GroupedReplacements;
  if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
    return 1;

  Rewriter ReplacementsRewriter(SM, LangOptions());

  for (FileToReplacementsMap::const_iterator I = GroupedReplacements.begin(),
                                             E = GroupedReplacements.end();
       I != E; ++I) {

    std::string NewFileData;

    // This shouldn't happen but if a file somehow has no replacements skip to
    // next file.
    if (I->getValue().empty())
      continue;

    if (!applyReplacements(I->getValue(), NewFileData, Diagnostics)) {
      errs() << "Failed to apply replacements to " << I->getKey() << "\n";
      continue;
    }

    // Apply formatting if requested.
    if (DoFormat && !applyFormatting(I->getValue(), NewFileData, NewFileData,
                                     FormatStyle, Diagnostics)) {
      errs() << "Failed to apply reformatting replacements for " << I->getKey()
             << "\n";
      continue;
    }

    // Write new file to disk
    std::string ErrorInfo;
    llvm::raw_fd_ostream FileStream(I->getKey().str().c_str(), ErrorInfo,
                                    llvm::sys::fs::F_Text);
    if (!ErrorInfo.empty()) {
      llvm::errs() << "Could not open " << I->getKey() << " for writing\n";
      continue;
    }

    FileStream << NewFileData;
  }

  return 0;
}