summaryrefslogtreecommitdiffstats
path: root/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2017-02-27 13:28:36 +0000
committerKrasimir Georgiev <krasimir@google.com>2017-02-27 13:28:36 +0000
commit7cb267af75e7f8de9d721f4d7bd801003784a6df (patch)
tree3d29f004e8f6835c8846f0f1ce2199d7c0f90b81 /clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
parentcf8396e4aa1cae7ea8b7f651bc52ec5159378958 (diff)
downloadbcm5719-llvm-7cb267af75e7f8de9d721f4d7bd801003784a6df.tar.gz
bcm5719-llvm-7cb267af75e7f8de9d721f4d7bd801003784a6df.zip
[clang-format] Add a NamespaceEndCommentsFixer
Summary: This patch adds a NamespaceEndCommentsFixer TokenAnalyzer for clang-format, which fixes end namespace comments. It currently supports inserting and updating existing wrong comments. Example source: ``` namespace A { int i; } namespace B { int j; } // namespace A ``` after formatting: ``` namespace A { int i; } // namespace A namespace B { int j; } // namespace B ``` Reviewers: klimek, djasper Reviewed By: djasper Subscribers: klimek, mgorny Differential Revision: https://reviews.llvm.org/D30269 llvm-svn: 296341
Diffstat (limited to 'clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp')
-rw-r--r--clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp350
1 files changed, 350 insertions, 0 deletions
diff --git a/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
new file mode 100644
index 00000000000..09f21929c37
--- /dev/null
+++ b/clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
@@ -0,0 +1,350 @@
+//===- NamespaceEndCommentsFixerTest.cpp - Formatting unit tests ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Format/Format.h"
+
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "namespace-end-comments-fixer-test"
+
+namespace clang {
+namespace format {
+namespace {
+
+class NamespaceEndCommentsFixerTest : public ::testing::Test {
+protected:
+ std::string
+ fixNamespaceEndComments(llvm::StringRef Code,
+ std::vector<tooling::Range> Ranges,
+ const FormatStyle &Style = getLLVMStyle()) {
+ DEBUG(llvm::errs() << "---\n");
+ DEBUG(llvm::errs() << Code << "\n\n");
+ tooling::Replacements Replaces =
+ clang::format::fixNamespaceEndComments(Style, Code, Ranges, "<stdin>");
+ auto Result = applyAllReplacements(Code, Replaces);
+ EXPECT_TRUE(static_cast<bool>(Result));
+ DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+ return *Result;
+ }
+
+ std::string
+ fixNamespaceEndComments(llvm::StringRef Code,
+ const FormatStyle &Style = getLLVMStyle()) {
+ return fixNamespaceEndComments(
+ Code,
+ /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+ }
+};
+
+TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) {
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "}// namespace",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "}// namespace\n",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "}\n"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("inline namespace A {\n"
+ " int i;\n"
+ "}// namespace A",
+ fixNamespaceEndComments("inline namespace A {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("namespace ::A {\n"
+ " int i;\n"
+ "}// namespace ::A",
+ fixNamespaceEndComments("namespace ::A {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("namespace ::A::B {\n"
+ " int i;\n"
+ "}// namespace ::A::B",
+ fixNamespaceEndComments("namespace ::A::B {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("namespace /**/::/**/A/**/::/**/B/**/ {\n"
+ " int i;\n"
+ "}// namespace ::A::B",
+ fixNamespaceEndComments("namespace /**/::/**/A/**/::/**/B/**/ {\n"
+ " int i;\n"
+ "}"));
+ EXPECT_EQ("namespace A {\n"
+ "namespace B {\n"
+ " int i;\n"
+ "}// namespace B\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ "namespace B {\n"
+ " int i;\n"
+ "}\n"
+ "}"));
+ EXPECT_EQ("namespace A {\n"
+ " int a;\n"
+ "}// namespace A\n"
+ "namespace B {\n"
+ " int b;\n"
+ "}// namespace B",
+ fixNamespaceEndComments("namespace A {\n"
+ " int a;\n"
+ "}\n"
+ "namespace B {\n"
+ " int b;\n"
+ "}"));
+ EXPECT_EQ("namespace A {\n"
+ " int a1;\n"
+ "}// namespace A\n"
+ "namespace A {\n"
+ " int a2;\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int a1;\n"
+ "}\n"
+ "namespace A {\n"
+ " int a2;\n"
+ "}"));
+ EXPECT_EQ("namespace A {\n"
+ " int a;\n"
+ "}// namespace A\n"
+ "// comment about b\n"
+ "int b;",
+ fixNamespaceEndComments("namespace A {\n"
+ " int a;\n"
+ "}\n"
+ "// comment about b\n"
+ "int b;"));
+
+ EXPECT_EQ("namespace A {\n"
+ "namespace B {\n"
+ "namespace C {\n"
+ "namespace D {\n"
+ "}// namespace D\n"
+ "}// namespace C\n"
+ "}// namespace B\n"
+ "}// namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ "namespace B {\n"
+ "namespace C {\n"
+ "namespace D {\n"
+ "}\n"
+ "}\n"
+ "}\n"
+ "}"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) {
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "}// namespace A\n"
+ " int j;",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} int j;"));
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "}// namespace\n"
+ " int j;",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "} int j;"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "}// namespace A\n"
+ " namespace B {\n"
+ " int j;\n"
+ "}// namespace B",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} namespace B {\n"
+ " int j;\n"
+ "}"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) {
+ EXPECT_EQ("namespace {}", fixNamespaceEndComments("namespace {}"));
+ EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}"));
+ EXPECT_EQ("namespace A { int i; }",
+ fixNamespaceEndComments("namespace A { int i; }"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) {
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "}",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "}",
+ // The range (16, 3) spans the 'int' above.
+ /*Ranges=*/{1, tooling::Range(16, 3)}));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) {
+ EXPECT_EQ("#define SAD \\\n"
+ "namespace A { \\\n"
+ " int i; \\\n"
+ "}",
+ fixNamespaceEndComments("#define SAD \\\n"
+ "namespace A { \\\n"
+ " int i; \\\n"
+ "}"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) {
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "} // end anonymous namespace",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "} // end anonymous namespace"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} /* end of namespace A */",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} /* end of namespace A */"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} // namespace A"));
+ EXPECT_EQ("namespace A::B {\n"
+ " int i;\n"
+ "} // end namespace A::B",
+ fixNamespaceEndComments("namespace A::B {\n"
+ " int i;\n"
+ "} // end namespace A::B"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) {
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "} // namespace",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "} // namespace A"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} // namespace"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} //"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} //"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} // banamespace A"));
+
+ // Updates invalid line comments even for short namespaces.
+ EXPECT_EQ("namespace A {} // namespace A",
+ fixNamespaceEndComments("namespace A {} // namespace"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) {
+ EXPECT_EQ("namespace {\n"
+ " int i;\n"
+ "} // namespace",
+ fixNamespaceEndComments("namespace {\n"
+ " int i;\n"
+ "} /* namespace A */"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} /* end namespace */"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} /**/"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} /* end unnamed namespace */"));
+ EXPECT_EQ("namespace A {\n"
+ " int i;\n"
+ "} // namespace A",
+ fixNamespaceEndComments("namespace A {\n"
+ " int i;\n"
+ "} /* banamespace A */"));
+ EXPECT_EQ("namespace A {} // namespace A",
+ fixNamespaceEndComments("namespace A {} /**/"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest,
+ DoesNotAddEndCommentForNamespacesControlledByMacros) {
+ EXPECT_EQ("#ifdef 1\n"
+ "namespace A {\n"
+ "#elseif\n"
+ "namespace B {\n"
+ "#endif\n"
+ " int i;\n"
+ "}\n"
+ "}\n",
+ fixNamespaceEndComments("#ifdef 1\n"
+ "namespace A {\n"
+ "#elseif\n"
+ "namespace B {\n"
+ "#endif\n"
+ " int i;\n"
+ "}\n"
+ "}\n"));
+}
+
+TEST_F(NamespaceEndCommentsFixerTest,
+ DoesNotAddEndCommentForNamespacesInMacroDeclarations) {
+ EXPECT_EQ("#ifdef 1\n"
+ "namespace A {\n"
+ "#elseif\n"
+ "namespace B {\n"
+ "#endif\n"
+ " int i;\n"
+ "}\n"
+ "}\n",
+ fixNamespaceEndComments("#ifdef 1\n"
+ "namespace A {\n"
+ "#elseif\n"
+ "namespace B {\n"
+ "#endif\n"
+ " int i;\n"
+ "}\n"
+ "}\n"));
+}
+} // end namespace
+} // end namespace format
+} // end namespace clang
OpenPOWER on IntegriCloud