summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-05-16 10:40:07 +0000
committerDaniel Jasper <djasper@google.com>2013-05-16 10:40:07 +0000
commitec04c0dba0b2ca2ad6906009e8eca54928b99c46 (patch)
tree90b56b68a2c79a436457b6cdf858c147c17b732f /clang/lib/Tooling
parentf9eb9b18830349057d4608ecbac2077e84906f5c (diff)
downloadbcm5719-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.cpp57
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) {}
OpenPOWER on IntegriCloud