summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2016-03-01 12:37:30 +0000
committerManuel Klimek <klimek@google.com>2016-03-01 12:37:30 +0000
commitb12e5a5ccd8e5ca71a3722a4b5103a794ca5515f (patch)
tree2be713f424b906e73a5320edca75855f6b37226e /clang/lib
parent109702ccb16f33a5b0305a1d1287413c9a88adca (diff)
downloadbcm5719-llvm-b12e5a5ccd8e5ca71a3722a4b5103a794ca5515f.tar.gz
bcm5719-llvm-b12e5a5ccd8e5ca71a3722a4b5103a794ca5515f.zip
Add functions to apply replacements and reformat them.
This is a commonly useful feature to have, and we have implemented it multiple times with different kinds of bugs. This implementation centralizes the idea in a set of functions that we can then use from the various tools. Reverts r262234, which is a revert of r262232, and puts the functions into FOrmat.h, as they are closely coupled to clang-format, and we otherwise introduce a cyclic dependency between libFormat and libTooling. Patch by Eric Liu. llvm-svn: 262323
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Format/Format.cpp28
-rw-r--r--clang/lib/Tooling/Core/Replacement.cpp17
2 files changed, 43 insertions, 2 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 85a0152e295..9d5c0bca335 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1884,6 +1884,34 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
return Replaces;
}
+tooling::Replacements formatReplacements(StringRef Code,
+ const tooling::Replacements &Replaces,
+ const FormatStyle &Style) {
+ if (Replaces.empty())
+ return tooling::Replacements();
+
+ std::string NewCode = applyAllReplacements(Code, Replaces);
+ std::vector<tooling::Range> ChangedRanges =
+ tooling::calculateChangedRangesInFile(Replaces);
+ StringRef FileName = Replaces.begin()->getFilePath();
+ tooling::Replacements FormatReplaces =
+ reformat(Style, NewCode, ChangedRanges, FileName);
+
+ tooling::Replacements MergedReplacements =
+ mergeReplacements(Replaces, FormatReplaces);
+ return MergedReplacements;
+}
+
+std::string applyAllReplacementsAndFormat(StringRef Code,
+ const tooling::Replacements &Replaces,
+ const FormatStyle &Style) {
+ tooling::Replacements NewReplacements =
+ formatReplacements(Code, Replaces, Style);
+ if (NewReplacements.empty())
+ return Code; // Exit early to avoid overhead in `applyAllReplacements`.
+ return applyAllReplacements(Code, NewReplacements);
+}
+
tooling::Replacements reformat(const FormatStyle &Style,
SourceManager &SourceMgr, FileID ID,
ArrayRef<CharSourceRange> Ranges,
diff --git a/clang/lib/Tooling/Core/Replacement.cpp b/clang/lib/Tooling/Core/Replacement.cpp
index 47bbdeb470e..6226cf285b2 100644
--- a/clang/lib/Tooling/Core/Replacement.cpp
+++ b/clang/lib/Tooling/Core/Replacement.cpp
@@ -11,6 +11,8 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Tooling/Core/Replacement.h"
+
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
@@ -18,7 +20,6 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Tooling/Core/Replacement.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_os_ostream.h"
@@ -281,6 +282,18 @@ std::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
return Result;
}
+std::vector<Range> calculateChangedRangesInFile(const Replacements &Replaces) {
+ std::vector<Range> ChangedRanges;
+ int Shift = 0;
+ for (const Replacement &R : Replaces) {
+ unsigned Offset = R.getOffset() + Shift;
+ unsigned Length = R.getReplacementText().size();
+ Shift += Length - R.getLength();
+ ChangedRanges.push_back(Range(Offset, Length));
+ }
+ return ChangedRanges;
+}
+
namespace {
// Represents a merged replacement, i.e. a replacement consisting of multiple
// overlapping replacements from 'First' and 'Second' in mergeReplacements.
@@ -314,7 +327,7 @@ public:
// Merges the next element 'R' into this merged element. As we always merge
// from 'First' into 'Second' or vice versa, the MergedReplacement knows what
- // set the next element is coming from.
+ // set the next element is coming from.
void merge(const Replacement &R) {
if (MergeSecond) {
unsigned REnd = R.getOffset() + Delta + R.getLength();
OpenPOWER on IntegriCloud