Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit a45abc6

Browse files
author
Eric Liu
committed
Make tooling::applyAllReplacements return llvm::Expected<string> instead of empty string to indicate potential error.
Summary: return llvm::Expected<> to carry error status and error information. This is the first step towards introducing "Error" into tooling::Replacements. Reviewers: djasper, klimek Subscribers: ioeric, klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D21601 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@275062 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 481ab3b commit a45abc6

16 files changed

+131
-102
lines changed

Diff for: include/clang/Format/Format.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -770,16 +770,18 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
770770
unsigned *Cursor = nullptr);
771771

772772
/// \brief Returns the replacements corresponding to applying and formatting
773-
/// \p Replaces.
774-
tooling::Replacements formatReplacements(StringRef Code,
775-
const tooling::Replacements &Replaces,
776-
const FormatStyle &Style);
773+
/// \p Replaces on success; otheriwse, return an llvm::Error carrying
774+
/// llvm::StringError.
775+
llvm::Expected<tooling::Replacements>
776+
formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
777+
const FormatStyle &Style);
777778

778779
/// \brief Returns the replacements corresponding to applying \p Replaces and
779-
/// cleaning up the code after that.
780+
/// cleaning up the code after that on success; otherwise, return an llvm::Error
781+
/// carrying llvm::StringError.
780782
/// This also inserts a C++ #include directive into the correct block if the
781783
/// replacement corresponding to the header insertion has offset UINT_MAX.
782-
tooling::Replacements
784+
llvm::Expected<tooling::Replacements>
783785
cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
784786
const FormatStyle &Style);
785787

Diff for: include/clang/Tooling/Core/Replacement.h

+8-26
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/Basic/LangOptions.h"
2323
#include "clang/Basic/SourceLocation.h"
2424
#include "llvm/ADT/StringRef.h"
25+
#include "llvm/Support/Error.h"
2526
#include <map>
2627
#include <set>
2728
#include <string>
@@ -165,9 +166,13 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces,
165166

166167
/// \brief Applies all replacements in \p Replaces to \p Code.
167168
///
168-
/// This completely ignores the path stored in each replacement. If one or more
169-
/// replacements cannot be applied, this returns an empty \c string.
170-
std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
169+
/// This completely ignores the path stored in each replacement. If all
170+
/// replacements are applied successfully, this returns the code with
171+
/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError
172+
/// is returned (the Error message can be converted to string using
173+
/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored).
174+
llvm::Expected<std::string> applyAllReplacements(StringRef Code,
175+
const Replacements &Replaces);
171176

172177
/// \brief Calculates how a code \p Position is shifted when \p Replaces are
173178
/// applied.
@@ -203,29 +208,6 @@ struct TranslationUnitReplacements {
203208
std::vector<Replacement> Replacements;
204209
};
205210

206-
/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
207-
///
208-
/// Replacement applications happen independently of the success of
209-
/// other applications.
210-
///
211-
/// \returns true if all replacements apply. false otherwise.
212-
bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
213-
214-
/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
215-
///
216-
/// Replacement applications happen independently of the success of
217-
/// other applications.
218-
///
219-
/// \returns true if all replacements apply. false otherwise.
220-
bool applyAllReplacements(const std::vector<Replacement> &Replaces,
221-
Rewriter &Rewrite);
222-
223-
/// \brief Applies all replacements in \p Replaces to \p Code.
224-
///
225-
/// This completely ignores the path stored in each replacement. If one or more
226-
/// replacements cannot be applied, this returns an empty \c string.
227-
std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
228-
229211
/// \brief Calculates the ranges in a single file that are affected by the
230212
/// Replacements. Overlapping ranges will be merged.
231213
///

Diff for: lib/Format/Format.cpp

+13-9
Original file line numberDiff line numberDiff line change
@@ -1393,36 +1393,40 @@ tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
13931393
}
13941394

13951395
template <typename T>
1396-
static tooling::Replacements
1396+
static llvm::Expected<tooling::Replacements>
13971397
processReplacements(T ProcessFunc, StringRef Code,
13981398
const tooling::Replacements &Replaces,
13991399
const FormatStyle &Style) {
14001400
if (Replaces.empty())
14011401
return tooling::Replacements();
14021402

1403-
std::string NewCode = applyAllReplacements(Code, Replaces);
1403+
auto NewCode = applyAllReplacements(Code, Replaces);
1404+
if (!NewCode)
1405+
return NewCode.takeError();
14041406
std::vector<tooling::Range> ChangedRanges =
14051407
tooling::calculateChangedRanges(Replaces);
14061408
StringRef FileName = Replaces.begin()->getFilePath();
14071409

14081410
tooling::Replacements FormatReplaces =
1409-
ProcessFunc(Style, NewCode, ChangedRanges, FileName);
1411+
ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
14101412

14111413
return mergeReplacements(Replaces, FormatReplaces);
14121414
}
14131415

1414-
tooling::Replacements formatReplacements(StringRef Code,
1415-
const tooling::Replacements &Replaces,
1416-
const FormatStyle &Style) {
1416+
llvm::Expected<tooling::Replacements>
1417+
formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
1418+
const FormatStyle &Style) {
14171419
// We need to use lambda function here since there are two versions of
14181420
// `sortIncludes`.
14191421
auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
14201422
std::vector<tooling::Range> Ranges,
14211423
StringRef FileName) -> tooling::Replacements {
14221424
return sortIncludes(Style, Code, Ranges, FileName);
14231425
};
1424-
tooling::Replacements SortedReplaces =
1426+
auto SortedReplaces =
14251427
processReplacements(SortIncludes, Code, Replaces, Style);
1428+
if (!SortedReplaces)
1429+
return SortedReplaces.takeError();
14261430

14271431
// We need to use lambda function here since there are two versions of
14281432
// `reformat`.
@@ -1431,7 +1435,7 @@ tooling::Replacements formatReplacements(StringRef Code,
14311435
StringRef FileName) -> tooling::Replacements {
14321436
return reformat(Style, Code, Ranges, FileName);
14331437
};
1434-
return processReplacements(Reformat, Code, SortedReplaces, Style);
1438+
return processReplacements(Reformat, Code, *SortedReplaces, Style);
14351439
}
14361440

14371441
namespace {
@@ -1591,7 +1595,7 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
15911595

15921596
} // anonymous namespace
15931597

1594-
tooling::Replacements
1598+
llvm::Expected<tooling::Replacements>
15951599
cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
15961600
const FormatStyle &Style) {
15971601
// We need to use lambda function here since there are two versions of

Diff for: lib/Tooling/Core/Replacement.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,10 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces,
249249
return Result;
250250
}
251251

252-
std::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
253-
if (Replaces.empty()) return Code;
252+
llvm::Expected<std::string> applyAllReplacements(StringRef Code,
253+
const Replacements &Replaces) {
254+
if (Replaces.empty())
255+
return Code.str();
254256

255257
IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
256258
new vfs::InMemoryFileSystem);
@@ -269,7 +271,9 @@ std::string applyAllReplacements(StringRef Code, const Replacements &Replaces) {
269271
Replacement Replace("<stdin>", I->getOffset(), I->getLength(),
270272
I->getReplacementText());
271273
if (!Replace.apply(Rewrite))
272-
return "";
274+
return llvm::make_error<llvm::StringError>(
275+
"Failed to apply replacement: " + Replace.toString(),
276+
llvm::inconvertibleErrorCode());
273277
}
274278
std::string Result;
275279
llvm::raw_string_ostream OS(Result);

Diff for: lib/Tooling/Refactoring.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ bool formatAndApplyAllReplacements(const Replacements &Replaces,
7979
StringRef Code = SM.getBufferData(ID);
8080

8181
format::FormatStyle CurStyle = format::getStyle(Style, FilePath, "LLVM");
82-
Replacements NewReplacements =
82+
auto NewReplacements =
8383
format::formatReplacements(Code, CurReplaces, CurStyle);
84-
Result = applyAllReplacements(NewReplacements, Rewrite) && Result;
84+
if (!NewReplacements) {
85+
llvm::errs() << llvm::toString(NewReplacements.takeError()) << "\n";
86+
return false;
87+
}
88+
Result = applyAllReplacements(*NewReplacements, Rewrite) && Result;
8589
}
8690
return Result;
8791
}

Diff for: tools/clang-format/ClangFormat.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,16 @@ static bool format(StringRef FileName) {
257257
unsigned CursorPosition = Cursor;
258258
Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges,
259259
AssumedFileName, &CursorPosition);
260-
std::string ChangedCode =
261-
tooling::applyAllReplacements(Code->getBuffer(), Replaces);
260+
auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
261+
if (!ChangedCode) {
262+
llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
263+
return true;
264+
}
262265
for (const auto &R : Replaces)
263266
Ranges.push_back({R.getOffset(), R.getLength()});
264267

265268
bool IncompleteFormat = false;
266-
Replacements FormatChanges = reformat(FormatStyle, ChangedCode, Ranges,
269+
Replacements FormatChanges = reformat(FormatStyle, *ChangedCode, Ranges,
267270
AssumedFileName, &IncompleteFormat);
268271
Replaces = tooling::mergeReplacements(Replaces, FormatChanges);
269272
if (OutputXML) {

Diff for: unittests/Format/CleanupTest.cpp

+19-9
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ class CleanupTest : public ::testing::Test {
2525
const FormatStyle &Style = getLLVMStyle()) {
2626
tooling::Replacements Replaces = format::cleanup(Style, Code, Ranges);
2727

28-
std::string Result = applyAllReplacements(Code, Replaces);
29-
EXPECT_NE("", Result);
30-
return Result;
28+
auto Result = applyAllReplacements(Code, Replaces);
29+
EXPECT_TRUE(static_cast<bool>(Result));
30+
return *Result;
3131
}
3232
};
3333

@@ -254,16 +254,26 @@ class CleanUpReplacementsTest : public ::testing::Test {
254254

255255
inline std::string apply(StringRef Code,
256256
const tooling::Replacements Replaces) {
257-
return applyAllReplacements(
258-
Code, cleanupAroundReplacements(Code, Replaces, Style));
257+
auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
258+
EXPECT_TRUE(static_cast<bool>(CleanReplaces))
259+
<< llvm::toString(CleanReplaces.takeError()) << "\n";
260+
auto Result = applyAllReplacements(Code, *CleanReplaces);
261+
EXPECT_TRUE(static_cast<bool>(Result));
262+
return *Result;
259263
}
260264

261265
inline std::string formatAndApply(StringRef Code,
262266
const tooling::Replacements Replaces) {
263-
return applyAllReplacements(
264-
Code,
265-
formatReplacements(
266-
Code, cleanupAroundReplacements(Code, Replaces, Style), Style));
267+
268+
auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
269+
EXPECT_TRUE(static_cast<bool>(CleanReplaces))
270+
<< llvm::toString(CleanReplaces.takeError()) << "\n";
271+
auto FormattedReplaces = formatReplacements(Code, *CleanReplaces, Style);
272+
EXPECT_TRUE(static_cast<bool>(FormattedReplaces))
273+
<< llvm::toString(FormattedReplaces.takeError()) << "\n";
274+
auto Result = applyAllReplacements(Code, *FormattedReplaces);
275+
EXPECT_TRUE(static_cast<bool>(Result));
276+
return *Result;
267277
}
268278

269279
int getOffset(StringRef Code, int Line, int Column) {

Diff for: unittests/Format/FormatTest.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ class FormatTest : public ::testing::Test {
4747
EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
4848
}
4949
ReplacementCount = Replaces.size();
50-
std::string Result = applyAllReplacements(Code, Replaces);
51-
EXPECT_NE("", Result);
52-
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
53-
return Result;
50+
auto Result = applyAllReplacements(Code, Replaces);
51+
EXPECT_TRUE(static_cast<bool>(Result));
52+
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
53+
return *Result;
5454
}
5555

5656
FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
@@ -11553,8 +11553,12 @@ TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
1155311553

1155411554
format::FormatStyle Style = format::getLLVMStyle();
1155511555
Style.ColumnLimit = 20; // Set column limit to 20 to increase readibility.
11556-
EXPECT_EQ(Expected, applyAllReplacements(
11557-
Code, formatReplacements(Code, Replaces, Style)));
11556+
auto FormattedReplaces = formatReplacements(Code, Replaces, Style);
11557+
EXPECT_TRUE(static_cast<bool>(FormattedReplaces))
11558+
<< llvm::toString(FormattedReplaces.takeError()) << "\n";
11559+
auto Result = applyAllReplacements(Code, *FormattedReplaces);
11560+
EXPECT_TRUE(static_cast<bool>(Result));
11561+
EXPECT_EQ(Expected, *Result);
1155811562
}
1155911563

1156011564
TEST_F(ReplacementTest, SortIncludesAfterReplacement) {
@@ -11578,8 +11582,12 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) {
1157811582

1157911583
format::FormatStyle Style = format::getLLVMStyle();
1158011584
Style.SortIncludes = true;
11581-
auto FinalReplaces = formatReplacements(Code, Replaces, Style);
11582-
EXPECT_EQ(Expected, applyAllReplacements(Code, FinalReplaces));
11585+
auto FormattedReplaces = formatReplacements(Code, Replaces, Style);
11586+
EXPECT_TRUE(static_cast<bool>(FormattedReplaces))
11587+
<< llvm::toString(FormattedReplaces.takeError()) << "\n";
11588+
auto Result = applyAllReplacements(Code, *FormattedReplaces);
11589+
EXPECT_TRUE(static_cast<bool>(Result));
11590+
EXPECT_EQ(Expected, *Result);
1158311591
}
1158411592

1158511593
} // end namespace

Diff for: unittests/Format/FormatTestJS.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class FormatTestJS : public ::testing::Test {
2828
tooling::Replacements Replaces =
2929
reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
3030
EXPECT_FALSE(IncompleteFormat);
31-
std::string Result = applyAllReplacements(Code, Replaces);
32-
EXPECT_NE("", Result);
33-
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
34-
return Result;
31+
auto Result = applyAllReplacements(Code, Replaces);
32+
EXPECT_TRUE(static_cast<bool>(Result));
33+
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
34+
return *Result;
3535
}
3636

3737
static std::string format(

Diff for: unittests/Format/FormatTestJava.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class FormatTestJava : public ::testing::Test {
2525
DEBUG(llvm::errs() << Code << "\n\n");
2626
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
2727
tooling::Replacements Replaces = reformat(Style, Code, Ranges);
28-
std::string Result = applyAllReplacements(Code, Replaces);
29-
EXPECT_NE("", Result);
30-
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
31-
return Result;
28+
auto Result = applyAllReplacements(Code, Replaces);
29+
EXPECT_TRUE(static_cast<bool>(Result));
30+
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
31+
return *Result;
3232
}
3333

3434
static std::string

Diff for: unittests/Format/FormatTestProto.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class FormatTestProto : public ::testing::Test {
2525
DEBUG(llvm::errs() << Code << "\n\n");
2626
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
2727
tooling::Replacements Replaces = reformat(Style, Code, Ranges);
28-
std::string Result = applyAllReplacements(Code, Replaces);
29-
EXPECT_NE("", Result);
30-
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
31-
return Result;
28+
auto Result = applyAllReplacements(Code, Replaces);
29+
EXPECT_TRUE(static_cast<bool>(Result));
30+
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
31+
return *Result;
3232
}
3333

3434
static std::string format(llvm::StringRef Code) {

Diff for: unittests/Format/FormatTestSelective.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class FormatTestSelective : public ::testing::Test {
2828
tooling::Replacements Replaces =
2929
reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
3030
EXPECT_FALSE(IncompleteFormat) << Code << "\n\n";
31-
std::string Result = applyAllReplacements(Code, Replaces);
32-
EXPECT_NE("", Result);
33-
DEBUG(llvm::errs() << "\n" << Result << "\n\n");
34-
return Result;
31+
auto Result = applyAllReplacements(Code, Replaces);
32+
EXPECT_TRUE(static_cast<bool>(Result));
33+
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
34+
return *Result;
3535
}
3636

3737
FormatStyle Style = getLLVMStyle();

Diff for: unittests/Format/SortImportsTestJS.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ class SortImportsTestJS : public ::testing::Test {
2525
if (Length == 0U)
2626
Length = Code.size() - Offset;
2727
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
28-
std::string Sorted =
28+
auto Sorted =
2929
applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
30-
return applyAllReplacements(Sorted,
31-
reformat(Style, Sorted, Ranges, FileName));
30+
EXPECT_TRUE(static_cast<bool>(Sorted));
31+
auto Formatted = applyAllReplacements(
32+
*Sorted, reformat(Style, *Sorted, Ranges, FileName));
33+
EXPECT_TRUE(static_cast<bool>(Formatted));
34+
return *Formatted;
3235
}
3336

3437
void verifySort(llvm::StringRef Expected, llvm::StringRef Code,

Diff for: unittests/Format/SortIncludesTest.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ class SortIncludesTest : public ::testing::Test {
2626

2727
std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
2828
auto Ranges = GetCodeRange(Code);
29-
std::string Sorted =
29+
auto Sorted =
3030
applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
31-
return applyAllReplacements(Sorted,
32-
reformat(Style, Sorted, Ranges, FileName));
31+
EXPECT_TRUE(static_cast<bool>(Sorted));
32+
auto Result = applyAllReplacements(
33+
*Sorted, reformat(Style, *Sorted, Ranges, FileName));
34+
EXPECT_TRUE(static_cast<bool>(Result));
35+
return *Result;
3336
}
3437

3538
unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {

0 commit comments

Comments
 (0)