diff options
author | Eric Liu <ioeric@google.com> | 2016-05-31 13:34:20 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-05-31 13:34:20 +0000 |
commit | 659afd55fa09a1ce668a2483c23acdaf200cc6b9 (patch) | |
tree | fe714837f8e3f6124026c19099cfc23817ebd215 /clang/unittests/Format/CleanupTest.cpp | |
parent | 61c47fd86a6455e0c526237d1eeb50b78da56cb6 (diff) | |
download | bcm5719-llvm-659afd55fa09a1ce668a2483c23acdaf200cc6b9.tar.gz bcm5719-llvm-659afd55fa09a1ce668a2483c23acdaf200cc6b9.zip |
[clang-format] insert new #includes into correct blocks when cleaning up Replacement with cleanupAroundReplacements().
Summary:
When a replacement's offset is set to UINT_MAX or -1U, it is treated as
a header insertion replacement by cleanupAroundReplacements(). The new #include
directive is then inserted into the correct block.
Reviewers: klimek, djasper
Subscribers: klimek, cfe-commits, bkramer
Differential Revision: http://reviews.llvm.org/D20734
llvm-svn: 271276
Diffstat (limited to 'clang/unittests/Format/CleanupTest.cpp')
-rw-r--r-- | clang/unittests/Format/CleanupTest.cpp | 288 |
1 files changed, 272 insertions, 16 deletions
diff --git a/clang/unittests/Format/CleanupTest.cpp b/clang/unittests/Format/CleanupTest.cpp index 93cc1e82fe6..9b011e436ac 100644 --- a/clang/unittests/Format/CleanupTest.cpp +++ b/clang/unittests/Format/CleanupTest.cpp @@ -243,13 +243,39 @@ TEST_F(CleanupTest, CtorInitializerInNamespace) { class CleanUpReplacementsTest : public ::testing::Test { protected: - tooling::Replacement createReplacement(SourceLocation Start, unsigned Length, - llvm::StringRef ReplacementText) { - return tooling::Replacement(Context.Sources, Start, Length, - ReplacementText); + tooling::Replacement createReplacement(unsigned Offset, unsigned Length, + StringRef Text) { + return tooling::Replacement(FileName, Offset, Length, Text); } - RewriterTestContext Context; + tooling::Replacement createInsertion(StringRef HeaderName) { + return createReplacement(UINT_MAX, 0, HeaderName); + } + + inline std::string apply(StringRef Code, + const tooling::Replacements Replaces) { + return applyAllReplacements( + Code, cleanupAroundReplacements(Code, Replaces, Style)); + } + + inline std::string formatAndApply(StringRef Code, + const tooling::Replacements Replaces) { + return applyAllReplacements( + Code, + formatReplacements( + Code, cleanupAroundReplacements(Code, Replaces, Style), Style)); + } + + int getOffset(StringRef Code, int Line, int Column) { + RewriterTestContext Context; + FileID ID = Context.createInMemoryFile(FileName, Code); + auto DecomposedLocation = + Context.Sources.getDecomposedLoc(Context.getLocation(ID, Line, Column)); + return DecomposedLocation.second; + } + + const std::string FileName = "fix.cpp"; + FormatStyle Style = getLLVMStyle(); }; TEST_F(CleanUpReplacementsTest, FixOnlyAffectedCodeAfterReplacements) { @@ -268,17 +294,247 @@ TEST_F(CleanUpReplacementsTest, FixOnlyAffectedCodeAfterReplacements) { "namespace D { int i; }\n\n" "int x= 0;" "}"; - FileID ID = Context.createInMemoryFile("fix.cpp", Code); - tooling::Replacements Replaces; - Replaces.insert(tooling::Replacement(Context.Sources, - Context.getLocation(ID, 3, 3), 6, "")); - Replaces.insert(tooling::Replacement(Context.Sources, - Context.getLocation(ID, 9, 34), 6, "")); - - format::FormatStyle Style = format::getLLVMStyle(); - auto FinalReplaces = formatReplacements( - Code, cleanupAroundReplacements(Code, Replaces, Style), Style); - EXPECT_EQ(Expected, applyAllReplacements(Code, FinalReplaces)); + tooling::Replacements Replaces = { + createReplacement(getOffset(Code, 3, 3), 6, ""), + createReplacement(getOffset(Code, 9, 34), 6, "")}; + + EXPECT_EQ(Expected, formatAndApply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithoutDefine) { + std::string Code = "int main() {}"; + std::string Expected = "#include \"a.h\"\n" + "int main() {}"; + tooling::Replacements Replaces = {createInsertion("#include \"a.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithDefine) { + std::string Code = "#ifndef A_H\n" + "#define A_H\n" + "class A {};\n" + "#define MMM 123\n" + "#endif"; + std::string Expected = "#ifndef A_H\n" + "#define A_H\n" + "#include \"b.h\"\n" + "class A {};\n" + "#define MMM 123\n" + "#endif"; + + tooling::Replacements Replaces = {createInsertion("#include \"b.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertBeforeCategoryWithLowerPriority) { + std::string Code = "#ifndef A_H\n" + "#define A_H\n" + "\n" + "\n" + "\n" + "#include <vector>\n" + "class A {};\n" + "#define MMM 123\n" + "#endif"; + std::string Expected = "#ifndef A_H\n" + "#define A_H\n" + "\n" + "\n" + "\n" + "#include \"a.h\"\n" + "#include <vector>\n" + "class A {};\n" + "#define MMM 123\n" + "#endif"; + + tooling::Replacements Replaces = {createInsertion("#include \"a.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertAfterMainHeader) { + std::string Code = "#include \"fix.h\"\n" + "\n" + "int main() {}"; + std::string Expected = "#include \"fix.h\"\n" + "#include <a>\n" + "\n" + "int main() {}"; + tooling::Replacements Replaces = {createInsertion("#include <a>")}; + Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertBeforeSystemHeaderLLVM) { + std::string Code = "#include <memory>\n" + "\n" + "int main() {}"; + std::string Expected = "#include \"z.h\"\n" + "#include <memory>\n" + "\n" + "int main() {}"; + tooling::Replacements Replaces = {createInsertion("#include \"z.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertAfterSystemHeaderGoogle) { + std::string Code = "#include <memory>\n" + "\n" + "int main() {}"; + std::string Expected = "#include <memory>\n" + "#include \"z.h\"\n" + "\n" + "int main() {}"; + tooling::Replacements Replaces = {createInsertion("#include \"z.h\"")}; + Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertOneIncludeLLVMStyle) { + std::string Code = "#include \"x/fix.h\"\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"clang/Format/Format.h\"\n" + "#include <memory>\n"; + std::string Expected = "#include \"x/fix.h\"\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"d.h\"\n" + "#include \"clang/Format/Format.h\"\n" + "#include \"llvm/x/y.h\"\n" + "#include <memory>\n"; + tooling::Replacements Replaces = {createInsertion("#include \"d.h\""), + createInsertion("#include \"llvm/x/y.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesLLVMStyle) { + std::string Code = "#include \"x/fix.h\"\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"clang/Format/Format.h\"\n" + "#include <memory>\n"; + std::string Expected = "#include \"x/fix.h\"\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"new/new.h\"\n" + "#include \"clang/Format/Format.h\"\n" + "#include <memory>\n" + "#include <list>\n"; + tooling::Replacements Replaces = {createInsertion("#include <list>"), + createInsertion("#include \"new/new.h\"")}; + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertNewSystemIncludeGoogleStyle) { + std::string Code = "#include \"x/fix.h\"\n" + "\n" + "#include \"y/a.h\"\n" + "#include \"z/b.h\"\n"; + // FIXME: inserting after the empty line following the main header might be + // prefered. + std::string Expected = "#include \"x/fix.h\"\n" + "#include <vector>\n" + "\n" + "#include \"y/a.h\"\n" + "#include \"z/b.h\"\n"; + tooling::Replacements Replaces = {createInsertion("#include <vector>")}; + Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesGoogleStyle) { + std::string Code = "#include \"x/fix.h\"\n" + "\n" + "#include <vector>\n" + "\n" + "#include \"y/a.h\"\n" + "#include \"z/b.h\"\n"; + std::string Expected = "#include \"x/fix.h\"\n" + "\n" + "#include <vector>\n" + "#include <list>\n" + "\n" + "#include \"y/a.h\"\n" + "#include \"z/b.h\"\n" + "#include \"x/x.h\"\n"; + tooling::Replacements Replaces = {createInsertion("#include <list>"), + createInsertion("#include \"x/x.h\"")}; + Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp); + EXPECT_EQ(Expected, apply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortLLVM) { + std::string Code = "\nint x;"; + std::string Expected = "#include \"fix.h\"\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"c.h\"\n" + "#include <list>\n" + "#include <vector>\n" + "\nint x;"; + tooling::Replacements Replaces = {createInsertion("#include \"a.h\""), + createInsertion("#include \"c.h\""), + createInsertion("#include \"b.h\""), + createInsertion("#include <vector>"), + createInsertion("#include <list>"), + createInsertion("#include \"fix.h\"")}; + EXPECT_EQ(Expected, formatAndApply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortGoogle) { + std::string Code = "\nint x;"; + std::string Expected = "#include \"fix.h\"\n" + "#include <list>\n" + "#include <vector>\n" + "#include \"a.h\"\n" + "#include \"b.h\"\n" + "#include \"c.h\"\n" + "\nint x;"; + tooling::Replacements Replaces = {createInsertion("#include \"a.h\""), + createInsertion("#include \"c.h\""), + createInsertion("#include \"b.h\""), + createInsertion("#include <vector>"), + createInsertion("#include <list>"), + createInsertion("#include \"fix.h\"")}; + Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp); + EXPECT_EQ(Expected, formatAndApply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, FormatCorrectLineWhenHeadersAreInserted) { + std::string Code = "\n" + "int a;\n" + "int a;\n" + "int a;"; + + std::string Expected = "#include \"x.h\"\n" + "#include \"y.h\"\n" + "#include \"clang/x/x.h\"\n" + "#include <list>\n" + "#include <vector>\n" + "\n" + "int a;\n" + "int b;\n" + "int a;"; + tooling::Replacements Replaces = { + createReplacement(getOffset(Code, 3, 8), 1, "b"), + createInsertion("#include <vector>"), + createInsertion("#include <list>"), + createInsertion("#include \"clang/x/x.h\""), + createInsertion("#include \"y.h\""), + createInsertion("#include \"x.h\"")}; + EXPECT_EQ(Expected, formatAndApply(Code, Replaces)); +} + +TEST_F(CleanUpReplacementsTest, NotConfusedByDefine) { + std::string Code = "void f() {}\n" + "#define A \\\n" + " int i;"; + std::string Expected = "#include <vector>\n" + "void f() {}\n" + "#define A \\\n" + " int i;"; + tooling::Replacements Replaces = {createInsertion("#include <vector>")}; + EXPECT_EQ(Expected, formatAndApply(Code, Replaces)); } } // end namespace |