}
BreakableSingleLineToken::BreakableSingleLineToken(
- const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
- StringRef Prefix, StringRef Postfix, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style)
- : BreakableToken(Tok, IndentLevel, InPPDirective, Encoding, Style),
+ const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
+ StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style)
+ : BreakableToken(Tok, InPPDirective, Encoding, Style),
StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
assert(Tok.TokenText.endswith(Postfix));
Line = Tok.TokenText.substr(
}
BreakableStringLiteral::BreakableStringLiteral(
- const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
- StringRef Prefix, StringRef Postfix, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style)
- : BreakableSingleLineToken(Tok, IndentLevel, StartColumn, Prefix, Postfix,
- InPPDirective, Encoding, Style) {}
+ const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
+ StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style)
+ : BreakableSingleLineToken(Tok, StartColumn, Prefix, Postfix, InPPDirective,
+ Encoding, Style) {}
BreakableToken::Split
BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
--LeadingSpaces;
Whitespaces.replaceWhitespaceInToken(
Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
- Prefix, InPPDirective, 1, IndentLevel, LeadingSpaces);
+ Prefix, InPPDirective, 1, LeadingSpaces);
}
BreakableComment::BreakableComment(const FormatToken &Token,
- unsigned IndentLevel, unsigned StartColumn,
+ unsigned StartColumn,
unsigned OriginalStartColumn,
bool FirstInLine, bool InPPDirective,
encoding::Encoding Encoding,
const FormatStyle &Style)
- : BreakableToken(Token, IndentLevel, InPPDirective, Encoding, Style),
+ : BreakableToken(Token, InPPDirective, Encoding, Style),
StartColumn(StartColumn), OriginalStartColumn(OriginalStartColumn),
FirstInLine(FirstInLine) {}
unsigned CharsToRemove = Split.second;
Whitespaces.replaceWhitespaceInToken(
tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", "",
- /*InPPDirective=*/false,
- /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1);
+ /*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
}
BreakableToken::Split
}
BreakableBlockComment::BreakableBlockComment(
- const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
+ const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
encoding::Encoding Encoding, const FormatStyle &Style)
- : BreakableComment(Token, IndentLevel, StartColumn, OriginalStartColumn,
- FirstInLine, InPPDirective, Encoding, Style) {
+ : BreakableComment(Token, StartColumn, OriginalStartColumn, FirstInLine,
+ InPPDirective, Encoding, Style) {
assert(Tok.is(TT_BlockComment) &&
"block comment section must start with a block comment");
assert(LocalIndentAtLineBreak >= Prefix.size());
Whitespaces.replaceWhitespaceInToken(
tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", Prefix,
- InPPDirective, /*Newlines=*/1, IndentLevel,
+ InPPDirective, /*Newlines=*/1,
/*Spaces=*/LocalIndentAtLineBreak - Prefix.size());
}
WhitespaceOffsetInToken;
Whitespaces.replaceWhitespaceInToken(
tokenAt(LineIndex), WhitespaceOffsetInToken,
- /*ReplaceChars=*/WhitespaceLength,
- /*PreviousPostfix=*/"",
- /*CurrentPrefix=*/ReflowPrefix, InPPDirective,
- /*Newlines=*/0, IndentLevel, /*Spaces=*/0);
+ /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"",
+ /*CurrentPrefix=*/ReflowPrefix, InPPDirective, /*Newlines=*/0,
+ /*Spaces=*/0);
// Check if we need to also insert a break at the whitespace range.
// For this we first adapt the reflow split relative to the beginning of the
// content.
tokenAt(LineIndex).TokenText.data() -
WhitespaceOffsetInToken;
Whitespaces.replaceWhitespaceInToken(
- tokenAt(LineIndex), WhitespaceOffsetInToken, WhitespaceLength, "",
- Prefix, InPPDirective, /*Newlines=*/1, IndentLevel,
- ContentColumn[LineIndex] - Prefix.size());
+ tokenAt(LineIndex), WhitespaceOffsetInToken, WhitespaceLength, "", Prefix,
+ InPPDirective, /*Newlines=*/1, ContentColumn[LineIndex] - Prefix.size());
}
unsigned
}
BreakableLineCommentSection::BreakableLineCommentSection(
- const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
+ const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
encoding::Encoding Encoding, const FormatStyle &Style)
- : BreakableComment(Token, IndentLevel, StartColumn, OriginalStartColumn,
- FirstInLine, InPPDirective, Encoding, Style) {
+ : BreakableComment(Token, StartColumn, OriginalStartColumn, FirstInLine,
+ InPPDirective, Encoding, Style) {
assert(Tok.is(TT_LineComment) &&
"line comment section must start with a line comment");
FormatToken *LineTok = nullptr;
assert(IndentAtLineBreak >= Prefix[LineIndex].size());
Whitespaces.replaceWhitespaceInToken(
tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "",
- Prefix[LineIndex], InPPDirective, /*Newlines=*/1, IndentLevel,
+ Prefix[LineIndex], InPPDirective, /*Newlines=*/1,
/*Spaces=*/IndentAtLineBreak - Prefix[LineIndex].size());
}
if (SplitBefore.first != StringRef::npos) {
// Reflow happens between tokens. Replace the whitespace between the
// tokens by the empty string.
- Whitespaces.replaceWhitespace(*Tokens[LineIndex],
- /*Newlines=*/0,
- /*IndentLevel=*/IndentLevel,
- /*Spaces=*/0,
- /*StartOfTokenColumn=*/StartColumn,
- /*InPPDirective=*/false);
+ Whitespaces.replaceWhitespace(
+ *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0,
+ /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false);
// Replace the indent and prefix of the token with the reflow prefix.
unsigned WhitespaceLength =
Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data();
/*CurrentPrefix=*/ReflowPrefix,
/*InPPDirective=*/false,
/*Newlines=*/0,
- /*IndentLevel=*/IndentLevel,
/*Spaces=*/0);
} else {
// This is the first line for the current token, but no reflow with the
if (tokenAt(LineIndex).OriginalColumn != LineColumn) {
Whitespaces.replaceWhitespace(*Tokens[LineIndex],
/*Newlines=*/1,
- /*IndentLevel=*/IndentLevel,
/*Spaces=*/LineColumn,
/*StartOfTokenColumn=*/LineColumn,
/*InPPDirective=*/false);
"at most a space");
Whitespaces.replaceWhitespaceInToken(
tokenAt(LineIndex), OriginalPrefix[LineIndex].size(), 0, "", "",
- /*InPPDirective=*/false,
- /*Newlines=*/0, /*IndentLevel=*/0,
- /*Spaces=*/1);
+ /*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
}
// Add a break after a reflow split has been introduced, if necessary.
// Note that this break doesn't need to be penalized, since it doesn't change
virtual void updateNextToken(LineState &State) const {}
protected:
- BreakableToken(const FormatToken &Tok, unsigned IndentLevel,
- bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style)
- : Tok(Tok), IndentLevel(IndentLevel), InPPDirective(InPPDirective),
- Encoding(Encoding), Style(Style) {}
+ BreakableToken(const FormatToken &Tok, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style)
+ : Tok(Tok), InPPDirective(InPPDirective), Encoding(Encoding),
+ Style(Style) {}
const FormatToken &Tok;
- const unsigned IndentLevel;
const bool InPPDirective;
const encoding::Encoding Encoding;
const FormatStyle &Style;
StringRef::size_type Length) const override;
protected:
- BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
- unsigned StartColumn, StringRef Prefix,
- StringRef Postfix, bool InPPDirective,
- encoding::Encoding Encoding,
+ BreakableSingleLineToken(const FormatToken &Tok, unsigned StartColumn,
+ StringRef Prefix, StringRef Postfix,
+ bool InPPDirective, encoding::Encoding Encoding,
const FormatStyle &Style);
// The column in which the token starts.
///
/// \p StartColumn specifies the column in which the token will start
/// after formatting.
- BreakableStringLiteral(const FormatToken &Tok, unsigned IndentLevel,
- unsigned StartColumn, StringRef Prefix,
- StringRef Postfix, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style);
+ BreakableStringLiteral(const FormatToken &Tok, unsigned StartColumn,
+ StringRef Prefix, StringRef Postfix,
+ bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style);
Split getSplit(unsigned LineIndex, unsigned TailOffset,
unsigned ColumnLimit) const override;
/// after formatting, while \p OriginalStartColumn specifies in which
/// column the comment started before formatting.
/// If the comment starts a line after formatting, set \p FirstInLine to true.
- BreakableComment(const FormatToken &Token, unsigned IndentLevel,
- unsigned StartColumn, unsigned OriginalStartColumn,
- bool FirstInLine, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style);
+ BreakableComment(const FormatToken &Token, unsigned StartColumn,
+ unsigned OriginalStartColumn, bool FirstInLine,
+ bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style);
public:
unsigned getLineCount() const override;
class BreakableBlockComment : public BreakableComment {
public:
- BreakableBlockComment(const FormatToken &Token, unsigned IndentLevel,
- unsigned StartColumn, unsigned OriginalStartColumn,
- bool FirstInLine, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style);
+ BreakableBlockComment(const FormatToken &Token, unsigned StartColumn,
+ unsigned OriginalStartColumn, bool FirstInLine,
+ bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style);
unsigned getLineLengthAfterSplit(unsigned LineIndex,
unsigned TailOffset,
class BreakableLineCommentSection : public BreakableComment {
public:
- BreakableLineCommentSection(const FormatToken &Token, unsigned IndentLevel,
- unsigned StartColumn,
+ BreakableLineCommentSection(const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine,
bool InPPDirective, encoding::Encoding Encoding,
const FormatStyle &Style);
State.Column = FirstIndent;
State.Line = Line;
State.NextToken = Line->First;
- State.Stack.push_back(ParenState(FirstIndent, Line->Level, FirstIndent,
+ State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
/*AvoidBinPacking=*/false,
/*NoLineBreak=*/false));
State.LineContainsContinuedForLoopSection = false;
unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
if (!DryRun)
- Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
- Spaces, State.Column + Spaces);
+ Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces,
+ State.Column + Spaces);
if (Current.is(TT_SelectorName) &&
!State.Stack.back().ObjCSelectorNameFound) {
if (!DryRun) {
unsigned Newlines = std::max(
1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
- Whitespaces.replaceWhitespace(Current, Newlines,
- State.Stack.back().IndentLevel, State.Column,
- State.Column, State.Line->InPPDirective);
+ Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
+ State.Line->InPPDirective);
}
if (!Current.isTrailingComment())
}
unsigned NewIndent;
- unsigned NewIndentLevel = State.Stack.back().IndentLevel;
unsigned LastSpace = State.Stack.back().LastSpace;
bool AvoidBinPacking;
bool BreakBeforeParameter = false;
if (Current.opensBlockOrBlockTypeList(Style)) {
NewIndent = State.Stack.back().NestedBlockIndent + Style.IndentWidth;
NewIndent = std::min(State.Column + 2, NewIndent);
- ++NewIndentLevel;
} else {
NewIndent = State.Stack.back().LastSpace + Style.ContinuationIndentWidth;
}
State.Stack.back().NoLineBreakInOperand ||
(Current.is(TT_TemplateOpener) &&
State.Stack.back().ContainsUnwrappedBuilder));
- State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, LastSpace,
- AvoidBinPacking, NoLineBreak));
+ State.Stack.push_back(
+ ParenState(NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
? Style.ObjCBlockIndentWidth
: Style.IndentWidth);
- State.Stack.push_back(ParenState(
- NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1,
- State.Stack.back().LastSpace, /*AvoidBinPacking=*/true,
- /*NoLineBreak=*/false));
+ State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,
+ /*AvoidBinPacking=*/true,
+ /*NoLineBreak=*/false));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
State.Stack.back().BreakBeforeParameter = true;
}
Text.startswith(Prefix = "u8\"") ||
Text.startswith(Prefix = "L\""))) ||
(Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")"))) {
- Token.reset(new BreakableStringLiteral(
- Current, State.Line->Level, StartColumn, Prefix, Postfix,
- State.Line->InPPDirective, Encoding, Style));
+ Token.reset(new BreakableStringLiteral(Current, StartColumn, Prefix,
+ Postfix, State.Line->InPPDirective,
+ Encoding, Style));
} else {
return 0;
}
switchesFormatting(Current))
return addMultilineToken(Current, State);
Token.reset(new BreakableBlockComment(
- Current, State.Line->Level, StartColumn, Current.OriginalColumn,
- !Current.Previous, State.Line->InPPDirective, Encoding, Style));
+ Current, StartColumn, Current.OriginalColumn, !Current.Previous,
+ State.Line->InPPDirective, Encoding, Style));
} else if (Current.is(TT_LineComment) &&
(Current.Previous == nullptr ||
Current.Previous->isNot(TT_ImplicitStringLiteral))) {
switchesFormatting(Current))
return 0;
Token.reset(new BreakableLineCommentSection(
- Current, State.Line->Level, StartColumn, Current.OriginalColumn,
- !Current.Previous,
+ Current, StartColumn, Current.OriginalColumn, !Current.Previous,
/*InPPDirective=*/false, Encoding, Style));
// We don't insert backslashes when breaking line comments.
ColumnLimit = Style.ColumnLimit;
};
struct ParenState {
- ParenState(unsigned Indent, unsigned IndentLevel, unsigned LastSpace,
- bool AvoidBinPacking, bool NoLineBreak)
- : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
- NestedBlockIndent(Indent), BreakBeforeClosingBrace(false),
- AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
- NoLineBreak(NoLineBreak), NoLineBreakInOperand(false),
- LastOperatorWrapped(true), ContainsLineBreak(false),
- ContainsUnwrappedBuilder(false), AlignColons(true),
- ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false),
- NestedBlockInlined(false) {}
+ ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
+ bool NoLineBreak)
+ : Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent),
+ BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
+ BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
+ NoLineBreakInOperand(false), LastOperatorWrapped(true),
+ ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
+ AlignColons(true), ObjCSelectorNameFound(false),
+ HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
unsigned Indent;
- /// \brief The number of indentation levels of the block.
- unsigned IndentLevel;
-
/// \brief The position of the last space on each level.
///
/// Used e.g. to break like:
/// [], {} or <>.
unsigned NestingLevel = 0;
+ /// \brief The indent level of this token. Copied from the surrounding line.
+ unsigned IndentLevel = 0;
+
/// \brief Penalty for inserting a line break before this token.
unsigned SplitPenalty = 0;
Line.First->TotalLength =
Line.First->IsMultiline ? Style.ColumnLimit : Line.First->ColumnWidth;
- if (!Line.First->Next)
- return;
FormatToken *Current = Line.First->Next;
bool InFunctionDecl = Line.MightBeFunctionDecl;
while (Current) {
}
calculateUnbreakableTailLengths(Line);
+ unsigned IndentLevel = Line.Level;
for (Current = Line.First; Current != nullptr; Current = Current->Next) {
if (Current->Role)
Current->Role->precomputeFormattingInfos(Current);
+ if (Current->MatchingParen &&
+ Current->MatchingParen->opensBlockOrBlockTypeList(Style)) {
+ assert(IndentLevel > 0);
+ --IndentLevel;
+ }
+ Current->IndentLevel = IndentLevel;
+ if (Current->opensBlockOrBlockTypeList(Style))
+ ++IndentLevel;
}
DEBUG({ printDebugInfo(Line); });
if (Previous.Children[0]->First->MustBreakBefore)
return false;
- // Cannot merge multiple statements into a single line.
- if (Previous.Children.size() > 1)
- return false;
-
// Cannot merge into one line if this line ends on a comment.
if (Previous.is(tok::comment))
return false;
+ // Cannot merge multiple statements into a single line.
+ if (Previous.Children.size() > 1)
+ return false;
+
+ const AnnotatedLine *Child = Previous.Children[0];
// We can't put the closing "}" on a line with a trailing comment.
- if (Previous.Children[0]->Last->isTrailingComment())
+ if (Child->Last->isTrailingComment())
return false;
// If the child line exceeds the column limit, we wouldn't want to merge it.
// We add +2 for the trailing " }".
if (Style.ColumnLimit > 0 &&
- Previous.Children[0]->Last->TotalLength + State.Column + 2 >
- Style.ColumnLimit)
+ Child->Last->TotalLength + State.Column + 2 > Style.ColumnLimit)
return false;
if (!DryRun) {
Whitespaces->replaceWhitespace(
- *Previous.Children[0]->First,
- /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,
+ *Child->First, /*Newlines=*/0, /*Spaces=*/1,
/*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
}
- Penalty += formatLine(*Previous.Children[0], State.Column + 1, DryRun);
+ Penalty += formatLine(*Child, State.Column + 1, DryRun);
- State.Column += 1 + Previous.Children[0]->Last->TotalLength;
+ State.Column += 1 + Child->Last->TotalLength;
return true;
}
if (ShouldFormat && TheLine.Type != LT_Invalid) {
if (!DryRun)
- formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent,
- TheLine.InPPDirective);
+ formatFirstToken(TheLine, PreviousLine, Indent);
NextLine = Joiner.getNextMergedLine(DryRun, IndentTracker);
unsigned ColumnLimit = getColumnLimit(TheLine.InPPDirective, NextLine);
TheLine.LeadingEmptyLinesAffected);
// Format the first token.
if (ReformatLeadingWhitespace)
- formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level,
- TheLine.First->OriginalColumn,
- TheLine.InPPDirective);
+ formatFirstToken(TheLine, PreviousLine,
+ TheLine.First->OriginalColumn);
else
Whitespaces->addUntouchableToken(*TheLine.First,
TheLine.InPPDirective);
return Penalty;
}
-void UnwrappedLineFormatter::formatFirstToken(FormatToken &RootToken,
+void UnwrappedLineFormatter::formatFirstToken(const AnnotatedLine &Line,
const AnnotatedLine *PreviousLine,
- unsigned IndentLevel,
- unsigned Indent,
- bool InPPDirective) {
+ unsigned Indent) {
+ FormatToken& RootToken = *Line.First;
if (RootToken.is(tok::eof)) {
unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u);
- Whitespaces->replaceWhitespace(RootToken, Newlines, /*IndentLevel=*/0,
- /*Spaces=*/0, /*TargetColumn=*/0);
+ Whitespaces->replaceWhitespace(RootToken, Newlines, /*Spaces=*/0,
+ /*TargetColumn=*/0);
return;
}
unsigned Newlines =
(!PreviousLine->InPPDirective || !RootToken.HasUnescapedNewline))
Newlines = std::min(1u, Newlines);
- Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent,
- Indent, InPPDirective &&
- !RootToken.HasUnescapedNewline);
+ Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
+ Line.InPPDirective &&
+ !RootToken.HasUnescapedNewline);
}
unsigned
private:
/// \brief Add a new line and the required indent before the first Token
/// of the \c UnwrappedLine if there was no structural parsing error.
- void formatFirstToken(FormatToken &RootToken,
- const AnnotatedLine *PreviousLine, unsigned IndentLevel,
- unsigned Indent, bool InPPDirective);
+ void formatFirstToken(const AnnotatedLine &Line,
+ const AnnotatedLine *PreviousLine, unsigned Indent);
/// \brief Returns the column limit for a line, taking into account whether we
/// need an escaped newline due to a continued preprocessor directive.
// starting from a specific additional offset. Improves performance if there
// are many nested blocks.
std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,
- unsigned> PenaltyCache;
+ unsigned>
+ PenaltyCache;
ContinuationIndenter *Indenter;
WhitespaceManager *Whitespaces;
C2.OriginalWhitespaceRange.getBegin());
}
-WhitespaceManager::Change::Change(
- bool CreateReplacement, SourceRange OriginalWhitespaceRange,
- unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
- unsigned NewlinesBefore, StringRef PreviousLinePostfix,
- StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective,
- bool IsStartOfDeclName, bool IsInsideToken)
- : CreateReplacement(CreateReplacement),
+WhitespaceManager::Change::Change(const FormatToken &Tok,
+ bool CreateReplacement,
+ SourceRange OriginalWhitespaceRange,
+ int Spaces, unsigned StartOfTokenColumn,
+ unsigned NewlinesBefore,
+ StringRef PreviousLinePostfix,
+ StringRef CurrentLinePrefix,
+ bool ContinuesPPDirective, bool IsInsideToken)
+ : Tok(&Tok), CreateReplacement(CreateReplacement),
OriginalWhitespaceRange(OriginalWhitespaceRange),
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
PreviousLinePostfix(PreviousLinePostfix),
- CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
- ContinuesPPDirective(ContinuesPPDirective),
- IsStartOfDeclName(IsStartOfDeclName), IndentLevel(IndentLevel),
- Spaces(Spaces), IsInsideToken(IsInsideToken), IsTrailingComment(false),
- TokenLength(0), PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
+ CurrentLinePrefix(CurrentLinePrefix),
+ ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
+ IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
+ PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
StartOfBlockComment(nullptr), IndentationOffset(0) {}
void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
- unsigned IndentLevel, unsigned Spaces,
+ unsigned Spaces,
unsigned StartOfTokenColumn,
bool InPPDirective) {
if (Tok.Finalized)
return;
Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
- Changes.push_back(
- Change(/*CreateReplacement=*/true, Tok.WhitespaceRange, IndentLevel,
- Spaces, StartOfTokenColumn, Newlines, "", "", Tok.Tok.getKind(),
- InPPDirective && !Tok.IsFirst,
- Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
- /*IsInsideToken=*/false));
+ Changes.push_back(Change(Tok, /*CreateReplacement=*/true,
+ Tok.WhitespaceRange, Spaces, StartOfTokenColumn,
+ Newlines, "", "", InPPDirective && !Tok.IsFirst,
+ /*IsInsideToken=*/false));
}
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
bool InPPDirective) {
if (Tok.Finalized)
return;
- Changes.push_back(Change(
- /*CreateReplacement=*/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),
- /*IsInsideToken=*/false));
+ Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
+ Tok.WhitespaceRange, /*Spaces=*/0,
+ Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
+ InPPDirective && !Tok.IsFirst,
+ /*IsInsideToken=*/false));
}
void WhitespaceManager::replaceWhitespaceInToken(
const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
- unsigned Newlines, unsigned IndentLevel, int Spaces) {
+ unsigned Newlines, int Spaces) {
if (Tok.Finalized)
return;
SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
- Changes.push_back(Change(
- true, SourceRange(Start, Start.getLocWithOffset(ReplaceChars)),
- IndentLevel, Spaces, std::max(0, Spaces), Newlines, PreviousPostfix,
- CurrentPrefix, Tok.is(TT_LineComment) ? tok::comment : tok::unknown,
- InPPDirective && !Tok.IsFirst,
- Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
- /*IsInsideToken=*/Newlines == 0));
+ Changes.push_back(
+ Change(Tok, /*CreateReplacement=*/true,
+ SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
+ std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
+ InPPDirective && !Tok.IsFirst, /*IsInsideToken=*/true));
}
const tooling::Replacements &WhitespaceManager::generateReplacements() {
Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
Changes[i - 1].IsTrailingComment =
- (Changes[i].NewlinesBefore > 0 || Changes[i].Kind == tok::eof ||
- (Changes[i].IsInsideToken && Changes[i].Kind == tok::comment)) &&
- Changes[i - 1].Kind == tok::comment &&
+ (Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) ||
+ (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) &&
+ Changes[i - 1].Tok->is(tok::comment) &&
// FIXME: This is a dirty hack. The problem is that
// BreakableLineCommentSection does comment reflow changes and here is
// the aligning of trailing comments. Consider the case where we reflow
// FIXME: The last token is currently not always an eof token; in those
// cases, setting TokenLength of the last token to 0 is wrong.
Changes.back().TokenLength = 0;
- Changes.back().IsTrailingComment = Changes.back().Kind == tok::comment;
+ Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
const WhitespaceManager::Change *LastBlockComment = nullptr;
for (auto &Change : Changes) {
Change.IsTrailingComment = false;
Change.StartOfBlockComment = nullptr;
Change.IndentationOffset = 0;
- if (Change.Kind == tok::comment) {
- LastBlockComment = &Change;
- } else if (Change.Kind == tok::unknown) {
- if ((Change.StartOfBlockComment = LastBlockComment))
- Change.IndentationOffset =
- Change.StartOfTokenColumn -
- Change.StartOfBlockComment->StartOfTokenColumn;
+ if (Change.Tok->is(tok::comment)) {
+ if (Change.Tok->is(TT_LineComment) || !Change.IsInsideToken)
+ LastBlockComment = &Change;
+ else {
+ if ((Change.StartOfBlockComment = LastBlockComment))
+ Change.IndentationOffset =
+ Change.StartOfTokenColumn -
+ Change.StartOfBlockComment->StartOfTokenColumn;
+ }
} else {
LastBlockComment = nullptr;
}
FoundMatchOnLine = false;
}
- if (Changes[i].Kind == tok::comma) {
+ if (Changes[i].Tok->is(tok::comma)) {
++CommasBeforeMatch;
- } else if (Changes[i].Kind == tok::r_brace ||
- Changes[i].Kind == tok::r_paren ||
- Changes[i].Kind == tok::r_square) {
+ } else if (Changes[i].Tok->isOneOf(tok::r_brace, tok::r_paren,
+ tok::r_square)) {
--NestingLevel;
- } else if (Changes[i].Kind == tok::l_brace ||
- Changes[i].Kind == tok::l_paren ||
- Changes[i].Kind == tok::l_square) {
+ } else if (Changes[i].Tok->isOneOf(tok::l_brace, tok::l_paren,
+ tok::l_square)) {
// We want sequences to skip over child scopes if possible, but not the
// other way around.
NestingLevelOfLastMatch = std::min(NestingLevelOfLastMatch, NestingLevel);
if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
return false;
- return C.Kind == tok::equal;
+ return C.Tok->is(tok::equal);
},
Changes);
}
// float const* v2;
// SomeVeryLongType const& v3;
- AlignTokens(Style, [](Change const &C) { return C.IsStartOfDeclName; },
+ AlignTokens(Style,
+ [](Change const &C) {
+ return C.Tok->isOneOf(TT_StartOfName,
+ TT_FunctionDeclarationName);
+ },
Changes);
}
// If this comment follows an } in column 0, it probably documents the
// closing of a namespace and we don't want to align it.
bool FollowsRBraceInColumn0 = i > 0 && Changes[i].NewlinesBefore == 0 &&
- Changes[i - 1].Kind == tok::r_brace &&
+ Changes[i - 1].Tok->is(tok::r_brace) &&
Changes[i - 1].StartOfTokenColumn == 0;
bool WasAlignedWithStartOfNextLine = false;
if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
unsigned CommentColumn = SourceMgr.getSpellingColumnNumber(
Changes[i].OriginalWhitespaceRange.getEnd());
for (unsigned j = i + 1; j != e; ++j) {
- if (Changes[j].Kind == tok::comment ||
- Changes[j].Kind == tok::unknown)
- // Skip over comments and unknown tokens. "unknown tokens are used for
- // the continuation of multiline comments.
+ if (Changes[j].Tok->is(tok::comment))
continue;
unsigned NextColumn = SourceMgr.getSpellingColumnNumber(
C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
else
appendNewlineText(ReplacementText, C.NewlinesBefore);
- appendIndentText(ReplacementText, C.IndentLevel, std::max(0, C.Spaces),
+ appendIndentText(ReplacementText, C.Tok->IndentLevel,
+ std::max(0, C.Spaces),
C.StartOfTokenColumn - std::max(0, C.Spaces));
ReplacementText.append(C.CurrentLinePrefix);
storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
/// \brief Replaces the whitespace in front of \p Tok. Only call once for
/// each \c AnnotatedToken.
- void replaceWhitespace(FormatToken &Tok, unsigned Newlines,
- unsigned IndentLevel, unsigned Spaces,
+ void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces,
unsigned StartOfTokenColumn,
bool InPPDirective = false);
unsigned ReplaceChars,
StringRef PreviousPostfix,
StringRef CurrentPrefix, bool InPPDirective,
- unsigned Newlines, unsigned IndentLevel,
- int Spaces);
+ unsigned Newlines, int Spaces);
/// \brief Returns all the \c Replacements created during formatting.
const tooling::Replacements &generateReplacements();
const SourceManager &SourceMgr;
};
- Change() {}
-
/// \brief Creates a \c Change.
///
/// The generated \c Change will replace the characters at
///
/// \p StartOfTokenColumn and \p InPPDirective will be used to lay out
/// trailing comments and escaped newlines.
- Change(bool CreateReplacement, SourceRange OriginalWhitespaceRange,
- unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
- unsigned NewlinesBefore, StringRef PreviousLinePostfix,
- StringRef CurrentLinePrefix, tok::TokenKind Kind,
- bool ContinuesPPDirective, bool IsStartOfDeclName,
- bool IsInsideToken);
+ Change(const FormatToken &Tok, bool CreateReplacement,
+ SourceRange OriginalWhitespaceRange, int Spaces,
+ unsigned StartOfTokenColumn, unsigned NewlinesBefore,
+ StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
+ bool ContinuesPPDirective, bool IsInsideToken);
+
+ // The kind of the token whose whitespace this change replaces, or in which
+ // this change inserts whitespace.
+ // FIXME: Currently this is not set correctly for breaks inside comments, as
+ // the \c BreakableToken is still doing its own alignment.
+ const FormatToken *Tok;
bool CreateReplacement;
// Changes might be in the middle of a token, so we cannot just keep the
unsigned NewlinesBefore;
std::string PreviousLinePostfix;
std::string CurrentLinePrefix;
- // The kind of the token whose whitespace this change replaces, or in which
- // this change inserts whitespace.
- // FIXME: Currently this is not set correctly for breaks inside comments, as
- // the \c BreakableToken is still doing its own alignment.
- tok::TokenKind Kind;
bool ContinuesPPDirective;
- bool IsStartOfDeclName;
-
- // The number of nested blocks the token is in. This is used to add tabs
- // only for the indentation, and not for alignment, when
- // UseTab = US_ForIndentation.
- unsigned IndentLevel;
// The number of spaces in front of the token or broken part of the token.
// This will be adapted when aligning tokens.