From c47fc31da10e8f068902fa8e6f231a358eff9f18 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 3 Nov 2017 14:38:07 +0000 Subject: [PATCH] [clang-format] Sort using-declarations case sensitively with a special case for '_' Summary: This makes clang-format sort using declarations case-sensitive with the exception that '_' comes just before 'A'. This is better than the current case insensitive version, because it groups uppercase names in the same namespace together. Reviewers: bkramer Reviewed By: bkramer Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D39549 llvm-svn: 317325 --- clang/lib/Format/UsingDeclarationsSorter.cpp | 23 ++++++++- .../Format/UsingDeclarationsSorterTest.cpp | 55 +++++----------------- 2 files changed, 33 insertions(+), 45 deletions(-) diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp index d6753b5..e9c535d 100644 --- a/clang/lib/Format/UsingDeclarationsSorter.cpp +++ b/clang/lib/Format/UsingDeclarationsSorter.cpp @@ -33,8 +33,27 @@ struct UsingDeclaration { UsingDeclaration(const AnnotatedLine *Line, const std::string &Label) : Line(Line), Label(Label) {} + // Compares lexicographically with the exception that '_' is just before 'A'. bool operator<(const UsingDeclaration &Other) const { - return StringRef(Label).compare_lower(Other.Label) < 0; + size_t Size = Label.size(); + size_t OtherSize = Other.Label.size(); + for (size_t I = 0, E = std::min(Size, OtherSize); I < E; ++I) { + char Rank = rank(Label[I]); + char OtherRank = rank(Other.Label[I]); + if (Rank != OtherRank) + return Rank < OtherRank; + } + return Size < OtherSize; + } + + // Returns the position of c in a lexicographic ordering with the exception + // that '_' is just before 'A'. + static char rank(char c) { + if (c == '_') + return 'A'; + if ('A' <= c && c < '_') + return c + 1; + return c; } }; @@ -77,7 +96,7 @@ void endUsingDeclarationBlock( SmallVectorImpl *UsingDeclarations, const SourceManager &SourceMgr, tooling::Replacements *Fixes) { bool BlockAffected = false; - for (const UsingDeclaration& Declaration : *UsingDeclarations) { + for (const UsingDeclaration &Declaration : *UsingDeclarations) { if (Declaration.Line->Affected) { BlockAffected = true; break; diff --git a/clang/unittests/Format/UsingDeclarationsSorterTest.cpp b/clang/unittests/Format/UsingDeclarationsSorterTest.cpp index caa2f43..6ce96ed 100644 --- a/clang/unittests/Format/UsingDeclarationsSorterTest.cpp +++ b/clang/unittests/Format/UsingDeclarationsSorterTest.cpp @@ -86,19 +86,25 @@ TEST_F(UsingDeclarationsSorterTest, SwapsTwoConsecutiveUsingDeclarations) { "using a, b;")); } -TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { +TEST_F(UsingDeclarationsSorterTest, SortsCaseSensitively) { EXPECT_EQ("using A;\n" "using a;", sortUsingDeclarations("using A;\n" "using a;")); - EXPECT_EQ("using a;\n" - "using A;", + EXPECT_EQ("using A;\n" + "using a;", sortUsingDeclarations("using a;\n" "using A;")); - EXPECT_EQ("using a;\n" - "using B;", + EXPECT_EQ("using B;\n" + "using a;", sortUsingDeclarations("using B;\n" "using a;")); + + // Sorts '_' right before 'A'. + EXPECT_EQ("using _;\n" + "using A;", + sortUsingDeclarations("using A;\n" + "using _;")); EXPECT_EQ("using _;\n" "using a;", sortUsingDeclarations("using a;\n" @@ -110,8 +116,8 @@ TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { EXPECT_EQ("using ::testing::_;\n" "using ::testing::Aardvark;\n" - "using ::testing::apple::Honeycrisp;\n" "using ::testing::Xylophone;\n" + "using ::testing::apple::Honeycrisp;\n" "using ::testing::zebra::Stripes;", sortUsingDeclarations("using ::testing::Aardvark;\n" "using ::testing::Xylophone;\n" @@ -120,43 +126,6 @@ TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { "using ::testing::zebra::Stripes;")); } -TEST_F(UsingDeclarationsSorterTest, SortsStably) { - EXPECT_EQ("using a;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using B;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;", - sortUsingDeclarations("using a;\n" - "using B;\n" - "using a;\n" - "using b;\n" - "using A;\n" - "using a;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using A;\n" - "using a;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using A;\n" - "using a;")); -} - TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) { EXPECT_EQ("using a;\n" "using b;\n" -- 2.7.4