17 #include "llvm/Support/Debug.h" 18 #include "llvm/Support/Regex.h" 22 #define DEBUG_TYPE "using-declarations-sorter" 36 int compareLabels(StringRef A, StringRef B) {
37 SmallVector<StringRef, 2> NamesA;
38 A.split(NamesA,
"::", -1,
false);
39 SmallVector<StringRef, 2> NamesB;
40 B.split(NamesB,
"::", -1,
false);
41 size_t SizeA = NamesA.size();
42 size_t SizeB = NamesB.size();
43 for (
size_t I = 0, E =
std::min(SizeA, SizeB); I < E; ++I) {
52 return NamesA[I].compare_lower(NamesB[I]);
61 int C = NamesA[I].compare_lower(NamesB[I]);
68 struct UsingDeclaration {
72 UsingDeclaration(
const AnnotatedLine *Line,
const std::string &Label)
73 : Line(Line), Label(Label) {}
75 bool operator<(
const UsingDeclaration &Other)
const {
76 return compareLabels(Label, Other.Label) < 0;
88 std::string computeUsingDeclarationLabel(
const FormatToken *UsingTok) {
89 assert(UsingTok && UsingTok->is(tok::kw_using) &&
"Expecting a using token");
91 const FormatToken *
Tok = UsingTok->
Next;
92 if (Tok && Tok->is(tok::kw_typename)) {
93 Label.append(
"typename ");
96 if (Tok && Tok->is(tok::coloncolon)) {
100 bool HasIdentifier =
false;
101 while (Tok && Tok->is(tok::identifier)) {
102 HasIdentifier =
true;
103 Label.append(Tok->TokenText.str());
105 if (!Tok || Tok->isNot(tok::coloncolon))
110 if (HasIdentifier && Tok && Tok->isOneOf(tok::semi, tok::comma))
115 void endUsingDeclarationBlock(
116 SmallVectorImpl<UsingDeclaration> *UsingDeclarations,
117 const SourceManager &SourceMgr, tooling::Replacements *Fixes) {
118 bool BlockAffected =
false;
119 for (
const UsingDeclaration &Declaration : *UsingDeclarations) {
120 if (Declaration.Line->Affected) {
121 BlockAffected =
true;
125 if (!BlockAffected) {
126 UsingDeclarations->clear();
129 SmallVector<UsingDeclaration, 4> SortedUsingDeclarations(
130 UsingDeclarations->begin(), UsingDeclarations->end());
131 std::stable_sort(SortedUsingDeclarations.begin(),
132 SortedUsingDeclarations.end());
133 SortedUsingDeclarations.erase(
134 std::unique(SortedUsingDeclarations.begin(),
135 SortedUsingDeclarations.end(),
136 [](
const UsingDeclaration &a,
const UsingDeclaration &b) {
137 return a.Label == b.Label;
139 SortedUsingDeclarations.end());
140 for (
size_t I = 0, E = UsingDeclarations->size(); I < E; ++I) {
141 if (I >= SortedUsingDeclarations.size()) {
144 (*UsingDeclarations)[I].Line->First->WhitespaceRange.getBegin();
145 auto End = (*UsingDeclarations)[I].Line->Last->Tok.getEndLoc();
149 llvm::errs() <<
"Error while sorting using declarations: " 154 if ((*UsingDeclarations)[I].
Line == SortedUsingDeclarations[I].
Line)
156 auto Begin = (*UsingDeclarations)[I].Line->First->Tok.getLocation();
157 auto End = (*UsingDeclarations)[I].Line->Last->Tok.getEndLoc();
159 SortedUsingDeclarations[I].Line->First->Tok.getLocation();
160 auto SortedEnd = SortedUsingDeclarations[I].Line->Last->Tok.getEndLoc();
161 StringRef
Text(SourceMgr.getCharacterData(SortedBegin),
162 SourceMgr.getCharacterData(SortedEnd) -
163 SourceMgr.getCharacterData(SortedBegin));
165 StringRef OldText(SourceMgr.getCharacterData(
Begin),
166 SourceMgr.getCharacterData(
End) -
167 SourceMgr.getCharacterData(
Begin));
168 llvm::dbgs() <<
"Replacing '" << OldText <<
"' with '" <<
Text <<
"'\n";
173 llvm::errs() <<
"Error while sorting using declarations: " 177 UsingDeclarations->clear();
193 for (
size_t I = 0, E = AnnotatedLines.size(); I != E; ++I) {
194 const auto *FirstTok = AnnotatedLines[I]->First;
196 !AnnotatedLines[I]->startsWith(tok::kw_using) || FirstTok->Finalized) {
197 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
200 if (FirstTok->NewlinesBefore > 1)
201 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
202 const auto *UsingTok =
203 FirstTok->is(tok::comment) ? FirstTok->getNextNonComment() : FirstTok;
204 std::string
Label = computeUsingDeclarationLabel(UsingTok);
206 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
209 UsingDeclarations.push_back(UsingDeclaration(AnnotatedLines[I], Label));
211 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
const AnnotatedLine * Line
static CharSourceRange getCharRange(SourceRange R)
Dataflow Directional Tag Classes.
std::string toString(const til::SExpr *E)
__DEVICE__ int min(int __a, int __b)
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
This class handles loading and caching of source files into memory.