[clang] 58751f9 - [clang-format] SortUsingDeclarations support lexicographic order
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 20 05:46:40 PST 2023
Author: Backl1ght
Date: 2023-01-20T21:34:57+08:00
New Revision: 58751f943f2f6dd78dd3363fc70ea1728044ee0b
URL: https://github.com/llvm/llvm-project/commit/58751f943f2f6dd78dd3363fc70ea1728044ee0b
DIFF: https://github.com/llvm/llvm-project/commit/58751f943f2f6dd78dd3363fc70ea1728044ee0b.diff
LOG: [clang-format] SortUsingDeclarations support lexicographic order
fix https://github.com/llvm/llvm-project/issues/59930
Differential Revision: https://reviews.llvm.org/D141694
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/UsingDeclarationsSorter.cpp
clang/unittests/Format/ConfigParseTest.cpp
clang/unittests/Format/UsingDeclarationsSorterTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 5acaf752826bf..da5af2645f18e 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -4505,22 +4505,54 @@ the configuration (without a prefix: ``Auto``).
.. _SortUsingDeclarations:
-**SortUsingDeclarations** (``Boolean``) :versionbadge:`clang-format 5` :ref:`¶ <SortUsingDeclarations>`
- If ``true``, clang-format will sort using declarations.
+**SortUsingDeclarations** (``SortUsingDeclarationsOptions``) :versionbadge:`clang-format 5` :ref:`¶ <SortUsingDeclarations>`
+ Controls if and how clang-format will sort using declarations.
- The order of using declarations is defined as follows:
- Split the strings by "::" and discard any initial empty strings. The last
- element of each list is a non-namespace name; all others are namespace
- names. Sort the lists of names lexicographically, where the sort order of
- individual names is that all non-namespace names come before all namespace
- names, and within those groups, names are in case-insensitive
- lexicographic order.
+ Possible values:
+
+ * ``SUD_Never`` (in configuration: ``Never``)
+ Using declarations are never sorted.
+
+ .. code-block:: c++
+
+ using std::chrono::duration_cast;
+ using std::move;
+ using boost::regex;
+ using boost::regex_constants::icase;
+ using std::string;
+
+ * ``SUD_Lexicographic`` (in configuration: ``Lexicographic``)
+ Using declarations are sorted in the order defined as follows:
+ Split the strings by "::" and discard any initial empty strings. Sort
+ the lists of names lexicographically, and within those groups, names are
+ in case-insensitive lexicographic order.
+
+ .. code-block:: c++
+
+ using boost::regex;
+ using boost::regex_constants::icase;
+ using std::chrono::duration_cast;
+ using std::move;
+ using std::string;
+
+ * ``SUD_LexicographicNumeric`` (in configuration: ``LexicographicNumeric``)
+ Using declarations are sorted in the order defined as follows:
+ Split the strings by "::" and discard any initial empty strings. The
+ last element of each list is a non-namespace name; all others are
+ namespace names. Sort the lists of names lexicographically, where the
+ sort order of individual names is that all non-namespace names come
+ before all namespace names, and within those groups, names are in
+ case-insensitive lexicographic order.
+
+ .. code-block:: c++
+
+ using boost::regex;
+ using boost::regex_constants::icase;
+ using std::move;
+ using std::string;
+ using std::chrono::duration_cast;
- .. code-block:: c++
- false: true:
- using std::cout; vs. using std::cin;
- using std::cin; using std::cout;
.. _SpaceAfterCStyleCast:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 02d48de59f596..72efd3be1cc72 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -3510,22 +3510,49 @@ struct FormatStyle {
/// \version 12
SortJavaStaticImportOptions SortJavaStaticImport;
- /// If ``true``, clang-format will sort using declarations.
- ///
- /// The order of using declarations is defined as follows:
- /// Split the strings by "::" and discard any initial empty strings. The last
- /// element of each list is a non-namespace name; all others are namespace
- /// names. Sort the lists of names lexicographically, where the sort order of
- /// individual names is that all non-namespace names come before all namespace
- /// names, and within those groups, names are in case-insensitive
- /// lexicographic order.
- /// \code
- /// false: true:
- /// using std::cout; vs. using std::cin;
- /// using std::cin; using std::cout;
- /// \endcode
+ /// Using declaration sorting options.
+ enum SortUsingDeclarationsOptions : int8_t {
+ /// Using declarations are never sorted.
+ /// \code
+ /// using std::chrono::duration_cast;
+ /// using std::move;
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::string;
+ /// \endcode
+ SUD_Never,
+ /// Using declarations are sorted in the order defined as follows:
+ /// Split the strings by "::" and discard any initial empty strings. Sort
+ /// the lists of names lexicographically, and within those groups, names are
+ /// in case-insensitive lexicographic order.
+ /// \code
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::chrono::duration_cast;
+ /// using std::move;
+ /// using std::string;
+ /// \endcode
+ SUD_Lexicographic,
+ /// Using declarations are sorted in the order defined as follows:
+ /// Split the strings by "::" and discard any initial empty strings. The
+ /// last element of each list is a non-namespace name; all others are
+ /// namespace names. Sort the lists of names lexicographically, where the
+ /// sort order of individual names is that all non-namespace names come
+ /// before all namespace names, and within those groups, names are in
+ /// case-insensitive lexicographic order.
+ /// \code
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::move;
+ /// using std::string;
+ /// using std::chrono::duration_cast;
+ /// \endcode
+ SUD_LexicographicNumeric,
+ };
+
+ /// Controls if and how clang-format will sort using declarations.
/// \version 5
- bool SortUsingDeclarations;
+ SortUsingDeclarationsOptions SortUsingDeclarations;
/// If ``true``, a space is inserted after C style casts.
/// \code
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 2e8f1301682bd..f37c3f9836350 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -606,6 +606,21 @@ struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::SortUsingDeclarationsOptions> {
+ static void enumeration(IO &IO,
+ FormatStyle::SortUsingDeclarationsOptions &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::SUD_Never);
+ IO.enumCase(Value, "Lexicographic", FormatStyle::SUD_Lexicographic);
+ IO.enumCase(Value, "LexicographicNumeric",
+ FormatStyle::SUD_LexicographicNumeric);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "false", FormatStyle::SUD_Never);
+ IO.enumCase(Value, "true", FormatStyle::SUD_LexicographicNumeric);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
static void
@@ -1404,7 +1419,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.ShortNamespaceLines = 1;
LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
- LLVMStyle.SortUsingDeclarations = true;
+ LLVMStyle.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
LLVMStyle.SpaceAfterCStyleCast = false;
LLVMStyle.SpaceAfterLogicalNot = false;
LLVMStyle.SpaceAfterTemplateKeyword = true;
@@ -1772,7 +1787,7 @@ FormatStyle getNoStyle() {
FormatStyle NoStyle = getLLVMStyle();
NoStyle.DisableFormat = true;
NoStyle.SortIncludes = FormatStyle::SI_Never;
- NoStyle.SortUsingDeclarations = false;
+ NoStyle.SortUsingDeclarations = FormatStyle::SUD_Never;
return NoStyle;
}
@@ -3480,7 +3495,7 @@ reformat(const FormatStyle &Style, StringRef Code,
});
}
- if (Style.SortUsingDeclarations) {
+ if (Style.SortUsingDeclarations != FormatStyle::SUD_Never) {
Passes.emplace_back([&](const Environment &Env) {
return UsingDeclarationsSorter(Env, Expanded).process();
});
diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp
index bf5307260c0b0..2f4b1e0e46270 100644
--- a/clang/lib/Format/UsingDeclarationsSorter.cpp
+++ b/clang/lib/Format/UsingDeclarationsSorter.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "UsingDeclarationsSorter.h"
+#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"
@@ -32,7 +33,7 @@ namespace {
// individual names is that all non-namespace names come before all namespace
// names, and within those groups, names are in case-insensitive lexicographic
// order.
-int compareLabels(StringRef A, StringRef B) {
+int compareLabelsLexicographicNumeric(StringRef A, StringRef B) {
SmallVector<StringRef, 2> NamesA;
A.split(NamesA, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
SmallVector<StringRef, 2> NamesB;
@@ -64,16 +65,38 @@ int compareLabels(StringRef A, StringRef B) {
return 0;
}
+int compareLabelsLexicographic(StringRef A, StringRef B) {
+ SmallVector<StringRef, 2> NamesA;
+ A.split(NamesA, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+ SmallVector<StringRef, 2> NamesB;
+ B.split(NamesB, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+ size_t SizeA = NamesA.size();
+ size_t SizeB = NamesB.size();
+ for (size_t I = 0, E = std::min(SizeA, SizeB); I < E; ++I) {
+ // Two namespaces names within a group compare case-insensitively.
+ int C = NamesA[I].compare_insensitive(NamesB[I]);
+ if (C != 0)
+ return C;
+ }
+ if (SizeA < SizeB)
+ return -1;
+ return SizeA == SizeB ? 0 : 1;
+}
+
+int compareLabels(
+ StringRef A, StringRef B,
+ FormatStyle::SortUsingDeclarationsOptions SortUsingDeclarations) {
+ if (SortUsingDeclarations == FormatStyle::SUD_LexicographicNumeric)
+ return compareLabelsLexicographicNumeric(A, B);
+ return compareLabelsLexicographic(A, B);
+}
+
struct UsingDeclaration {
const AnnotatedLine *Line;
std::string Label;
UsingDeclaration(const AnnotatedLine *Line, const std::string &Label)
: Line(Line), Label(Label) {}
-
- bool operator<(const UsingDeclaration &Other) const {
- return compareLabels(Label, Other.Label) < 0;
- }
};
/// Computes the label of a using declaration starting at tthe using token
@@ -113,7 +136,8 @@ std::string computeUsingDeclarationLabel(const FormatToken *UsingTok) {
void endUsingDeclarationBlock(
SmallVectorImpl<UsingDeclaration> *UsingDeclarations,
- const SourceManager &SourceMgr, tooling::Replacements *Fixes) {
+ const SourceManager &SourceMgr, tooling::Replacements *Fixes,
+ FormatStyle::SortUsingDeclarationsOptions SortUsingDeclarations) {
bool BlockAffected = false;
for (const UsingDeclaration &Declaration : *UsingDeclarations) {
if (Declaration.Line->Affected) {
@@ -127,7 +151,11 @@ void endUsingDeclarationBlock(
}
SmallVector<UsingDeclaration, 4> SortedUsingDeclarations(
UsingDeclarations->begin(), UsingDeclarations->end());
- llvm::stable_sort(SortedUsingDeclarations);
+ auto Comp = [SortUsingDeclarations](const UsingDeclaration &Lhs,
+ const UsingDeclaration &Rhs) -> bool {
+ return compareLabels(Lhs.Label, Rhs.Label, SortUsingDeclarations) < 0;
+ };
+ llvm::stable_sort(SortedUsingDeclarations, Comp);
SortedUsingDeclarations.erase(
std::unique(SortedUsingDeclarations.begin(),
SortedUsingDeclarations.end(),
@@ -192,21 +220,26 @@ std::pair<tooling::Replacements, unsigned> UsingDeclarationsSorter::analyze(
const auto *FirstTok = Line->First;
if (Line->InPPDirective || !Line->startsWith(tok::kw_using) ||
FirstTok->Finalized) {
- endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
+ endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes,
+ Style.SortUsingDeclarations);
continue;
}
- if (FirstTok->NewlinesBefore > 1)
- endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
+ if (FirstTok->NewlinesBefore > 1) {
+ endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes,
+ Style.SortUsingDeclarations);
+ }
const auto *UsingTok =
FirstTok->is(tok::comment) ? FirstTok->getNextNonComment() : FirstTok;
std::string Label = computeUsingDeclarationLabel(UsingTok);
if (Label.empty()) {
- endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
+ endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes,
+ Style.SortUsingDeclarations);
continue;
}
UsingDeclarations.push_back(UsingDeclaration(Line, Label));
}
- endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
+ endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes,
+ Style.SortUsingDeclarations);
return {Fixes, 0};
}
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 89ebb6c20c192..f432c2641b244 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -174,7 +174,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(ReflowComments);
CHECK_PARSE_BOOL(RemoveBracesLLVM);
CHECK_PARSE_BOOL(RemoveSemicolon);
- CHECK_PARSE_BOOL(SortUsingDeclarations);
CHECK_PARSE_BOOL(SpacesInParentheses);
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
CHECK_PARSE_BOOL(SpacesInConditionalStatement);
@@ -714,6 +713,19 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
FormatStyle::SJSIO_Before);
+ Style.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
+ CHECK_PARSE("SortUsingDeclarations: Never", SortUsingDeclarations,
+ FormatStyle::SUD_Never);
+ CHECK_PARSE("SortUsingDeclarations: Lexicographic", SortUsingDeclarations,
+ FormatStyle::SUD_Lexicographic);
+ CHECK_PARSE("SortUsingDeclarations: LexicographicNumeric",
+ SortUsingDeclarations, FormatStyle::SUD_LexicographicNumeric);
+ // For backward compatibility:
+ CHECK_PARSE("SortUsingDeclarations: false", SortUsingDeclarations,
+ FormatStyle::SUD_Never);
+ CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
+ FormatStyle::SUD_LexicographicNumeric);
+
// FIXME: This is required because parsing a configuration simply overwrites
// the first N elements of the list instead of resetting it.
Style.ForEachMacros.clear();
diff --git a/clang/unittests/Format/UsingDeclarationsSorterTest.cpp b/clang/unittests/Format/UsingDeclarationsSorterTest.cpp
index cd5d456b1d737..6bfee7dd16cc0 100644
--- a/clang/unittests/Format/UsingDeclarationsSorterTest.cpp
+++ b/clang/unittests/Format/UsingDeclarationsSorterTest.cpp
@@ -41,88 +41,162 @@ class UsingDeclarationsSorterTest : public ::testing::Test {
};
TEST_F(UsingDeclarationsSorterTest, SwapsTwoConsecutiveUsingDeclarations) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a;\n"
"using b;",
sortUsingDeclarations("using a;\n"
- "using b;"));
+ "using b;",
+ Style));
EXPECT_EQ("using a;\n"
"using aa;",
sortUsingDeclarations("using aa;\n"
- "using a;"));
+ "using a;",
+ Style));
EXPECT_EQ("using a;\n"
"using ::a;",
sortUsingDeclarations("using a;\n"
- "using ::a;"));
+ "using ::a;",
+ Style));
EXPECT_EQ("using a::bcd;\n"
"using a::cd;",
sortUsingDeclarations("using a::cd;\n"
- "using a::bcd;"));
+ "using a::bcd;",
+ Style));
EXPECT_EQ("using a;\n"
"using a::a;",
sortUsingDeclarations("using a::a;\n"
- "using a;"));
+ "using a;",
+ Style));
EXPECT_EQ("using a::ba::aa;\n"
"using a::bb::ccc;",
sortUsingDeclarations("using a::bb::ccc;\n"
- "using a::ba::aa;"));
+ "using a::ba::aa;",
+ Style));
EXPECT_EQ("using a;\n"
"using typename a;",
sortUsingDeclarations("using typename a;\n"
- "using a;"));
+ "using a;",
+ Style));
EXPECT_EQ("using typename z;\n"
"using typenamea;",
sortUsingDeclarations("using typenamea;\n"
- "using typename z;"));
+ "using typename z;",
+ Style));
EXPECT_EQ("using a, b;\n"
"using aa;",
sortUsingDeclarations("using aa;\n"
- "using a, b;"));
+ "using a, b;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using a;\n"
+ "using b;",
+ sortUsingDeclarations("using a;\n"
+ "using b;",
+ Style));
+ EXPECT_EQ("using a;\n"
+ "using aa;",
+ sortUsingDeclarations("using aa;\n"
+ "using a;",
+ Style));
+ EXPECT_EQ("using a;\n"
+ "using ::a;",
+ sortUsingDeclarations("using a;\n"
+ "using ::a;",
+ Style));
+
+ EXPECT_EQ("using a::bcd;\n"
+ "using a::cd;",
+ sortUsingDeclarations("using a::cd;\n"
+ "using a::bcd;",
+ Style));
+
+ EXPECT_EQ("using a;\n"
+ "using a::a;",
+ sortUsingDeclarations("using a::a;\n"
+ "using a;",
+ Style));
+
+ EXPECT_EQ("using a::ba::aa;\n"
+ "using a::bb::ccc;",
+ sortUsingDeclarations("using a::bb::ccc;\n"
+ "using a::ba::aa;",
+ Style));
+
+ EXPECT_EQ("using a;\n"
+ "using typename a;",
+ sortUsingDeclarations("using typename a;\n"
+ "using a;",
+ Style));
+
+ EXPECT_EQ("using typename z;\n"
+ "using typenamea;",
+ sortUsingDeclarations("using typenamea;\n"
+ "using typename z;",
+ Style));
+
+ EXPECT_EQ("using a, b;\n"
+ "using aa;",
+ sortUsingDeclarations("using aa;\n"
+ "using a, b;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, UsingDeclarationOrder) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using A;\n"
"using a;",
sortUsingDeclarations("using A;\n"
- "using a;"));
+ "using a;",
+ Style));
EXPECT_EQ("using a;\n"
"using A;",
sortUsingDeclarations("using a;\n"
- "using A;"));
+ "using A;",
+ Style));
EXPECT_EQ("using a;\n"
"using B;",
sortUsingDeclarations("using B;\n"
- "using a;"));
+ "using a;",
+ Style));
// Ignores leading '::'.
EXPECT_EQ("using ::a;\n"
"using A;",
sortUsingDeclarations("using ::a;\n"
- "using A;"));
+ "using A;",
+ Style));
EXPECT_EQ("using ::A;\n"
"using a;",
sortUsingDeclarations("using ::A;\n"
- "using a;"));
+ "using a;",
+ Style));
// Sorts '_' before 'a' and 'A'.
EXPECT_EQ("using _;\n"
"using A;",
sortUsingDeclarations("using A;\n"
- "using _;"));
+ "using _;",
+ Style));
EXPECT_EQ("using _;\n"
"using a;",
sortUsingDeclarations("using a;\n"
- "using _;"));
+ "using _;",
+ Style));
EXPECT_EQ("using a::_;\n"
"using a::a;",
sortUsingDeclarations("using a::a;\n"
- "using a::_;"));
+ "using a::_;",
+ Style));
// Sorts non-namespace names before namespace names at the same level.
EXPECT_EQ("using ::testing::_;\n"
@@ -136,10 +210,75 @@ TEST_F(UsingDeclarationsSorterTest, UsingDeclarationOrder) {
"using ::testing::kMax;\n"
"using ::testing::_;\n"
"using ::testing::apple::Honeycrisp;\n"
- "using ::testing::zebra::Stripes;"));
+ "using ::testing::zebra::Stripes;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using A;\n"
+ "using a;",
+ sortUsingDeclarations("using A;\n"
+ "using a;",
+ Style));
+ EXPECT_EQ("using a;\n"
+ "using A;",
+ sortUsingDeclarations("using a;\n"
+ "using A;",
+ Style));
+ EXPECT_EQ("using a;\n"
+ "using B;",
+ sortUsingDeclarations("using B;\n"
+ "using a;",
+ Style));
+
+ // Ignores leading '::'.
+ EXPECT_EQ("using ::a;\n"
+ "using A;",
+ sortUsingDeclarations("using ::a;\n"
+ "using A;",
+ Style));
+
+ EXPECT_EQ("using ::A;\n"
+ "using a;",
+ sortUsingDeclarations("using ::A;\n"
+ "using a;",
+ Style));
+
+ // Sorts '_' before 'a' and 'A'.
+ EXPECT_EQ("using _;\n"
+ "using A;",
+ sortUsingDeclarations("using A;\n"
+ "using _;",
+ Style));
+ EXPECT_EQ("using _;\n"
+ "using a;",
+ sortUsingDeclarations("using a;\n"
+ "using _;",
+ Style));
+ EXPECT_EQ("using a::_;\n"
+ "using a::a;",
+ sortUsingDeclarations("using a::a;\n"
+ "using a::_;",
+ Style));
+
+ // Sorts non-namespace names before namespace names at the same level.
+ EXPECT_EQ("using ::testing::_;\n"
+ "using ::testing::Aardvark;\n"
+ "using ::testing::apple::Honeycrisp;\n"
+ "using ::testing::kMax;\n"
+ "using ::testing::Xylophone;\n"
+ "using ::testing::zebra::Stripes;",
+ sortUsingDeclarations("using ::testing::Aardvark;\n"
+ "using ::testing::Xylophone;\n"
+ "using ::testing::kMax;\n"
+ "using ::testing::_;\n"
+ "using ::testing::apple::Honeycrisp;\n"
+ "using ::testing::zebra::Stripes;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SortsStably) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a;\n"
"using A;\n"
"using a;\n"
@@ -169,10 +308,46 @@ TEST_F(UsingDeclarationsSorterTest, SortsStably) {
"using B;\n"
"using b;\n"
"using A;\n"
- "using a;"));
+ "using a;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("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;",
+ 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;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a;\n"
"using b;\n"
"using c;\n"
@@ -182,7 +357,8 @@ TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) {
"using b;\n"
"using e;\n"
"using a;\n"
- "using c;"));
+ "using c;",
+ Style));
EXPECT_EQ("#include <iostream>\n"
"using std::cin;\n"
@@ -193,10 +369,51 @@ TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) {
"using std::cout;\n"
"using ::std::endl;\n"
"using std::cin;\n"
- "int main();"));
+ "int main();",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using a;\n"
+ "using b;\n"
+ "using c;\n"
+ "using d;\n"
+ "using e;",
+ sortUsingDeclarations("using d;\n"
+ "using b;\n"
+ "using e;\n"
+ "using a;\n"
+ "using c;",
+ Style));
+
+ EXPECT_EQ("#include <iostream>\n"
+ "using std::cin;\n"
+ "using std::cout;\n"
+ "using ::std::endl;\n"
+ "int main();",
+ sortUsingDeclarations("#include <iostream>\n"
+ "using std::cout;\n"
+ "using ::std::endl;\n"
+ "using std::cin;\n"
+ "int main();",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, BreaksOnEmptyLines) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("using b;\n"
+ "using c;\n"
+ "\n"
+ "using a;\n"
+ "using d;",
+ sortUsingDeclarations("using c;\n"
+ "using b;\n"
+ "\n"
+ "using d;\n"
+ "using a;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
EXPECT_EQ("using b;\n"
"using c;\n"
"\n"
@@ -206,35 +423,68 @@ TEST_F(UsingDeclarationsSorterTest, BreaksOnEmptyLines) {
"using b;\n"
"\n"
"using d;\n"
- "using a;"));
+ "using a;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, BreaksOnUsingNamespace) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("using b;\n"
+ "using namespace std;\n"
+ "using a;",
+ sortUsingDeclarations("using b;\n"
+ "using namespace std;\n"
+ "using a;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
EXPECT_EQ("using b;\n"
"using namespace std;\n"
"using a;",
sortUsingDeclarations("using b;\n"
"using namespace std;\n"
- "using a;"));
+ "using a;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, KeepsUsingDeclarationsInPPDirectives) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("#define A \\\n"
"using b;\\\n"
"using a;",
sortUsingDeclarations("#define A \\\n"
"using b;\\\n"
- "using a;"));
+ "using a;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("#define A \\\n"
+ "using b;\\\n"
+ "using a;",
+ sortUsingDeclarations("#define A \\\n"
+ "using b;\\\n"
+ "using a;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, KeepsTypeAliases) {
auto Code = "struct C { struct B { struct A; }; };\n"
"using B = C::B;\n"
"using A = B::A;";
- EXPECT_EQ(Code, sortUsingDeclarations(Code));
+
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ(Code, sortUsingDeclarations(Code, Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ(Code, sortUsingDeclarations(Code, Style));
}
TEST_F(UsingDeclarationsSorterTest, MovesTrailingCommentsWithDeclarations) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a; // line a1\n"
"using b; /* line b1\n"
" * line b2\n"
@@ -246,10 +496,41 @@ TEST_F(UsingDeclarationsSorterTest, MovesTrailingCommentsWithDeclarations) {
"using b; /* line b1\n"
" * line b2\n"
" * line b3 */\n"
- "using a; // line a1"));
+ "using a; // line a1",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using a; // line a1\n"
+ "using b; /* line b1\n"
+ " * line b2\n"
+ " * line b3 */\n"
+ "using c; // line c1\n"
+ " // line c2",
+ sortUsingDeclarations("using c; // line c1\n"
+ " // line c2\n"
+ "using b; /* line b1\n"
+ " * line b2\n"
+ " * line b3 */\n"
+ "using a; // line a1",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SortsInStructScope) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("struct pt3 : pt2 {\n"
+ " using pt2::x;\n"
+ " using pt2::y;\n"
+ " float z;\n"
+ "};",
+ sortUsingDeclarations("struct pt3 : pt2 {\n"
+ " using pt2::y;\n"
+ " using pt2::x;\n"
+ " float z;\n"
+ "};",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
EXPECT_EQ("struct pt3 : pt2 {\n"
" using pt2::x;\n"
" using pt2::y;\n"
@@ -259,19 +540,53 @@ TEST_F(UsingDeclarationsSorterTest, SortsInStructScope) {
" using pt2::y;\n"
" using pt2::x;\n"
" float z;\n"
- "};"));
+ "};",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, KeepsOperators) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a::operator();\n"
"using a::operator-;\n"
"using a::operator+;",
sortUsingDeclarations("using a::operator();\n"
"using a::operator-;\n"
- "using a::operator+;"));
+ "using a::operator+;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using a::operator();\n"
+ "using a::operator-;\n"
+ "using a::operator+;",
+ sortUsingDeclarations("using a::operator();\n"
+ "using a::operator-;\n"
+ "using a::operator+;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsInsideNamespaces) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("namespace A {\n"
+ "struct B;\n"
+ "struct C;\n"
+ "}\n"
+ "namespace X {\n"
+ "using A::B;\n"
+ "using A::C;\n"
+ "}",
+ sortUsingDeclarations("namespace A {\n"
+ "struct B;\n"
+ "struct C;\n"
+ "}\n"
+ "namespace X {\n"
+ "using A::C;\n"
+ "using A::B;\n"
+ "}",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
EXPECT_EQ("namespace A {\n"
"struct B;\n"
"struct C;\n"
@@ -287,10 +602,28 @@ TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsInsideNamespaces) {
"namespace X {\n"
"using A::C;\n"
"using A::B;\n"
- "}"));
+ "}",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SupportsClangFormatOff) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("// clang-format off\n"
+ "using b;\n"
+ "using a;\n"
+ "// clang-format on\n"
+ "using c;\n"
+ "using d;",
+ sortUsingDeclarations("// clang-format off\n"
+ "using b;\n"
+ "using a;\n"
+ "// clang-format on\n"
+ "using d;\n"
+ "using c;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
EXPECT_EQ("// clang-format off\n"
"using b;\n"
"using a;\n"
@@ -302,10 +635,13 @@ TEST_F(UsingDeclarationsSorterTest, SupportsClangFormatOff) {
"using a;\n"
"// clang-format on\n"
"using d;\n"
- "using c;"));
+ "using c;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
// Sorts the whole block of using declarations surrounding the range.
EXPECT_EQ("using a;\n"
"using b;\n"
@@ -313,7 +649,7 @@ TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
sortUsingDeclarations("using b;\n"
"using c;\n" // starts at offset 10
"using a;",
- {tooling::Range(10, 15)}));
+ {tooling::Range(10, 15)}, Style));
EXPECT_EQ("using a;\n"
"using b;\n"
"using c;\n"
@@ -322,7 +658,7 @@ TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
"using c;\n" // starts at offset 10
"using a;\n"
"using A = b;",
- {tooling::Range(10, 15)}));
+ {tooling::Range(10, 15)}, Style));
EXPECT_EQ("using d;\n"
"using c;\n"
@@ -340,18 +676,67 @@ TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
"\n"
"using f;\n"
"using e;",
- {tooling::Range(19, 1)}));
+ {tooling::Range(19, 1)}, Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ // Sorts the whole block of using declarations surrounding the range.
+ EXPECT_EQ("using a;\n"
+ "using b;\n"
+ "using c;",
+ sortUsingDeclarations("using b;\n"
+ "using c;\n" // starts at offset 10
+ "using a;",
+ {tooling::Range(10, 15)}, Style));
+ EXPECT_EQ("using a;\n"
+ "using b;\n"
+ "using c;\n"
+ "using A = b;",
+ sortUsingDeclarations("using b;\n"
+ "using c;\n" // starts at offset 10
+ "using a;\n"
+ "using A = b;",
+ {tooling::Range(10, 15)}, Style));
+
+ EXPECT_EQ("using d;\n"
+ "using c;\n"
+ "\n"
+ "using a;\n"
+ "using b;\n"
+ "\n"
+ "using f;\n"
+ "using e;",
+ sortUsingDeclarations("using d;\n"
+ "using c;\n"
+ "\n"
+ "using b;\n" // starts at offset 19
+ "using a;\n"
+ "\n"
+ "using f;\n"
+ "using e;",
+ {tooling::Range(19, 1)}, Style));
}
TEST_F(UsingDeclarationsSorterTest,
SortsUsingDeclarationsWithLeadingkComments) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("/* comment */ using a;\n"
"/* comment */ using b;",
sortUsingDeclarations("/* comment */ using b;\n"
- "/* comment */ using a;"));
+ "/* comment */ using a;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("/* comment */ using a;\n"
+ "/* comment */ using b;",
+ sortUsingDeclarations("/* comment */ using b;\n"
+ "/* comment */ using a;",
+ Style));
}
TEST_F(UsingDeclarationsSorterTest, DeduplicatesUsingDeclarations) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
EXPECT_EQ("using a;\n"
"using b;\n"
"using c;\n"
@@ -366,7 +751,68 @@ TEST_F(UsingDeclarationsSorterTest, DeduplicatesUsingDeclarations) {
"\n"
"using e;\n"
"using a;\n"
- "using e;"));
+ "using e;",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using a;\n"
+ "using b;\n"
+ "using c;\n"
+ "\n"
+ "using a;\n"
+ "using e;",
+ sortUsingDeclarations("using c;\n"
+ "using a;\n"
+ "using b;\n"
+ "using a;\n"
+ "using b;\n"
+ "\n"
+ "using e;\n"
+ "using a;\n"
+ "using e;",
+ Style));
+}
+
+TEST_F(UsingDeclarationsSorterTest,
+ SortsUsingDeclarationsWithDifferentCountsOfScopes) {
+ FormatStyle Style = getLLVMStyle();
+ EXPECT_EQ(FormatStyle::SUD_LexicographicNumeric, Style.SortUsingDeclarations);
+ EXPECT_EQ("using boost::regex;\n"
+ "using boost::regex_constants::icase;\n"
+ "using std::move;\n"
+ "using std::string;\n"
+ "using std::chrono::duration_cast;\n"
+ "using std::chrono::microseconds;\n"
+ "using std::chrono::seconds;\n"
+ "using std::chrono::steady_clock;\n",
+ sortUsingDeclarations("using boost::regex;\n"
+ "using boost::regex_constants::icase;\n"
+ "using std::chrono::duration_cast;\n"
+ "using std::chrono::microseconds;\n"
+ "using std::chrono::seconds;\n"
+ "using std::chrono::steady_clock;\n"
+ "using std::move;\n"
+ "using std::string;\n",
+ Style));
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_Lexicographic;
+ EXPECT_EQ("using boost::regex;\n"
+ "using boost::regex_constants::icase;\n"
+ "using std::chrono::duration_cast;\n"
+ "using std::chrono::microseconds;\n"
+ "using std::chrono::seconds;\n"
+ "using std::chrono::steady_clock;\n"
+ "using std::move;\n"
+ "using std::string;\n",
+ sortUsingDeclarations("using boost::regex;\n"
+ "using boost::regex_constants::icase;\n"
+ "using std::move;\n"
+ "using std::string;\n"
+ "using std::chrono::duration_cast;\n"
+ "using std::chrono::microseconds;\n"
+ "using std::chrono::seconds;\n"
+ "using std::chrono::steady_clock;\n",
+ Style));
}
} // end namespace
More information about the cfe-commits
mailing list