This revision was automatically updated to reflect the committed changes. Closed by commit rL283330: [clang-format] append newline after code when inserting new headers at the end… (authored by ioeric).
Changed prior to commit: https://reviews.llvm.org/D21026?vs=73648&id=73651#toc Repository: rL LLVM https://reviews.llvm.org/D21026 Files: cfe/trunk/lib/Format/Format.cpp cfe/trunk/unittests/Format/CleanupTest.cpp Index: cfe/trunk/lib/Format/Format.cpp =================================================================== --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -1662,6 +1662,7 @@ if (CategoryEndOffsets.find(*I) == CategoryEndOffsets.end()) CategoryEndOffsets[*I] = CategoryEndOffsets[*std::prev(I)]; + bool NeedNewLineAtEnd = !Code.empty() && Code.back() != '\n'; for (const auto &R : HeaderInsertions) { auto IncludeDirective = R.getReplacementText(); bool Matched = IncludeRegex.match(IncludeDirective, &Matches); @@ -1680,10 +1681,18 @@ std::string NewInclude = !IncludeDirective.endswith("\n") ? (IncludeDirective + "\n").str() : IncludeDirective.str(); + // When inserting headers at end of the code, also append '\n' to the code + // if it does not end with '\n'. + if (NeedNewLineAtEnd && Offset == Code.size()) { + NewInclude = "\n" + NewInclude; + NeedNewLineAtEnd = false; + } auto NewReplace = tooling::Replacement(FileName, Offset, 0, NewInclude); auto Err = Result.add(NewReplace); if (Err) { llvm::consumeError(std::move(Err)); + unsigned NewOffset = Result.getShiftedCodePosition(Offset); + NewReplace = tooling::Replacement(FileName, NewOffset, 0, NewInclude); Result = Result.merge(tooling::Replacements(NewReplace)); } } Index: cfe/trunk/unittests/Format/CleanupTest.cpp =================================================================== --- cfe/trunk/unittests/Format/CleanupTest.cpp +++ cfe/trunk/unittests/Format/CleanupTest.cpp @@ -709,16 +709,24 @@ EXPECT_EQ(Expected, apply(Code, Replaces)); } -// FIXME: although this case does not crash, the insertion is wrong. A '\n' -// should be inserted between the two #includes. TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCode) { std::string Code = "#include <map>"; - std::string Expected = "#include <map>#include <vector>\n"; + std::string Expected = "#include <map>\n#include <vector>\n"; tooling::Replacements Replaces = toReplacements({createInsertion("#include <vector>")}); EXPECT_EQ(Expected, apply(Code, Replaces)); } +TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCodeMultipleInsertions) { + std::string Code = "#include <map>"; + std::string Expected = + "#include <map>\n#include <string>\n#include <vector>\n"; + tooling::Replacements Replaces = + toReplacements({createInsertion("#include <string>"), + createInsertion("#include <vector>")}); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + TEST_F(CleanUpReplacementsTest, SkipExistingHeaders) { std::string Code = "#include \"a.h\"\n" "#include <vector>\n";
Index: cfe/trunk/lib/Format/Format.cpp =================================================================== --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -1662,6 +1662,7 @@ if (CategoryEndOffsets.find(*I) == CategoryEndOffsets.end()) CategoryEndOffsets[*I] = CategoryEndOffsets[*std::prev(I)]; + bool NeedNewLineAtEnd = !Code.empty() && Code.back() != '\n'; for (const auto &R : HeaderInsertions) { auto IncludeDirective = R.getReplacementText(); bool Matched = IncludeRegex.match(IncludeDirective, &Matches); @@ -1680,10 +1681,18 @@ std::string NewInclude = !IncludeDirective.endswith("\n") ? (IncludeDirective + "\n").str() : IncludeDirective.str(); + // When inserting headers at end of the code, also append '\n' to the code + // if it does not end with '\n'. + if (NeedNewLineAtEnd && Offset == Code.size()) { + NewInclude = "\n" + NewInclude; + NeedNewLineAtEnd = false; + } auto NewReplace = tooling::Replacement(FileName, Offset, 0, NewInclude); auto Err = Result.add(NewReplace); if (Err) { llvm::consumeError(std::move(Err)); + unsigned NewOffset = Result.getShiftedCodePosition(Offset); + NewReplace = tooling::Replacement(FileName, NewOffset, 0, NewInclude); Result = Result.merge(tooling::Replacements(NewReplace)); } } Index: cfe/trunk/unittests/Format/CleanupTest.cpp =================================================================== --- cfe/trunk/unittests/Format/CleanupTest.cpp +++ cfe/trunk/unittests/Format/CleanupTest.cpp @@ -709,16 +709,24 @@ EXPECT_EQ(Expected, apply(Code, Replaces)); } -// FIXME: although this case does not crash, the insertion is wrong. A '\n' -// should be inserted between the two #includes. TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCode) { std::string Code = "#include <map>"; - std::string Expected = "#include <map>#include <vector>\n"; + std::string Expected = "#include <map>\n#include <vector>\n"; tooling::Replacements Replaces = toReplacements({createInsertion("#include <vector>")}); EXPECT_EQ(Expected, apply(Code, Replaces)); } +TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCodeMultipleInsertions) { + std::string Code = "#include <map>"; + std::string Expected = + "#include <map>\n#include <string>\n#include <vector>\n"; + tooling::Replacements Replaces = + toReplacements({createInsertion("#include <string>"), + createInsertion("#include <vector>")}); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + TEST_F(CleanUpReplacementsTest, SkipExistingHeaders) { std::string Code = "#include \"a.h\"\n" "#include <vector>\n";
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits