diff options
author | Daniel Jasper <djasper@google.com> | 2013-05-16 10:40:07 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-05-16 10:40:07 +0000 |
commit | ec04c0dba0b2ca2ad6906009e8eca54928b99c46 (patch) | |
tree | 90b56b68a2c79a436457b6cdf858c147c17b732f /clang/lib/Tooling | |
parent | f9eb9b18830349057d4608ecbac2077e84906f5c (diff) | |
download | bcm5719-llvm-ec04c0dba0b2ca2ad6906009e8eca54928b99c46.tar.gz bcm5719-llvm-ec04c0dba0b2ca2ad6906009e8eca54928b99c46.zip |
Add a more convenient interface to use clang-format.
It turns out that several implementations go through the trouble of
setting up a SourceManager and Lexer and abstracting this into a
function makes usage easier.
Also abstracts SourceManager-independent ranges out of
tooling::Refactoring and provides a convenience function to create them
from line ranges.
llvm-svn: 181997
Diffstat (limited to 'clang/lib/Tooling')
-rw-r--r-- | clang/lib/Tooling/Refactoring.cpp | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp index d8440d639d0..f795def74ff 100644 --- a/clang/lib/Tooling/Refactoring.cpp +++ b/clang/lib/Tooling/Refactoring.cpp @@ -26,12 +26,12 @@ namespace tooling { static const char * const InvalidLocation = ""; Replacement::Replacement() - : FilePath(InvalidLocation), Offset(0), Length(0) {} + : FilePath(InvalidLocation) {} -Replacement::Replacement(StringRef FilePath, unsigned Offset, - unsigned Length, StringRef ReplacementText) - : FilePath(FilePath), Offset(Offset), - Length(Length), ReplacementText(ReplacementText) {} +Replacement::Replacement(StringRef FilePath, unsigned Offset, unsigned Length, + StringRef ReplacementText) + : FilePath(FilePath), ReplacementRange(Offset, Length), + ReplacementText(ReplacementText) {} Replacement::Replacement(SourceManager &Sources, SourceLocation Start, unsigned Length, StringRef ReplacementText) { @@ -62,11 +62,12 @@ bool Replacement::apply(Rewriter &Rewrite) const { // the remapping API is not public in the RewriteBuffer. const SourceLocation Start = SM.getLocForStartOfFile(ID). - getLocWithOffset(Offset); + getLocWithOffset(ReplacementRange.getOffset()); // ReplaceText returns false on success. // ReplaceText only fails if the source location is not a file location, in // which case we already returned false earlier. - bool RewriteSucceeded = !Rewrite.ReplaceText(Start, Length, ReplacementText); + bool RewriteSucceeded = !Rewrite.ReplaceText( + Start, ReplacementRange.getLength(), ReplacementText); assert(RewriteSucceeded); return RewriteSucceeded; } @@ -74,16 +75,18 @@ bool Replacement::apply(Rewriter &Rewrite) const { std::string Replacement::toString() const { std::string result; llvm::raw_string_ostream stream(result); - stream << FilePath << ": " << Offset << ":+" << Length - << ":\"" << ReplacementText << "\""; + stream << FilePath << ": " << ReplacementRange.getOffset() << ":+" + << ReplacementRange.getLength() << ":\"" << ReplacementText << "\""; return result; } bool Replacement::Less::operator()(const Replacement &R1, const Replacement &R2) const { if (R1.FilePath != R2.FilePath) return R1.FilePath < R2.FilePath; - if (R1.Offset != R2.Offset) return R1.Offset < R2.Offset; - if (R1.Length != R2.Length) return R1.Length < R2.Length; + if (R1.ReplacementRange.getOffset() != R2.ReplacementRange.getOffset()) + return R1.ReplacementRange.getOffset() < R2.ReplacementRange.getOffset(); + if (R1.ReplacementRange.getLength() != R2.ReplacementRange.getLength()) + return R1.ReplacementRange.getLength() < R2.ReplacementRange.getLength(); return R1.ReplacementText < R2.ReplacementText; } @@ -94,8 +97,7 @@ void Replacement::setFromSourceLocation(SourceManager &Sources, Sources.getDecomposedLoc(Start); const FileEntry *Entry = Sources.getFileEntryForID(DecomposedLocation.first); this->FilePath = Entry != NULL ? Entry->getName() : InvalidLocation; - this->Offset = DecomposedLocation.second; - this->Length = Length; + this->ReplacementRange = Range(DecomposedLocation.second, Length); this->ReplacementText = ReplacementText; } @@ -135,6 +137,35 @@ bool applyAllReplacements(Replacements &Replaces, Rewriter &Rewrite) { return Result; } +std::string applyAllReplacements(StringRef Code, Replacements &Replaces) { + FileManager Files((FileSystemOptions())); + DiagnosticsEngine Diagnostics( + IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), + new DiagnosticOptions); + Diagnostics.setClient(new TextDiagnosticPrinter( + llvm::outs(), &Diagnostics.getDiagnosticOptions())); + SourceManager SourceMgr(Diagnostics, Files); + Rewriter Rewrite(SourceMgr, LangOptions()); + llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, "<stdin>"); + const clang::FileEntry *Entry = + Files.getVirtualFile("<stdin>", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(Entry, Buf); + FileID ID = + SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User); + for (Replacements::iterator I = Replaces.begin(), E = Replaces.end(); I != E; + ++I) { + Replacement Replace("<stdin>", I->getOffset(), I->getLength(), + I->getReplacementText()); + if (!Replace.apply(Rewrite)) + return ""; + } + std::string Result; + llvm::raw_string_ostream OS(Result); + Rewrite.getEditBuffer(ID).write(OS); + OS.flush(); + return Result; +} + RefactoringTool::RefactoringTool(const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths) : ClangTool(Compilations, SourcePaths) {} |