aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/UsingDeclarationsSorter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/Format/UsingDeclarationsSorter.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'clang/lib/Format/UsingDeclarationsSorter.cpp')
-rw-r--r--clang/lib/Format/UsingDeclarationsSorter.cpp57
1 files changed, 45 insertions, 12 deletions
diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp
index bf5307260c0b..2f4b1e0e4627 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};
}