clang-format: [Java] Support formatting qualified annotations.

llvm-svn: 225559
This commit is contained in:
Nico Weber 2015-01-09 23:25:06 +00:00
parent 29e464f0df
commit beb03938e9
3 changed files with 45 additions and 23 deletions

View File

@ -93,8 +93,9 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
const FormatToken &Current = *State.NextToken;
const FormatToken &Previous = *Current.Previous;
assert(&Previous == Current.Previous);
if (!Current.CanBreakBefore && !(State.Stack.back().BreakBeforeClosingBrace &&
Current.closesBlockTypeList(Style)))
if (!Current.CanBreakBefore &&
!(State.Stack.back().BreakBeforeClosingBrace &&
Current.closesBlockTypeList(Style)))
return false;
// The opening "{" of a braced list has to be on the same line as the first
// element if it is nested in another braced init list or function call.
@ -196,7 +197,6 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
return true;
}
// Same as above, but for the first "<<" operator.
if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
State.Stack.back().BreakBeforeParameter &&
@ -209,12 +209,13 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
if (Current.NestingLevel == 0 && !Current.isTrailingComment()) {
if (Previous.ClosesTemplateDeclaration)
return true;
if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren))
if (Previous.is(TT_LeadingJavaAnnotation) && Current.isNot(tok::l_paren) &&
Current.isNot(TT_LeadingJavaAnnotation))
return true;
}
// If the return type spans multiple lines, wrap before the function name.
if (Current.isOneOf(TT_FunctionDeclarationName ,tok::kw_operator) &&
if (Current.isOneOf(TT_FunctionDeclarationName, tok::kw_operator) &&
State.Stack.back().BreakBeforeParameter)
return true;

View File

@ -305,7 +305,7 @@ private:
(Left->is(TT_ArraySubscriptLSquare) ||
(Left->is(TT_ObjCMethodExpr) && !ColonFound)))
Left->Type = TT_ArrayInitializerLSquare;
FormatToken* Tok = CurrentToken;
FormatToken *Tok = CurrentToken;
if (!consumeToken())
return false;
updateParameterCount(Left, Tok);
@ -861,6 +861,11 @@ private:
if (PreviousNoComment &&
PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
Current.Type = TT_DesignatedInitializerPeriod;
else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
Current.Previous->isOneOf(TT_JavaAnnotation,
TT_LeadingJavaAnnotation)) {
Current.Type = Current.Previous->Type;
}
} else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
Current.Previous &&
!Current.Previous->isOneOf(tok::equal, tok::at) &&
@ -868,15 +873,20 @@ private:
// Line.MightBeFunctionDecl can only be true after the parentheses of a
// function declaration have been found.
Current.Type = TT_TrailingAnnotation;
} else if (Style.Language == FormatStyle::LK_Java && Current.Previous &&
Current.Previous->is(tok::at) &&
Current.isNot(Keywords.kw_interface)) {
const FormatToken &AtToken = *Current.Previous;
const FormatToken *Previous = AtToken.getPreviousNonComment();
if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
Current.Type = TT_LeadingJavaAnnotation;
else
Current.Type = TT_JavaAnnotation;
} else if (Style.Language == FormatStyle::LK_Java && Current.Previous) {
if (Current.Previous->is(tok::at) &&
Current.isNot(Keywords.kw_interface)) {
const FormatToken &AtToken = *Current.Previous;
const FormatToken *Previous = AtToken.getPreviousNonComment();
if (!Previous || Previous->is(TT_LeadingJavaAnnotation))
Current.Type = TT_LeadingJavaAnnotation;
else
Current.Type = TT_JavaAnnotation;
} else if (Current.Previous->is(tok::period) &&
Current.Previous->isOneOf(TT_JavaAnnotation,
TT_LeadingJavaAnnotation)) {
Current.Type = Current.Previous->Type;
}
}
}
@ -1281,8 +1291,8 @@ private:
} // end anonymous namespace
void
TokenAnnotator::setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) {
void TokenAnnotator::setCommentLineLevels(
SmallVectorImpl<AnnotatedLine *> &Lines) {
const AnnotatedLine *NextNonCommentLine = nullptr;
for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
E = Lines.rend();
@ -1408,9 +1418,9 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
Current->MustBreakBefore =
Current->MustBreakBefore || mustBreakBefore(Line, *Current);
if (Style.AlwaysBreakAfterDefinitionReturnType &&
InFunctionDecl && Current->is(TT_FunctionDeclarationName) &&
!Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions.
if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl &&
Current->is(TT_FunctionDeclarationName) &&
!Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions.
// FIXME: Line.Last points to other characters than tok::semi
// and tok::lbrace.
Current->MustBreakBefore = true;
@ -1423,7 +1433,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
: LastOfChild.TotalLength + 1;
}
const FormatToken *Prev= Current->Previous;
const FormatToken *Prev = Current->Previous;
if (Current->MustBreakBefore || Prev->Children.size() > 1 ||
(Prev->Children.size() == 1 &&
Prev->Children[0]->First->MustBreakBefore) ||
@ -1612,7 +1622,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Left.is(tok::l_paren) && Right.is(tok::r_paren))
return Style.SpaceInEmptyParentheses;
if (Left.is(tok::l_paren) || Right.is(tok::r_paren))
return (Right.is(TT_CastRParen )||
return (Right.is(TT_CastRParen) ||
(Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen)))
? Style.SpacesInCStyleCastParentheses
: Style.SpacesInParentheses;
@ -1897,7 +1907,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
Left.NestingLevel == 0)
return true;
} else if (Style.Language == FormatStyle::LK_Java) {
if (Left.is(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
if (Left.is(TT_LeadingJavaAnnotation) &&
Right.isNot(TT_LeadingJavaAnnotation) && Right.isNot(tok::l_paren) &&
Line.Last->is(tok::l_brace))
return true;
if (Right.is(tok::plus) && Left.is(tok::string_literal) && Right.Next &&

View File

@ -242,6 +242,9 @@ TEST_F(FormatTestJava, Annotations) {
verifyFormat("@Override // comment\n"
"@Nullable\n"
"public String getNameIfPresent() {}");
verifyFormat("@java.lang.Override // comment\n"
"@Nullable\n"
"public String getNameIfPresent() {}");
verifyFormat("@SuppressWarnings(value = \"unchecked\")\n"
"public void doSomething() {}");
@ -255,6 +258,7 @@ TEST_F(FormatTestJava, Annotations) {
"});");
verifyFormat("void SomeFunction(@Nullable String something) {}");
verifyFormat("void SomeFunction(@org.llvm.Nullable String something) {}");
verifyFormat("@Partial @Mock DataLoader loader;");
verifyFormat("@SuppressWarnings(value = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")\n"
@ -262,10 +266,16 @@ TEST_F(FormatTestJava, Annotations) {
verifyFormat("@SomeAnnotation(\"With some really looooooooooooooong text\")\n"
"private static final long something = 0L;");
verifyFormat("@org.llvm.Qualified(\"With some really looooooooooong text\")\n"
"private static final long something = 0L;");
verifyFormat("@Mock\n"
"DataLoader loooooooooooooooooooooooader =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
getStyleWithColumns(60));
verifyFormat("@org.llvm.QualifiedMock\n"
"DataLoader loooooooooooooooooooooooader =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
getStyleWithColumns(60));
}
TEST_F(FormatTestJava, Generics) {