diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-03-06 20:06:33 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-03-06 20:06:33 +0000 |
commit | 30660a898545416f0fea2d717f16f75640001e38 (patch) | |
tree | a8408d8c12d992b4110fca1bfe78f337b48f5d11 /lib/Frontend/DiagnosticRenderer.cpp | |
parent | 2a253960f0312c9759965a1defb9326d6b2764a4 (diff) |
Add new code migrator support for migrating existing Objective-C code to use
the new Objective-C NSArray/NSDictionary/NSNumber literal syntax.
This introduces a new library, libEdit, which provides a new way to support
migration of code that improves on the original ARC migrator. We now believe
that most of its functionality can be refactored into the existing libraries,
and thus this new library may shortly disappear.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152141 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/DiagnosticRenderer.cpp')
-rw-r--r-- | lib/Frontend/DiagnosticRenderer.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index 29f9ed5a7d..6c3bb1d695 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -12,6 +12,9 @@ #include "clang/Basic/SourceManager.h" #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Lex/Lexer.h" +#include "clang/Edit/EditedSource.h" +#include "clang/Edit/Commit.h" +#include "clang/Edit/EditsReceiver.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" @@ -127,6 +130,54 @@ DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM, DiagnosticRenderer::~DiagnosticRenderer() {} +namespace { + +class FixitReceiver : public edit::EditsReceiver { + SmallVectorImpl<FixItHint> &MergedFixits; + +public: + FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) + : MergedFixits(MergedFixits) { } + virtual void insert(SourceLocation loc, StringRef text) { + MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); + } + virtual void replace(CharSourceRange range, StringRef text) { + MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); + } +}; + +} + +static void mergeFixits(ArrayRef<FixItHint> FixItHints, + const SourceManager &SM, const LangOptions &LangOpts, + SmallVectorImpl<FixItHint> &MergedFixits) { + edit::Commit commit(SM, LangOpts); + for (ArrayRef<FixItHint>::const_iterator + I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { + const FixItHint &Hint = *I; + if (Hint.CodeToInsert.empty()) { + if (Hint.InsertFromRange.isValid()) + commit.insertFromRange(Hint.RemoveRange.getBegin(), + Hint.InsertFromRange, /*afterToken=*/false, + Hint.BeforePreviousInsertions); + else + commit.remove(Hint.RemoveRange); + } else { + if (Hint.RemoveRange.isTokenRange() || + Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd()) + commit.replace(Hint.RemoveRange, Hint.CodeToInsert); + else + commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, + /*afterToken=*/false, Hint.BeforePreviousInsertions); + } + } + + edit::EditedSource Editor(SM, LangOpts); + if (Editor.commit(commit)) { + FixitReceiver Rec(MergedFixits); + Editor.applyRewrites(Rec); + } +} void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level, @@ -152,6 +203,12 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), Ranges.end()); + llvm::SmallVector<FixItHint, 8> MergedFixits; + if (!FixItHints.empty()) { + mergeFixits(FixItHints, SM, LangOpts, MergedFixits); + FixItHints = MergedFixits; + } + for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) |