|
@@ -29,13 +29,15 @@ WhitespaceManager::Change::Change(
|
|
bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
|
|
bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
|
|
unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
|
|
unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
|
|
unsigned NewlinesBefore, StringRef PreviousLinePostfix,
|
|
unsigned NewlinesBefore, StringRef PreviousLinePostfix,
|
|
- StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective)
|
|
|
|
|
|
+ StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective,
|
|
|
|
+ bool IsStartOfDeclName)
|
|
: CreateReplacement(CreateReplacement),
|
|
: CreateReplacement(CreateReplacement),
|
|
OriginalWhitespaceRange(OriginalWhitespaceRange),
|
|
OriginalWhitespaceRange(OriginalWhitespaceRange),
|
|
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
|
|
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
|
|
PreviousLinePostfix(PreviousLinePostfix),
|
|
PreviousLinePostfix(PreviousLinePostfix),
|
|
CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
|
|
CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
|
|
- ContinuesPPDirective(ContinuesPPDirective), IndentLevel(IndentLevel),
|
|
|
|
|
|
+ ContinuesPPDirective(ContinuesPPDirective),
|
|
|
|
+ IsStartOfDeclName(IsStartOfDeclName), IndentLevel(IndentLevel),
|
|
Spaces(Spaces), IsTrailingComment(false), TokenLength(0),
|
|
Spaces(Spaces), IsTrailingComment(false), TokenLength(0),
|
|
PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
|
|
PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
|
|
StartOfBlockComment(nullptr), IndentationOffset(0) {}
|
|
StartOfBlockComment(nullptr), IndentationOffset(0) {}
|
|
@@ -52,19 +54,21 @@ void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
|
|
if (Tok.Finalized)
|
|
if (Tok.Finalized)
|
|
return;
|
|
return;
|
|
Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
|
|
Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
|
|
- Changes.push_back(Change(true, Tok.WhitespaceRange, IndentLevel, Spaces,
|
|
|
|
- StartOfTokenColumn, Newlines, "", "",
|
|
|
|
- Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst));
|
|
|
|
|
|
+ Changes.push_back(
|
|
|
|
+ Change(true, Tok.WhitespaceRange, IndentLevel, Spaces, StartOfTokenColumn,
|
|
|
|
+ Newlines, "", "", Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst,
|
|
|
|
+ Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName)));
|
|
}
|
|
}
|
|
|
|
|
|
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
|
|
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
|
|
bool InPPDirective) {
|
|
bool InPPDirective) {
|
|
if (Tok.Finalized)
|
|
if (Tok.Finalized)
|
|
return;
|
|
return;
|
|
- Changes.push_back(Change(false, Tok.WhitespaceRange, /*IndentLevel=*/0,
|
|
|
|
- /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore,
|
|
|
|
- "", "", Tok.Tok.getKind(),
|
|
|
|
- InPPDirective && !Tok.IsFirst));
|
|
|
|
|
|
+ Changes.push_back(
|
|
|
|
+ Change(false, Tok.WhitespaceRange, /*IndentLevel=*/0,
|
|
|
|
+ /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
|
|
|
|
+ Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst,
|
|
|
|
+ Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName)));
|
|
}
|
|
}
|
|
|
|
|
|
void WhitespaceManager::replaceWhitespaceInToken(
|
|
void WhitespaceManager::replaceWhitespaceInToken(
|
|
@@ -84,7 +88,8 @@ void WhitespaceManager::replaceWhitespaceInToken(
|
|
// calculate the new length of the comment and to calculate the changes
|
|
// calculate the new length of the comment and to calculate the changes
|
|
// for which to do the alignment when aligning comments.
|
|
// for which to do the alignment when aligning comments.
|
|
Tok.is(TT_LineComment) && Newlines > 0 ? tok::comment : tok::unknown,
|
|
Tok.is(TT_LineComment) && Newlines > 0 ? tok::comment : tok::unknown,
|
|
- InPPDirective && !Tok.IsFirst));
|
|
|
|
|
|
+ InPPDirective && !Tok.IsFirst,
|
|
|
|
+ Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName)));
|
|
}
|
|
}
|
|
|
|
|
|
const tooling::Replacements &WhitespaceManager::generateReplacements() {
|
|
const tooling::Replacements &WhitespaceManager::generateReplacements() {
|
|
@@ -93,6 +98,7 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() {
|
|
|
|
|
|
std::sort(Changes.begin(), Changes.end(), Change::IsBeforeInFile(SourceMgr));
|
|
std::sort(Changes.begin(), Changes.end(), Change::IsBeforeInFile(SourceMgr));
|
|
calculateLineBreakInformation();
|
|
calculateLineBreakInformation();
|
|
|
|
+ alignConsecutiveDeclarations();
|
|
alignConsecutiveAssignments();
|
|
alignConsecutiveAssignments();
|
|
alignTrailingComments();
|
|
alignTrailingComments();
|
|
alignEscapedNewlines();
|
|
alignEscapedNewlines();
|
|
@@ -152,6 +158,7 @@ void WhitespaceManager::alignConsecutiveAssignments() {
|
|
return;
|
|
return;
|
|
|
|
|
|
unsigned MinColumn = 0;
|
|
unsigned MinColumn = 0;
|
|
|
|
+ unsigned MaxColumn = UINT_MAX;
|
|
unsigned StartOfSequence = 0;
|
|
unsigned StartOfSequence = 0;
|
|
unsigned EndOfSequence = 0;
|
|
unsigned EndOfSequence = 0;
|
|
bool FoundAssignmentOnLine = false;
|
|
bool FoundAssignmentOnLine = false;
|
|
@@ -168,6 +175,7 @@ void WhitespaceManager::alignConsecutiveAssignments() {
|
|
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
|
|
if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
|
|
alignConsecutiveAssignments(StartOfSequence, EndOfSequence, MinColumn);
|
|
alignConsecutiveAssignments(StartOfSequence, EndOfSequence, MinColumn);
|
|
MinColumn = 0;
|
|
MinColumn = 0;
|
|
|
|
+ MaxColumn = UINT_MAX;
|
|
StartOfSequence = 0;
|
|
StartOfSequence = 0;
|
|
EndOfSequence = 0;
|
|
EndOfSequence = 0;
|
|
};
|
|
};
|
|
@@ -207,7 +215,18 @@ void WhitespaceManager::alignConsecutiveAssignments() {
|
|
StartOfSequence = i;
|
|
StartOfSequence = i;
|
|
|
|
|
|
unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
|
|
unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
|
|
|
|
+ int LineLengthAfter = -Changes[i].Spaces;
|
|
|
|
+ for (unsigned j = i; j != e && Changes[j].NewlinesBefore == 0; ++j)
|
|
|
|
+ LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
|
|
|
|
+ unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
|
|
|
|
+
|
|
|
|
+ if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) {
|
|
|
|
+ AlignSequence();
|
|
|
|
+ StartOfSequence = i;
|
|
|
|
+ }
|
|
|
|
+
|
|
MinColumn = std::max(MinColumn, ChangeMinColumn);
|
|
MinColumn = std::max(MinColumn, ChangeMinColumn);
|
|
|
|
+ MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -242,6 +261,110 @@ void WhitespaceManager::alignConsecutiveAssignments(unsigned Start,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Walk through all of the changes and find sequences of declaration names to
|
|
|
|
+// align. To do so, keep track of the lines and whether or not a name was found
|
|
|
|
+// on align. If a name is found on a line, extend the current sequence. If the
|
|
|
|
+// current line cannot be part of a sequence, e.g. because there is an empty
|
|
|
|
+// line before it or it contains non-declarations, finalize the previous
|
|
|
|
+// sequence.
|
|
|
|
+void WhitespaceManager::alignConsecutiveDeclarations() {
|
|
|
|
+ if (!Style.AlignConsecutiveDeclarations)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ unsigned MinColumn = 0;
|
|
|
|
+ unsigned MaxColumn = UINT_MAX;
|
|
|
|
+ unsigned StartOfSequence = 0;
|
|
|
|
+ unsigned EndOfSequence = 0;
|
|
|
|
+ bool FoundDeclarationOnLine = false;
|
|
|
|
+ bool FoundLeftBraceOnLine = false;
|
|
|
|
+ bool FoundLeftParenOnLine = false;
|
|
|
|
+
|
|
|
|
+ auto AlignSequence = [&] {
|
|
|
|
+ if (StartOfSequence > 0 && StartOfSequence < EndOfSequence)
|
|
|
|
+ alignConsecutiveDeclarations(StartOfSequence, EndOfSequence, MinColumn);
|
|
|
|
+ MinColumn = 0;
|
|
|
|
+ MaxColumn = UINT_MAX;
|
|
|
|
+ StartOfSequence = 0;
|
|
|
|
+ EndOfSequence = 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
|
|
|
|
+ if (Changes[i].NewlinesBefore != 0) {
|
|
|
|
+ EndOfSequence = i;
|
|
|
|
+ if (Changes[i].NewlinesBefore > 1 || !FoundDeclarationOnLine ||
|
|
|
|
+ FoundLeftBraceOnLine || FoundLeftParenOnLine)
|
|
|
|
+ AlignSequence();
|
|
|
|
+ FoundDeclarationOnLine = false;
|
|
|
|
+ FoundLeftBraceOnLine = false;
|
|
|
|
+ FoundLeftParenOnLine = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (Changes[i].Kind == tok::r_brace) {
|
|
|
|
+ if (!FoundLeftBraceOnLine)
|
|
|
|
+ AlignSequence();
|
|
|
|
+ FoundLeftBraceOnLine = false;
|
|
|
|
+ } else if (Changes[i].Kind == tok::l_brace) {
|
|
|
|
+ FoundLeftBraceOnLine = true;
|
|
|
|
+ if (!FoundDeclarationOnLine)
|
|
|
|
+ AlignSequence();
|
|
|
|
+ } else if (Changes[i].Kind == tok::r_paren) {
|
|
|
|
+ if (!FoundLeftParenOnLine)
|
|
|
|
+ AlignSequence();
|
|
|
|
+ FoundLeftParenOnLine = false;
|
|
|
|
+ } else if (Changes[i].Kind == tok::l_paren) {
|
|
|
|
+ FoundLeftParenOnLine = true;
|
|
|
|
+ if (!FoundDeclarationOnLine)
|
|
|
|
+ AlignSequence();
|
|
|
|
+ } else if (!FoundDeclarationOnLine && !FoundLeftBraceOnLine &&
|
|
|
|
+ !FoundLeftParenOnLine && Changes[i].IsStartOfDeclName) {
|
|
|
|
+ FoundDeclarationOnLine = true;
|
|
|
|
+ if (StartOfSequence == 0)
|
|
|
|
+ StartOfSequence = i;
|
|
|
|
+
|
|
|
|
+ unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
|
|
|
|
+ int LineLengthAfter = -Changes[i].Spaces;
|
|
|
|
+ for (unsigned j = i; j != e && Changes[j].NewlinesBefore == 0; ++j)
|
|
|
|
+ LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
|
|
|
|
+ unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
|
|
|
|
+
|
|
|
|
+ if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) {
|
|
|
|
+ AlignSequence();
|
|
|
|
+ StartOfSequence = i;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ MinColumn = std::max(MinColumn, ChangeMinColumn);
|
|
|
|
+ MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ EndOfSequence = Changes.size();
|
|
|
|
+ AlignSequence();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void WhitespaceManager::alignConsecutiveDeclarations(unsigned Start,
|
|
|
|
+ unsigned End,
|
|
|
|
+ unsigned Column) {
|
|
|
|
+ bool FoundDeclarationOnLine = false;
|
|
|
|
+ int Shift = 0;
|
|
|
|
+ for (unsigned i = Start; i != End; ++i) {
|
|
|
|
+ if (Changes[i].NewlinesBefore != 0) {
|
|
|
|
+ FoundDeclarationOnLine = false;
|
|
|
|
+ Shift = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!FoundDeclarationOnLine && Changes[i].IsStartOfDeclName) {
|
|
|
|
+ FoundDeclarationOnLine = true;
|
|
|
|
+ Shift = Column - Changes[i].StartOfTokenColumn;
|
|
|
|
+ Changes[i].Spaces += Shift;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assert(Shift >= 0);
|
|
|
|
+ Changes[i].StartOfTokenColumn += Shift;
|
|
|
|
+ if (i + 1 != Changes.size())
|
|
|
|
+ Changes[i + 1].PreviousEndOfTokenColumn += Shift;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void WhitespaceManager::alignTrailingComments() {
|
|
void WhitespaceManager::alignTrailingComments() {
|
|
unsigned MinColumn = 0;
|
|
unsigned MinColumn = 0;
|
|
unsigned MaxColumn = UINT_MAX;
|
|
unsigned MaxColumn = UINT_MAX;
|