1f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===--- Refactoring.cpp - Framework for clang refactoring tools ----------===// 2f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 3f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// The LLVM Compiler Infrastructure 4f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 5f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// This file is distributed under the University of Illinois Open Source 6f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// License. See LICENSE.TXT for details. 7f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 8f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===----------------------------------------------------------------------===// 9f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 10f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// Implements tools to support refactorings. 11f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek// 12f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek//===----------------------------------------------------------------------===// 13f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 1402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h" 15f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/FileManager.h" 16f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Basic/SourceManager.h" 174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Format/Format.h" 18f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Frontend/TextDiagnosticPrinter.h" 19f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Lex/Lexer.h" 20305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Core/Rewriter.h" 21f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek#include "clang/Tooling/Refactoring.h" 22d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal#include "llvm/Support/FileSystem.h" 23d11344a728c7ffab17e5557506edfbcbae18d34eAriel J. Bernal#include "llvm/Support/Path.h" 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_os_ostream.h" 25f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 26f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace clang { 27f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimeknamespace tooling { 28f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 2987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarRefactoringTool::RefactoringTool( 3087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths, 3187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::shared_ptr<PCHContainerOperations> PCHContainerOps) 3287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : ClangTool(Compilations, SourcePaths, PCHContainerOps) {} 33f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 34f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel KlimekReplacements &RefactoringTool::getReplacements() { return Replace; } 35f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 36d088a5f966c31462280d5ace29febc6889834611Edwin Vaneint RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) { 37d088a5f966c31462280d5ace29febc6889834611Edwin Vane if (int Result = run(ActionFactory)) { 38d088a5f966c31462280d5ace29febc6889834611Edwin Vane return Result; 39d088a5f966c31462280d5ace29febc6889834611Edwin Vane } 40d088a5f966c31462280d5ace29febc6889834611Edwin Vane 41f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek LangOptions DefaultLangOptions; 4202c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 4302c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts); 44f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek DiagnosticsEngine Diagnostics( 45cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), 4602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor &*DiagOpts, &DiagnosticPrinter, false); 47d088a5f966c31462280d5ace29febc6889834611Edwin Vane SourceManager Sources(Diagnostics, getFiles()); 48f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek Rewriter Rewrite(Sources, DefaultLangOptions); 49d088a5f966c31462280d5ace29febc6889834611Edwin Vane 50d088a5f966c31462280d5ace29febc6889834611Edwin Vane if (!applyAllReplacements(Rewrite)) { 51f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek llvm::errs() << "Skipped some replacements.\n"; 52f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek } 53d088a5f966c31462280d5ace29febc6889834611Edwin Vane 54d088a5f966c31462280d5ace29febc6889834611Edwin Vane return saveRewrittenFiles(Rewrite); 55d088a5f966c31462280d5ace29febc6889834611Edwin Vane} 56d088a5f966c31462280d5ace29febc6889834611Edwin Vane 57d088a5f966c31462280d5ace29febc6889834611Edwin Vanebool RefactoringTool::applyAllReplacements(Rewriter &Rewrite) { 58d088a5f966c31462280d5ace29febc6889834611Edwin Vane return tooling::applyAllReplacements(Replace, Rewrite); 59d088a5f966c31462280d5ace29febc6889834611Edwin Vane} 60d088a5f966c31462280d5ace29febc6889834611Edwin Vane 61d088a5f966c31462280d5ace29febc6889834611Edwin Vaneint RefactoringTool::saveRewrittenFiles(Rewriter &Rewrite) { 626bf97fb15c09db9a0238ccb73be2dbf9cd77a7eeAlp Toker return Rewrite.overwriteChangedFiles() ? 1 : 0; 63f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} 64f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek 654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool formatAndApplyAllReplacements(const Replacements &Replaces, 664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Rewriter &Rewrite, StringRef Style) { 674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SourceManager &SM = Rewrite.getSourceMgr(); 684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar FileManager &Files = SM.getFileManager(); 694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto FileToReplaces = groupReplacementsByFile(Replaces); 714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool Result = true; 734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (const auto &FileAndReplaces : FileToReplaces) { 744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const std::string &FilePath = FileAndReplaces.first; 754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto &CurReplaces = FileAndReplaces.second; 764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const FileEntry *Entry = Files.getFile(FilePath); 784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar FileID ID = SM.getOrCreateFileID(Entry, SrcMgr::C_User); 794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar StringRef Code = SM.getBufferData(ID); 804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar format::FormatStyle CurStyle = format::getStyle(Style, FilePath, "LLVM"); 824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto NewReplacements = 834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar format::formatReplacements(Code, CurReplaces, CurStyle); 844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!NewReplacements) { 854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::errs() << llvm::toString(NewReplacements.takeError()) << "\n"; 864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Result = applyAllReplacements(*NewReplacements, Rewrite) && Result; 894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Result; 914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 93f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace tooling 94f9d4cbd3dd1eb4cf3ec3c5ec7acc310415beeefdManuel Klimek} // end namespace clang 95