diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/Format/UsingDeclarationsSorter.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'clang/lib/Format/UsingDeclarationsSorter.cpp')
-rw-r--r-- | clang/lib/Format/UsingDeclarationsSorter.cpp | 57 |
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}; } |