forked from OSchip/llvm-project
Implemented tab usage only for indentation (http://llvm.org/PR17363)
Summary: Changed UseTab to be a enum with three options: Never, Always, ForIndentation (true/false are still supported when reading .clang-format). IndentLevel should currently be propagated correctly for all tokens, except for block comments. Please take a look at the general idea before I start dealing with block comments. Reviewers: klimek, djasper Reviewed By: klimek CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1770 llvm-svn: 191527
This commit is contained in:
parent
ca9bd8fac1
commit
3c3d09c885
|
@ -166,9 +166,19 @@ struct FormatStyle {
|
|||
/// \brief If \c true, always break before multiline string literals.
|
||||
bool AlwaysBreakBeforeMultilineStrings;
|
||||
|
||||
/// \brief If \c true, \c IndentWidth consecutive spaces will be replaced
|
||||
/// with tab characters.
|
||||
bool UseTab;
|
||||
/// \brief Different ways to use tab in formatting.
|
||||
enum UseTabStyle {
|
||||
/// Never use tab.
|
||||
UT_Never,
|
||||
/// Use tabs only for indentation.
|
||||
UT_ForIndentation,
|
||||
/// Use tabs whenever we need to fill whitespace that spans at least from
|
||||
/// one tab stop to the next one.
|
||||
UT_Always
|
||||
};
|
||||
|
||||
/// \brief The way to use tab characters in the resulting file.
|
||||
UseTabStyle UseTab;
|
||||
|
||||
/// \brief If \c true, binary operators will be placed after line breaks.
|
||||
bool BreakBeforeBinaryOperators;
|
||||
|
|
|
@ -145,10 +145,10 @@ unsigned BreakableSingleLineToken::getLineLengthAfterSplit(
|
|||
}
|
||||
|
||||
BreakableSingleLineToken::BreakableSingleLineToken(
|
||||
const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
|
||||
StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
|
||||
const FormatStyle &Style)
|
||||
: BreakableToken(Tok, InPPDirective, Encoding, Style),
|
||||
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),
|
||||
StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
|
||||
assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix));
|
||||
Line = Tok.TokenText.substr(
|
||||
|
@ -156,11 +156,11 @@ BreakableSingleLineToken::BreakableSingleLineToken(
|
|||
}
|
||||
|
||||
BreakableStringLiteral::BreakableStringLiteral(
|
||||
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) {}
|
||||
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) {}
|
||||
|
||||
BreakableToken::Split
|
||||
BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
|
||||
|
@ -175,7 +175,7 @@ void BreakableStringLiteral::insertBreak(unsigned LineIndex,
|
|||
WhitespaceManager &Whitespaces) {
|
||||
Whitespaces.replaceWhitespaceInToken(
|
||||
Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
|
||||
Prefix, InPPDirective, 1, StartColumn);
|
||||
Prefix, InPPDirective, 1, IndentLevel, StartColumn);
|
||||
}
|
||||
|
||||
static StringRef getLineCommentPrefix(StringRef Comment) {
|
||||
|
@ -186,12 +186,10 @@ static StringRef getLineCommentPrefix(StringRef Comment) {
|
|||
return "";
|
||||
}
|
||||
|
||||
BreakableLineComment::BreakableLineComment(const FormatToken &Token,
|
||||
unsigned StartColumn,
|
||||
bool InPPDirective,
|
||||
encoding::Encoding Encoding,
|
||||
const FormatStyle &Style)
|
||||
: BreakableSingleLineToken(Token, StartColumn,
|
||||
BreakableLineComment::BreakableLineComment(
|
||||
const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
|
||||
bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style)
|
||||
: BreakableSingleLineToken(Token, IndentLevel, StartColumn,
|
||||
getLineCommentPrefix(Token.TokenText), "",
|
||||
InPPDirective, Encoding, Style) {
|
||||
OriginalPrefix = Prefix;
|
||||
|
@ -216,7 +214,7 @@ void BreakableLineComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
|
|||
WhitespaceManager &Whitespaces) {
|
||||
Whitespaces.replaceWhitespaceInToken(
|
||||
Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second,
|
||||
Postfix, Prefix, InPPDirective, 1, StartColumn);
|
||||
Postfix, Prefix, InPPDirective, 1, IndentLevel, StartColumn);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -224,15 +222,15 @@ BreakableLineComment::replaceWhitespaceBefore(unsigned LineIndex,
|
|||
WhitespaceManager &Whitespaces) {
|
||||
if (OriginalPrefix != Prefix) {
|
||||
Whitespaces.replaceWhitespaceInToken(Tok, OriginalPrefix.size(), 0, "", "",
|
||||
false, 0, 1);
|
||||
false, 0, /*IndentLevel=*/0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
BreakableBlockComment::BreakableBlockComment(
|
||||
const FormatToken &Token, unsigned StartColumn,
|
||||
const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
|
||||
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
|
||||
encoding::Encoding Encoding, const FormatStyle &Style)
|
||||
: BreakableToken(Token, InPPDirective, Encoding, Style) {
|
||||
: BreakableToken(Token, IndentLevel, InPPDirective, Encoding, Style) {
|
||||
StringRef TokenText(Token.TokenText);
|
||||
assert(TokenText.startswith("/*") && TokenText.endswith("*/"));
|
||||
TokenText.substr(2, TokenText.size() - 4).split(Lines, "\n");
|
||||
|
@ -327,12 +325,6 @@ void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
|
|||
LeadingWhitespace[LineIndex] =
|
||||
Lines[LineIndex].begin() - Lines[LineIndex - 1].end();
|
||||
|
||||
// FIXME: We currently count tabs as 1 character. To solve this, we need to
|
||||
// get the correct indentation width of the start of the comment, which
|
||||
// requires correct counting of the tab expansions before the comment, and
|
||||
// a configurable tab width. Since the current implementation only breaks
|
||||
// if leading tabs are intermixed with spaces, that is not a high priority.
|
||||
|
||||
// Adjust the start column uniformly accross all lines.
|
||||
StartOfLineColumn[LineIndex] = std::max<int>(
|
||||
0,
|
||||
|
@ -376,9 +368,9 @@ void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
|
|||
Text.data() - Tok.TokenText.data() + Split.first;
|
||||
unsigned CharsToRemove = Split.second;
|
||||
assert(IndentAtLineBreak >= Decoration.size());
|
||||
Whitespaces.replaceWhitespaceInToken(Tok, BreakOffsetInToken, CharsToRemove,
|
||||
"", Prefix, InPPDirective, 1,
|
||||
IndentAtLineBreak - Decoration.size());
|
||||
Whitespaces.replaceWhitespaceInToken(
|
||||
Tok, BreakOffsetInToken, CharsToRemove, "", Prefix, InPPDirective, 1,
|
||||
IndentLevel, IndentAtLineBreak - Decoration.size());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -412,7 +404,8 @@ BreakableBlockComment::replaceWhitespaceBefore(unsigned LineIndex,
|
|||
assert(StartOfLineColumn[LineIndex] >= Prefix.size());
|
||||
Whitespaces.replaceWhitespaceInToken(
|
||||
Tok, WhitespaceOffsetInToken, LeadingWhitespace[LineIndex], "", Prefix,
|
||||
InPPDirective, 1, StartOfLineColumn[LineIndex] - Prefix.size());
|
||||
InPPDirective, 1, IndentLevel,
|
||||
StartOfLineColumn[LineIndex] - Prefix.size());
|
||||
}
|
||||
|
||||
unsigned
|
||||
|
|
|
@ -66,12 +66,14 @@ public:
|
|||
WhitespaceManager &Whitespaces) {}
|
||||
|
||||
protected:
|
||||
BreakableToken(const FormatToken &Tok, bool InPPDirective,
|
||||
encoding::Encoding Encoding, const FormatStyle &Style)
|
||||
: Tok(Tok), InPPDirective(InPPDirective), Encoding(Encoding),
|
||||
Style(Style) {}
|
||||
BreakableToken(const FormatToken &Tok, unsigned IndentLevel,
|
||||
bool InPPDirective, encoding::Encoding Encoding,
|
||||
const FormatStyle &Style)
|
||||
: Tok(Tok), IndentLevel(IndentLevel), InPPDirective(InPPDirective),
|
||||
Encoding(Encoding), Style(Style) {}
|
||||
|
||||
const FormatToken &Tok;
|
||||
const unsigned IndentLevel;
|
||||
const bool InPPDirective;
|
||||
const encoding::Encoding Encoding;
|
||||
const FormatStyle &Style;
|
||||
|
@ -88,9 +90,10 @@ public:
|
|||
StringRef::size_type Length) const;
|
||||
|
||||
protected:
|
||||
BreakableSingleLineToken(const FormatToken &Tok, unsigned StartColumn,
|
||||
StringRef Prefix, StringRef Postfix,
|
||||
bool InPPDirective, encoding::Encoding Encoding,
|
||||
BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
|
||||
unsigned StartColumn, StringRef Prefix,
|
||||
StringRef Postfix, bool InPPDirective,
|
||||
encoding::Encoding Encoding,
|
||||
const FormatStyle &Style);
|
||||
|
||||
// The column in which the token starts.
|
||||
|
@ -109,10 +112,10 @@ public:
|
|||
///
|
||||
/// \p StartColumn specifies the column in which the token will start
|
||||
/// after formatting.
|
||||
BreakableStringLiteral(const FormatToken &Tok, unsigned StartColumn,
|
||||
StringRef Prefix, StringRef Postfix,
|
||||
bool InPPDirective, encoding::Encoding Encoding,
|
||||
const FormatStyle &Style);
|
||||
BreakableStringLiteral(const FormatToken &Tok, unsigned IndentLevel,
|
||||
unsigned StartColumn, StringRef Prefix,
|
||||
StringRef Postfix, bool InPPDirective,
|
||||
encoding::Encoding Encoding, const FormatStyle &Style);
|
||||
|
||||
virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
|
||||
unsigned ColumnLimit) const;
|
||||
|
@ -126,9 +129,9 @@ public:
|
|||
///
|
||||
/// \p StartColumn specifies the column in which the comment will start
|
||||
/// after formatting.
|
||||
BreakableLineComment(const FormatToken &Token, unsigned StartColumn,
|
||||
bool InPPDirective, encoding::Encoding Encoding,
|
||||
const FormatStyle &Style);
|
||||
BreakableLineComment(const FormatToken &Token, unsigned IndentLevel,
|
||||
unsigned StartColumn, bool InPPDirective,
|
||||
encoding::Encoding Encoding, const FormatStyle &Style);
|
||||
|
||||
virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
|
||||
unsigned ColumnLimit) const;
|
||||
|
@ -150,10 +153,10 @@ public:
|
|||
/// 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.
|
||||
BreakableBlockComment(const FormatToken &Token, unsigned StartColumn,
|
||||
unsigned OriginaStartColumn, bool FirstInLine,
|
||||
bool InPPDirective, encoding::Encoding Encoding,
|
||||
const FormatStyle &Style);
|
||||
BreakableBlockComment(const FormatToken &Token, unsigned IndentLevel,
|
||||
unsigned StartColumn, unsigned OriginaStartColumn,
|
||||
bool FirstInLine, bool InPPDirective,
|
||||
encoding::Encoding Encoding, const FormatStyle &Style);
|
||||
|
||||
virtual unsigned getLineCount() const;
|
||||
virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
|
||||
|
|
|
@ -303,12 +303,13 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
|
|||
State.Stack.back().BreakBeforeParameter = false;
|
||||
|
||||
if (!DryRun) {
|
||||
unsigned NewLines = 1;
|
||||
unsigned Newlines = 1;
|
||||
if (Current.is(tok::comment))
|
||||
NewLines = std::max(NewLines, std::min(Current.NewlinesBefore,
|
||||
Newlines = std::max(Newlines, std::min(Current.NewlinesBefore,
|
||||
Style.MaxEmptyLinesToKeep + 1));
|
||||
Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
|
||||
State.Column, State.Line->InPPDirective);
|
||||
Whitespaces.replaceWhitespace(Current, Newlines, State.Line->Level,
|
||||
State.Column, State.Column,
|
||||
State.Line->InPPDirective);
|
||||
}
|
||||
|
||||
if (!Current.isTrailingComment())
|
||||
|
@ -363,7 +364,8 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
|
|||
unsigned Spaces = State.NextToken->SpacesRequiredBefore + ExtraSpaces;
|
||||
|
||||
if (!DryRun)
|
||||
Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column + Spaces);
|
||||
Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
|
||||
Spaces, State.Column + Spaces);
|
||||
|
||||
if (Current.Type == TT_ObjCSelectorName &&
|
||||
State.Stack.back().ColonPos == 0) {
|
||||
|
@ -693,21 +695,22 @@ unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
|
|||
Text.startswith(Prefix = "L\""))) ||
|
||||
(Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")")) ||
|
||||
getRawStringLiteralPrefixPostfix(Text, Prefix, Postfix)) {
|
||||
Token.reset(new BreakableStringLiteral(Current, StartColumn, Prefix,
|
||||
Postfix, State.Line->InPPDirective,
|
||||
Encoding, Style));
|
||||
Token.reset(new BreakableStringLiteral(
|
||||
Current, State.Line->Level, StartColumn, Prefix, Postfix,
|
||||
State.Line->InPPDirective, Encoding, Style));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
|
||||
Token.reset(new BreakableBlockComment(
|
||||
Current, StartColumn, Current.OriginalColumn, !Current.Previous,
|
||||
State.Line->InPPDirective, Encoding, Style));
|
||||
Current, State.Line->Level, StartColumn, Current.OriginalColumn,
|
||||
!Current.Previous, State.Line->InPPDirective, Encoding, Style));
|
||||
} else if (Current.Type == TT_LineComment &&
|
||||
(Current.Previous == NULL ||
|
||||
Current.Previous->Type != TT_ImplicitStringLiteral)) {
|
||||
Token.reset(new BreakableLineComment(
|
||||
Current, StartColumn, State.Line->InPPDirective, Encoding, Style));
|
||||
Token.reset(new BreakableLineComment(Current, State.Line->Level,
|
||||
StartColumn, State.Line->InPPDirective,
|
||||
Encoding, Style));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,19 @@ struct ScalarEnumerationTraits<clang::format::FormatStyle::LanguageStandard> {
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<clang::format::FormatStyle::UseTabStyle> {
|
||||
static void
|
||||
enumeration(IO &IO, clang::format::FormatStyle::UseTabStyle &Value) {
|
||||
IO.enumCase(Value, "Never", clang::format::FormatStyle::UT_Never);
|
||||
IO.enumCase(Value, "false", clang::format::FormatStyle::UT_Never);
|
||||
IO.enumCase(Value, "Always", clang::format::FormatStyle::UT_Always);
|
||||
IO.enumCase(Value, "true", clang::format::FormatStyle::UT_Always);
|
||||
IO.enumCase(Value, "ForIndentation",
|
||||
clang::format::FormatStyle::UT_ForIndentation);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<clang::format::FormatStyle::BraceBreakingStyle> {
|
||||
static void
|
||||
|
@ -194,7 +207,7 @@ FormatStyle getLLVMStyle() {
|
|||
LLVMStyle.PointerBindsToType = false;
|
||||
LLVMStyle.SpacesBeforeTrailingComments = 1;
|
||||
LLVMStyle.Standard = FormatStyle::LS_Cpp03;
|
||||
LLVMStyle.UseTab = false;
|
||||
LLVMStyle.UseTab = FormatStyle::UT_Never;
|
||||
LLVMStyle.SpacesInParentheses = false;
|
||||
LLVMStyle.SpaceInEmptyParentheses = false;
|
||||
LLVMStyle.SpacesInCStyleCastParentheses = false;
|
||||
|
@ -237,7 +250,7 @@ FormatStyle getGoogleStyle() {
|
|||
GoogleStyle.PointerBindsToType = true;
|
||||
GoogleStyle.SpacesBeforeTrailingComments = 2;
|
||||
GoogleStyle.Standard = FormatStyle::LS_Auto;
|
||||
GoogleStyle.UseTab = false;
|
||||
GoogleStyle.UseTab = FormatStyle::UT_Never;
|
||||
GoogleStyle.SpacesInParentheses = false;
|
||||
GoogleStyle.SpaceInEmptyParentheses = false;
|
||||
GoogleStyle.SpacesInCStyleCastParentheses = false;
|
||||
|
@ -539,7 +552,7 @@ private:
|
|||
Style.MaxEmptyLinesToKeep + 1);
|
||||
Newlines = std::max(1u, Newlines);
|
||||
Whitespaces->replaceWhitespace(
|
||||
*(*I)->First, Newlines, /*Spaces=*/Indent,
|
||||
*(*I)->First, Newlines, (*I)->Level, /*Spaces=*/Indent,
|
||||
/*StartOfTokenColumn=*/Indent, Line.InPPDirective);
|
||||
}
|
||||
UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style, **I);
|
||||
|
@ -556,10 +569,10 @@ private:
|
|||
return false;
|
||||
|
||||
if (!DryRun) {
|
||||
Whitespaces->replaceWhitespace(*LBrace.Children[0]->First,
|
||||
/*Newlines=*/0, /*Spaces=*/1,
|
||||
/*StartOfTokenColumn=*/State.Column,
|
||||
State.Line->InPPDirective);
|
||||
Whitespaces->replaceWhitespace(
|
||||
*LBrace.Children[0]->First,
|
||||
/*Newlines=*/0, /*IndentLevel=*/1, /*Spaces=*/1,
|
||||
/*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
|
||||
UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style,
|
||||
*LBrace.Children[0]);
|
||||
Penalty += Formatter.format(State.Column + 1, DryRun);
|
||||
|
@ -847,8 +860,9 @@ public:
|
|||
if (TheLine.First->is(tok::eof)) {
|
||||
if (PreviousLineWasTouched) {
|
||||
unsigned NewLines = std::min(FirstTok->NewlinesBefore, 1u);
|
||||
Whitespaces.replaceWhitespace(*TheLine.First, NewLines, /*Indent*/ 0,
|
||||
/*TargetColumn*/ 0);
|
||||
Whitespaces.replaceWhitespace(*TheLine.First, NewLines,
|
||||
/*IndentLevel=*/0, /*Spaces=*/0,
|
||||
/*TargetColumn=*/0);
|
||||
}
|
||||
} else if (TheLine.Type != LT_Invalid &&
|
||||
(WasMoved || FormatPPDirective || touchesLine(TheLine))) {
|
||||
|
@ -1225,7 +1239,7 @@ private:
|
|||
++Newlines;
|
||||
|
||||
Whitespaces.replaceWhitespace(
|
||||
RootToken, Newlines, Indent, Indent,
|
||||
RootToken, Newlines, Indent / Style.IndentWidth, Indent, Indent,
|
||||
InPPDirective && !RootToken.HasUnescapedNewline);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,41 +28,44 @@ WhitespaceManager::Change::IsBeforeInFile::operator()(const Change &C1,
|
|||
|
||||
WhitespaceManager::Change::Change(
|
||||
bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
|
||||
unsigned Spaces, unsigned StartOfTokenColumn, unsigned NewlinesBefore,
|
||||
StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
|
||||
tok::TokenKind Kind, bool ContinuesPPDirective)
|
||||
unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
|
||||
unsigned NewlinesBefore, StringRef PreviousLinePostfix,
|
||||
StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective)
|
||||
: CreateReplacement(CreateReplacement),
|
||||
OriginalWhitespaceRange(OriginalWhitespaceRange),
|
||||
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
|
||||
PreviousLinePostfix(PreviousLinePostfix),
|
||||
CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
|
||||
ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces) {}
|
||||
ContinuesPPDirective(ContinuesPPDirective), IndentLevel(IndentLevel),
|
||||
Spaces(Spaces) {}
|
||||
|
||||
void WhitespaceManager::replaceWhitespace(const FormatToken &Tok,
|
||||
unsigned Newlines, unsigned Spaces,
|
||||
unsigned Newlines,
|
||||
unsigned IndentLevel, unsigned Spaces,
|
||||
unsigned StartOfTokenColumn,
|
||||
bool InPPDirective) {
|
||||
Changes.push_back(Change(true, Tok.WhitespaceRange, Spaces,
|
||||
Changes.push_back(Change(true, Tok.WhitespaceRange, IndentLevel, Spaces,
|
||||
StartOfTokenColumn, Newlines, "", "",
|
||||
Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst));
|
||||
}
|
||||
|
||||
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
|
||||
bool InPPDirective) {
|
||||
Changes.push_back(Change(false, Tok.WhitespaceRange, /*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));
|
||||
}
|
||||
|
||||
void WhitespaceManager::replaceWhitespaceInToken(
|
||||
const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
|
||||
StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
|
||||
unsigned Newlines, unsigned Spaces) {
|
||||
unsigned Newlines, unsigned IndentLevel, unsigned Spaces) {
|
||||
Changes.push_back(Change(
|
||||
true, SourceRange(Tok.getStartOfNonWhitespace().getLocWithOffset(Offset),
|
||||
Tok.getStartOfNonWhitespace().getLocWithOffset(
|
||||
Offset + ReplaceChars)),
|
||||
Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
|
||||
IndentLevel, Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
|
||||
// If we don't add a newline this change doesn't start a comment. Thus,
|
||||
// when we align line comments, we don't need to treat this change as one.
|
||||
// FIXME: We still need to take this change in account to properly
|
||||
|
@ -225,7 +228,8 @@ void WhitespaceManager::generateChanges() {
|
|||
C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
|
||||
else
|
||||
appendNewlineText(ReplacementText, C.NewlinesBefore);
|
||||
appendIndentText(ReplacementText, C.Spaces, C.StartOfTokenColumn - C.Spaces);
|
||||
appendIndentText(ReplacementText, C.IndentLevel, C.Spaces,
|
||||
C.StartOfTokenColumn - C.Spaces);
|
||||
ReplacementText.append(C.CurrentLinePrefix);
|
||||
storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
|
||||
}
|
||||
|
@ -264,11 +268,14 @@ void WhitespaceManager::appendNewlineText(std::string &Text, unsigned Newlines,
|
|||
}
|
||||
}
|
||||
|
||||
void WhitespaceManager::appendIndentText(std::string &Text, unsigned Spaces,
|
||||
void WhitespaceManager::appendIndentText(std::string &Text,
|
||||
unsigned IndentLevel, unsigned Spaces,
|
||||
unsigned WhitespaceStartColumn) {
|
||||
if (!Style.UseTab) {
|
||||
switch (Style.UseTab) {
|
||||
case FormatStyle::UT_Never:
|
||||
Text.append(std::string(Spaces, ' '));
|
||||
} else {
|
||||
break;
|
||||
case FormatStyle::UT_Always: {
|
||||
unsigned FirstTabWidth =
|
||||
Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
|
||||
// Indent with tabs only when there's at least one full tab.
|
||||
|
@ -278,6 +285,19 @@ void WhitespaceManager::appendIndentText(std::string &Text, unsigned Spaces,
|
|||
}
|
||||
Text.append(std::string(Spaces / Style.TabWidth, '\t'));
|
||||
Text.append(std::string(Spaces % Style.TabWidth, ' '));
|
||||
break;
|
||||
}
|
||||
case FormatStyle::UT_ForIndentation:
|
||||
if (WhitespaceStartColumn == 0) {
|
||||
unsigned Indentation = IndentLevel * Style.IndentWidth;
|
||||
if (Indentation > Spaces)
|
||||
Indentation = Spaces;
|
||||
unsigned Tabs = Indentation / Style.TabWidth;
|
||||
Text.append(std::string(Tabs, '\t'));
|
||||
Spaces -= Tabs * Style.TabWidth;
|
||||
}
|
||||
Text.append(std::string(Spaces, ' '));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
/// \brief Replaces the whitespace in front of \p Tok. Only call once for
|
||||
/// each \c AnnotatedToken.
|
||||
void replaceWhitespace(const FormatToken &Tok, unsigned Newlines,
|
||||
unsigned Spaces, unsigned StartOfTokenColumn,
|
||||
unsigned IndentLevel, unsigned Spaces,
|
||||
unsigned StartOfTokenColumn,
|
||||
bool InPPDirective = false);
|
||||
|
||||
/// \brief Adds information about an unchangable token's whitespace.
|
||||
|
@ -65,7 +66,8 @@ public:
|
|||
unsigned ReplaceChars,
|
||||
StringRef PreviousPostfix,
|
||||
StringRef CurrentPrefix, bool InPPDirective,
|
||||
unsigned Newlines, unsigned Spaces);
|
||||
unsigned Newlines, unsigned IndentLevel,
|
||||
unsigned Spaces);
|
||||
|
||||
/// \brief Returns all the \c Replacements created during formatting.
|
||||
const tooling::Replacements &generateReplacements();
|
||||
|
@ -96,7 +98,7 @@ private:
|
|||
/// \p StartOfTokenColumn and \p InPPDirective will be used to lay out
|
||||
/// trailing comments and escaped newlines.
|
||||
Change(bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
|
||||
unsigned Spaces, unsigned StartOfTokenColumn,
|
||||
unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
|
||||
unsigned NewlinesBefore, StringRef PreviousLinePostfix,
|
||||
StringRef CurrentLinePrefix, tok::TokenKind Kind,
|
||||
bool ContinuesPPDirective);
|
||||
|
@ -116,6 +118,11 @@ private:
|
|||
tok::TokenKind Kind;
|
||||
bool ContinuesPPDirective;
|
||||
|
||||
// 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.
|
||||
unsigned Spaces;
|
||||
|
@ -157,8 +164,8 @@ private:
|
|||
void appendNewlineText(std::string &Text, unsigned Newlines,
|
||||
unsigned PreviousEndOfTokenColumn,
|
||||
unsigned EscapedNewlineColumn);
|
||||
void appendIndentText(std::string &Text, unsigned Spaces,
|
||||
unsigned WhitespaceStartColumn);
|
||||
void appendIndentText(std::string &Text, unsigned IndentLevel,
|
||||
unsigned Spaces, unsigned WhitespaceStartColumn);
|
||||
|
||||
SmallVector<Change, 16> Changes;
|
||||
SourceManager &SourceMgr;
|
||||
|
|
|
@ -5758,7 +5758,7 @@ TEST_F(FormatTest, ConfigurableFunctionDeclarationIndentAfterType) {
|
|||
TEST_F(FormatTest, ConfigurableUseOfTab) {
|
||||
FormatStyle Tab = getLLVMStyleWithColumns(42);
|
||||
Tab.IndentWidth = 8;
|
||||
Tab.UseTab = true;
|
||||
Tab.UseTab = FormatStyle::UT_Always;
|
||||
Tab.AlignEscapedNewlinesLeft = true;
|
||||
|
||||
EXPECT_EQ("if (aaaaaaaa && // q\n"
|
||||
|
@ -5858,7 +5858,83 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
|
|||
" \t */",
|
||||
Tab));
|
||||
|
||||
Tab.UseTab = false;
|
||||
Tab.UseTab = FormatStyle::UT_ForIndentation;
|
||||
EXPECT_EQ("if (aaaaaaaa && // q\n"
|
||||
" bb) // w\n"
|
||||
"\t;",
|
||||
format("if (aaaaaaaa &&// q\n"
|
||||
"bb)// w\n"
|
||||
";",
|
||||
Tab));
|
||||
verifyFormat("class X {\n"
|
||||
"\tvoid f() {\n"
|
||||
"\t\tsomeFunction(parameter1,\n"
|
||||
"\t\t parameter2);\n"
|
||||
"\t}\n"
|
||||
"};",
|
||||
Tab);
|
||||
verifyFormat("{\n"
|
||||
"\tQ({\n"
|
||||
"\t\t int a;\n"
|
||||
"\t\t someFunction(aaaaaaaaaa,\n"
|
||||
"\t\t bbbbbbbbb);\n"
|
||||
"\t },\n"
|
||||
"\t p);\n"
|
||||
"}",
|
||||
Tab);
|
||||
EXPECT_EQ("{\n"
|
||||
"\t/* aaaa\n"
|
||||
"\t bbbb */\n"
|
||||
"}",
|
||||
format("{\n"
|
||||
"/* aaaa\n"
|
||||
" bbbb */\n"
|
||||
"}",
|
||||
Tab));
|
||||
EXPECT_EQ("{\n"
|
||||
"\t/*\n"
|
||||
"\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
|
||||
"\t bbbbbbbbbbbbb\n"
|
||||
"\t*/\n"
|
||||
"}",
|
||||
format("{\n"
|
||||
"/*\n"
|
||||
" aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
|
||||
"*/\n"
|
||||
"}",
|
||||
Tab));
|
||||
EXPECT_EQ("{\n"
|
||||
"\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
|
||||
"\t// bbbbbbbbbbbbb\n"
|
||||
"}",
|
||||
format("{\n"
|
||||
"\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
|
||||
"}",
|
||||
Tab));
|
||||
EXPECT_EQ("{\n"
|
||||
"\t/*\n"
|
||||
"\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
|
||||
"\t bbbbbbbbbbbbb\n"
|
||||
"\t*/\n"
|
||||
"}",
|
||||
format("{\n"
|
||||
"\t/*\n"
|
||||
"\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
|
||||
"\t*/\n"
|
||||
"}",
|
||||
Tab));
|
||||
EXPECT_EQ("{\n"
|
||||
"\t/*\n"
|
||||
"\n"
|
||||
"\t*/\n"
|
||||
"}",
|
||||
format("{\n"
|
||||
"\t/*\n"
|
||||
"\n"
|
||||
"\t*/\n"
|
||||
"}", Tab));
|
||||
|
||||
Tab.UseTab = FormatStyle::UT_Never;
|
||||
EXPECT_EQ("/*\n"
|
||||
" a\t\tcomment\n"
|
||||
" in multiple lines\n"
|
||||
|
@ -6265,7 +6341,6 @@ TEST_F(FormatTest, ParsesConfiguration) {
|
|||
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
|
||||
CHECK_PARSE_BOOL(PointerBindsToType);
|
||||
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
|
||||
CHECK_PARSE_BOOL(UseTab);
|
||||
CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);
|
||||
CHECK_PARSE_BOOL(SpacesInParentheses);
|
||||
CHECK_PARSE_BOOL(SpaceInEmptyParentheses);
|
||||
|
@ -6292,6 +6367,13 @@ TEST_F(FormatTest, ParsesConfiguration) {
|
|||
CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
|
||||
CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
|
||||
|
||||
Style.UseTab = FormatStyle::UT_ForIndentation;
|
||||
CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
|
||||
CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
|
||||
CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
|
||||
CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
|
||||
CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
|
||||
|
||||
Style.ColumnLimit = 123;
|
||||
FormatStyle BaseStyle = getLLVMStyle();
|
||||
CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
|
||||
|
|
Loading…
Reference in New Issue