bool formatAndApplyAllReplacements( const std::map<std::string, Replacements> &FileToReplaces, Rewriter &Rewrite, StringRef Style) { SourceManager &SM = Rewrite.getSourceMgr(); FileManager &Files = SM.getFileManager(); bool Result = true; for (const auto &FileAndReplaces : groupReplacementsByFile(FileToReplaces)) { const std::string &FilePath = FileAndReplaces.first; auto &CurReplaces = FileAndReplaces.second; const FileEntry *Entry = Files.getFile(FilePath); FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User); StringRef Code = SM.getBufferData(ID); format::FormatStyle CurStyle = format::getStyle(Style, FilePath, "LLVM"); auto NewReplacements = format::formatReplacements(Code, CurReplaces, CurStyle); if (!NewReplacements) { llvm::errs() << llvm::toString(NewReplacements.takeError()) << "\n"; return false; } Result = applyAllReplacements(*NewReplacements, Rewrite) && Result; } return Result; }
extern "C" void TestOneInput(uint8_t *data, size_t size) { // FIXME: fuzz more things: different styles, different style features. std::string s((const char *)data, size); auto Style = getGoogleStyle(clang::format::FormatStyle::LK_Cpp); Style.ColumnLimit = 60; applyAllReplacements(s, clang::format::reformat( Style, s, {clang::tooling::Range(0, s.size())})); }
TEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) { FileID ID = createFile("input.cpp", "line1\nline2\nline3\nline4"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_FALSE(Context.Rewrite.overwriteChangedFiles()); EXPECT_EQ("line1\nreplaced\nline3\nline4", getFileContentFromDisk("input.cpp")); }
static std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length, const FormatStyle &Style) { DEBUG(llvm::errs() << "---\n"); DEBUG(llvm::errs() << Code << "\n\n"); std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); tooling::Replacements Replaces = reformat(Style, Code, Ranges); std::string Result = applyAllReplacements(Code, Replaces); EXPECT_NE("", Result); DEBUG(llvm::errs() << "\n" << Result << "\n\n"); return Result; }
TEST_F(ReplacementTest, CanApplyReplacements) { FileID ID = Context.createInMemoryFile("input.cpp", "line1\nline2\nline3\nline4"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 2, 1), 5, "replaced")); Replaces.insert(Replacement(Context.Sources, Context.getLocation(ID, 3, 1), 5, "other")); EXPECT_TRUE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_EQ("line1\nreplaced\nother\nline4", Context.getRewrittenText(ID)); }
static std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length, const FormatStyle &Style) { LLVM_DEBUG(llvm::errs() << "---\n"); LLVM_DEBUG(llvm::errs() << Code << "\n\n"); std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); tooling::Replacements Replaces = reformat(Style, Code, Ranges); auto Result = applyAllReplacements(Code, Replaces); EXPECT_TRUE(static_cast<bool>(Result)); LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); return *Result; }
TEST_F(ReplacementTest, ApplyAllFailsIfOneApplyFails) { // This test depends on the value of the file name of an invalid source // location being in the range ]a, z[. FileID IDa = Context.createInMemoryFile("a.cpp", "text"); FileID IDz = Context.createInMemoryFile("z.cpp", "text"); Replacements Replaces; Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDa, 1, 1), 4, "a")); Replaces.insert(Replacement(Context.Sources, SourceLocation(), 5, "2")); Replaces.insert(Replacement(Context.Sources, Context.getLocation(IDz, 1, 1), 4, "z")); EXPECT_FALSE(applyAllReplacements(Replaces, Context.Rewrite)); EXPECT_EQ("a", Context.getRewrittenText(IDa)); EXPECT_EQ("z", Context.getRewrittenText(IDz)); }
std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length, const FormatStyle &Style) { RewriterTestContext Context; FileID ID = Context.createInMemoryFile("input.cc", Code); SourceLocation Start = Context.Sources.getLocForStartOfFile(ID).getLocWithOffset(Offset); std::vector<CharSourceRange> Ranges( 1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length))); LangOptions LangOpts; LangOpts.CPlusPlus = 1; Lexer Lex(ID, Context.Sources.getBuffer(ID), Context.Sources, LangOpts); tooling::Replacements Replace = reformat(Style, Lex, Context.Sources, Ranges); EXPECT_TRUE(applyAllReplacements(Replace, Context.Rewrite)); return Context.getRewrittenText(ID); }
std::string RefactoringTool::transform(CustomToolInvocation& invocation, clang::tooling::FrontendActionFactory *actionFactory) { invocation.run(actionFactory->create()); //create rewriter clang::LangOptions defaultLangOptions; clang::Rewriter rewriter(invocation.getSources(), defaultLangOptions); if (_replacements.empty()) { return invocation.code(); } // apply replacements applyAllReplacements(_replacements, rewriter); // create replacements _replacements.clear(); // write replacements to buffer return writeReplacements(rewriter); }
int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) { if (int Result = run(ActionFactory)) { return Result; } LangOptions DefaultLangOptions; IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts); DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts, &DiagnosticPrinter, false); SourceManager Sources(Diagnostics, getFiles()); Rewriter Rewrite(Sources, DefaultLangOptions); if (!applyAllReplacements(Rewrite)) { llvm::errs() << "Skipped some replacements.\n"; } return saveRewrittenFiles(Rewrite); }
int RefactoringTool::run(FrontendActionFactory *ActionFactory) { int Result = Tool.run(ActionFactory); LangOptions DefaultLangOptions; DiagnosticOptions DefaultDiagnosticOptions; TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions); DiagnosticsEngine Diagnostics( llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &DiagnosticPrinter, false); SourceManager Sources(Diagnostics, Tool.getFiles()); Rewriter Rewrite(Sources, DefaultLangOptions); if (!applyAllReplacements(Replace, Rewrite)) { llvm::errs() << "Skipped some replacements.\n"; } if (!saveRewrittenFiles(Rewrite)) { llvm::errs() << "Could not save rewritten files.\n"; return 1; } return Result; }