17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/Regex.h"
22 #define DEBUG_TYPE "using-declarations-sorter"
29 struct UsingDeclaration {
33 UsingDeclaration(
const AnnotatedLine *
Line,
const std::string &
Label)
34 : Line(Line), Label(Label) {}
36 bool operator<(
const UsingDeclaration &Other)
const {
37 return Label < Other.Label;
49 std::string computeUsingDeclarationLabel(
const FormatToken *UsingTok) {
50 assert(UsingTok && UsingTok->is(tok::kw_using) &&
"Expecting a using token");
52 const FormatToken *Tok = UsingTok->Next;
53 if (Tok && Tok->is(tok::kw_typename)) {
54 Label.append(
"typename ");
57 if (Tok && Tok->is(tok::coloncolon)) {
61 bool HasIdentifier =
false;
62 while (Tok && Tok->is(tok::identifier)) {
64 Label.append(Tok->TokenText.str());
66 if (!Tok || Tok->isNot(tok::coloncolon))
71 if (HasIdentifier && Tok && Tok->isOneOf(tok::semi, tok::comma))
76 void endUsingDeclarationBlock(
77 SmallVectorImpl<UsingDeclaration> *UsingDeclarations,
78 const SourceManager &
SourceMgr, tooling::Replacements *Fixes) {
79 SmallVector<UsingDeclaration, 4> SortedUsingDeclarations(
80 UsingDeclarations->begin(), UsingDeclarations->end());
81 std::sort(SortedUsingDeclarations.begin(), SortedUsingDeclarations.end());
82 for (
size_t I = 0,
E = UsingDeclarations->size();
I <
E; ++
I) {
83 if ((*UsingDeclarations)[
I].Line == SortedUsingDeclarations[
I].Line)
85 auto Begin = (*UsingDeclarations)[
I].Line->First->Tok.getLocation();
86 auto End = (*UsingDeclarations)[
I].Line->Last->Tok.getEndLoc();
88 SortedUsingDeclarations[
I].Line->First->Tok.getLocation();
89 auto SortedEnd = SortedUsingDeclarations[
I].Line->Last->Tok.getEndLoc();
90 StringRef
Text(SourceMgr.getCharacterData(SortedBegin),
91 SourceMgr.getCharacterData(SortedEnd) -
92 SourceMgr.getCharacterData(SortedBegin));
94 StringRef OldText(SourceMgr.getCharacterData(
Begin),
95 SourceMgr.getCharacterData(
End) -
96 SourceMgr.getCharacterData(
Begin));
97 llvm::dbgs() <<
"Replacing '" << OldText <<
"' with '" <<
Text <<
"'\n";
102 llvm::errs() <<
"Error while sorting using declarations: "
106 UsingDeclarations->clear();
120 AnnotatedLines.end());
123 for (
size_t I = 0, E = AnnotatedLines.size();
I !=
E; ++
I) {
124 if (!AnnotatedLines[
I]->Affected || AnnotatedLines[
I]->InPPDirective ||
125 !AnnotatedLines[
I]->startsWith(tok::kw_using) ||
126 AnnotatedLines[
I]->First->Finalized) {
127 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
130 if (AnnotatedLines[
I]->First->NewlinesBefore > 1)
131 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
132 std::string Label = computeUsingDeclarationLabel(AnnotatedLines[
I]->First);
134 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
137 UsingDeclarations.push_back(UsingDeclaration(AnnotatedLines[
I], Label));
139 endUsingDeclarationBlock(&UsingDeclarations, SourceMgr, &Fixes);
detail::InMemoryDirectory::const_iterator I
const AnnotatedLine * Line
static CharSourceRange getCharRange(SourceRange R)
ArrayRef< FormatToken * > Tokens
detail::InMemoryDirectory::const_iterator E
std::string toString(const til::SExpr *E)
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
This class handles loading and caching of source files into memory.