From 50b4bd7c0e3b5bcb3f1fd64c82d01a85109fa8da Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Sun, 2 Nov 2014 19:16:41 +0000 Subject: [PATCH] clang-format: [Java] Don't break after extends/implements. Before: abstract class SomeClass extends SomeOtherClass implements SomeInterface {} After: abstract class SomeClass extends SomeOtherClass implements SomeInterface {} llvm-svn: 221103 --- clang/lib/Format/ContinuationIndenter.cpp | 7 +++++++ clang/lib/Format/TokenAnnotator.cpp | 15 ++++++++++++--- clang/lib/Format/UnwrappedLineParser.cpp | 8 ++++---- clang/unittests/Format/FormatTestJava.cpp | 19 +++++++++++++++++++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b6dd9bd..7071532 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -503,6 +503,13 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { const FormatToken *NextNonComment = Previous.getNextNonComment(); if (!NextNonComment) NextNonComment = &Current; + + // Java specific bits. + if (Style.Language == FormatStyle::LK_Java && Current.is(tok::identifier) && + (Current.TokenText == "implements" || Current.TokenText == "extends")) + return std::max(State.Stack.back().LastSpace, + State.Stack.back().Indent + Style.ContinuationIndentWidth); + if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block) return Current.NestingLevel == 0 ? State.FirstIndent : State.Stack.back().Indent; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c54b041..ebcad05 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1064,7 +1064,8 @@ static int PrecedenceArrowAndPeriod = prec::PointerToMember + 2; /// operator precedence. class ExpressionParser { public: - ExpressionParser(AnnotatedLine &Line) : Current(Line.First) {} + ExpressionParser(const FormatStyle &Style, AnnotatedLine &Line) + : Style(Style), Current(Line.First) {} /// \brief Parse expressions with the given operatore precedence. void parse(int Precedence = 0) { @@ -1167,6 +1168,11 @@ private: return Current->getPrecedence(); else if (Current->isOneOf(tok::period, tok::arrow)) return PrecedenceArrowAndPeriod; + else if (Style.Language == FormatStyle::LK_Java && + Current->is(tok::identifier) && + (Current->TokenText == "extends" || + Current->TokenText == "implements")) + return 0; } return -1; } @@ -1224,6 +1230,7 @@ private: Current = Current->Next; } + const FormatStyle &Style; FormatToken *Current; }; @@ -1256,7 +1263,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { if (Line.Type == LT_Invalid) return; - ExpressionParser ExprParser(Line); + ExpressionParser ExprParser(Style, Line); ExprParser.parse(); if (Line.First->Type == TT_ObjCMethodSpecifier) @@ -1837,7 +1844,9 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, const FormatToken &Left = *Right.Previous; if (Style.Language == FormatStyle::LK_Java) { - if (Left.is(tok::identifier) && Left.TokenText == "throws") + if (Left.is(tok::identifier) && + (Left.TokenText == "throws" || Left.TokenText == "extends" || + Left.TokenText == "implements")) return false; } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 6d2b67c..256fc28 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1375,10 +1375,10 @@ void UnwrappedLineParser::parseRecord() { } // The actual identifier can be a nested name specifier, and in macros // it is often token-pasted. - while ( - FormatTok->is(tok::identifier) || FormatTok->is(tok::coloncolon) || - FormatTok->is(tok::hashhash) || - (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::period))) + while (FormatTok->is(tok::identifier) || FormatTok->is(tok::coloncolon) || + FormatTok->is(tok::hashhash) || + (Style.Language == FormatStyle::LK_Java && + FormatTok->isOneOf(tok::period, tok::comma))) nextToken(); // Note that parsing away template declarations here leads to incorrectly diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp index 4f9a3dc..73a1848 100644 --- a/clang/unittests/Format/FormatTestJava.cpp +++ b/clang/unittests/Format/FormatTestJava.cpp @@ -37,6 +37,12 @@ protected: return format(Code, 0, Code.size(), Style); } + static FormatStyle getStyleWithColumns(unsigned ColumnLimit) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Java); + Style.ColumnLimit = ColumnLimit; + return Style; + } + static void verifyFormat( llvm::StringRef Code, const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_Java)) { @@ -58,6 +64,19 @@ TEST_F(FormatTestJava, ClassDeclarations) { " }\n" "}"); verifyFormat("public class A extends B.C {}"); + + verifyFormat("abstract class SomeClass extends SomeOtherClass\n" + " implements SomeInterface {}", + getStyleWithColumns(60)); + verifyFormat("abstract class SomeClass\n" + " extends SomeOtherClass\n" + " implements SomeInterface {}", + getStyleWithColumns(40)); + verifyFormat("abstract class SomeClass\n" + " extends SomeOtherClass\n" + " implements SomeInterface,\n" + " AnotherInterface {}", + getStyleWithColumns(40)); } TEST_F(FormatTestJava, ThrowsDeclarations) { -- 2.7.4