krasimir updated this revision to Diff 157452.
krasimir added a comment.
- Update tests
Repository:
rC Clang
https://reviews.llvm.org/D49797
Files:
lib/Format/BreakableToken.cpp
lib/Format/BreakableToken.h
lib/Format/ContinuationIndenter.cpp
unittests/Format/FormatTestComments.cpp
unittests/Format/FormatTestJS.cpp
Index: unittests/Format/FormatTestJS.cpp
===================================================================
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -2058,8 +2058,8 @@
verifyFormat(
"/**\n"
" * @param This is a\n"
- " * long comment but\n"
- " * no type\n"
+ " * long comment\n"
+ " * but no type\n"
" */",
"/**\n"
" * @param This is a long comment but no type\n"
Index: unittests/Format/FormatTestComments.cpp
===================================================================
--- unittests/Format/FormatTestComments.cpp
+++ unittests/Format/FormatTestComments.cpp
@@ -3105,6 +3105,87 @@
// clang-format on
}
+TEST_F(FormatTestComments, IndentsLongJavadocAnnotatedLines) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_Java);
+ Style.ColumnLimit = 60;
+ FormatStyle Style20 = getGoogleStyle(FormatStyle::LK_Java);
+ Style20.ColumnLimit = 20;
+ EXPECT_EQ(
+ "/**\n"
+ " * @param x long long long long long long long long long\n"
+ " * long\n"
+ " */\n",
+ format("/**\n"
+ " * @param x long long long long long long long long long long\n"
+ " */\n",
+ Style));
+ EXPECT_EQ("/**\n"
+ " * @param x long long long long long long long long long\n"
+ " * long long long long long long long long long long\n"
+ " */\n",
+ format("/**\n"
+ " * @param x long long long long long long long long long "
+ "long long long long long long long long long long\n"
+ " */\n",
+ Style));
+ EXPECT_EQ("/**\n"
+ " * @param x long long long long long long long long long\n"
+ " * long long long long long long long long long long\n"
+ " * long\n"
+ " */\n",
+ format("/**\n"
+ " * @param x long long long long long long long long long "
+ "long long long long long long long long long long long\n"
+ " */\n",
+ Style));
+ EXPECT_EQ(
+ "/**\n"
+ " * Sentence that\n"
+ " * should be broken.\n"
+ " * @param short\n"
+ " * keep indentation\n"
+ " */\n", format(
+ "/**\n"
+ " * Sentence that should be broken.\n"
+ " * @param short\n"
+ " * keep indentation\n"
+ " */\n", Style20));
+
+ EXPECT_EQ("/**\n"
+ " * @param l1 long1\n"
+ " * to break\n"
+ " * @param l2 long2\n"
+ " * to break\n"
+ " */\n",
+ format("/**\n"
+ " * @param l1 long1 to break\n"
+ " * @param l2 long2 to break\n"
+ " */\n",
+ Style20));
+
+ EXPECT_EQ("/**\n"
+ " * @param xx to\n"
+ " * break\n"
+ " * no reflow\n"
+ " */\n",
+ format("/**\n"
+ " * @param xx to break\n"
+ " * no reflow\n"
+ " */\n",
+ Style20));
+
+ EXPECT_EQ("/**\n"
+ " * @param xx to\n"
+ " * break yes\n"
+ " * reflow\n"
+ " */\n",
+ format("/**\n"
+ " * @param xx to break\n"
+ " * yes reflow\n"
+ " */\n",
+ Style20));
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -1782,6 +1782,7 @@
if (!DryRun)
Token->adaptStartOfLine(0, Whitespaces);
+ unsigned ContentIndent = 0;
unsigned Penalty = 0;
LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column "
<< StartColumn << ".\n");
@@ -1903,8 +1904,15 @@
}
}
LLVM_DEBUG(llvm::dbgs() << " Breaking...\n");
- ContentStartColumn =
- Token->getContentStartColumn(LineIndex, /*Break=*/true);
+ // Update the ContentIndent only if the current line was not reflown with
+ // the previous line, since in that case the previous line should still
+ // determine the ContentIndent.
+ if (!Reflow) ContentIndent = Token->getContentIndent(LineIndex);
+ LLVM_DEBUG(llvm::dbgs()
+ << " ContentIndent: " << ContentIndent << "\n");
+ ContentStartColumn = ContentIndent + Token->getContentStartColumn(
+ LineIndex, /*Break=*/true);
+
unsigned NewRemainingTokenColumns = Token->getRemainingLength(
LineIndex, TailOffset + Split.first + Split.second,
ContentStartColumn);
@@ -1921,7 +1929,8 @@
LLVM_DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first
<< ", " << Split.second << "\n");
if (!DryRun)
- Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
+ Token->insertBreak(LineIndex, TailOffset, Split, ContentIndent,
+ Whitespaces);
Penalty += NewBreakPenalty;
TailOffset += Split.first + Split.second;
Index: lib/Format/BreakableToken.h
===================================================================
--- lib/Format/BreakableToken.h
+++ lib/Format/BreakableToken.h
@@ -21,6 +21,7 @@
#include "Encoding.h"
#include "TokenAnnotator.h"
#include "WhitespaceManager.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Regex.h"
#include <utility>
@@ -135,6 +136,19 @@
virtual unsigned getContentStartColumn(unsigned LineIndex,
bool Break) const = 0;
+ /// Returns additional content indent required for the second line after the
+ /// content at line \p LineIndex is broken.
+ ///
+ /// For example, Javadoc @param annotations require and indent of 4 spaces and
+ /// in this example getContentIndex(1) returns 4.
+ /// /**
+ /// * @param loooooooooooooong line
+ /// * continuation
+ /// */
+ virtual unsigned getContentIndent(unsigned LineIndex) const {
+ return 0;
+ }
+
/// Returns a range (offset, length) at which to break the line at
/// \p LineIndex, if previously broken at \p TailOffset. If possible, do not
/// violate \p ColumnLimit, assuming the text starting at \p TailOffset in
@@ -146,6 +160,7 @@
/// Emits the previously retrieved \p Split via \p Whitespaces.
virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
+ unsigned ContentIndent,
WhitespaceManager &Whitespaces) const = 0;
/// Returns the number of columns needed to format
@@ -210,7 +225,7 @@
Split SplitAfterLastLine,
WhitespaceManager &Whitespaces) const {
insertBreak(getLineCount() - 1, TailOffset, SplitAfterLastLine,
- Whitespaces);
+ /*ContentIndent=*/0, Whitespaces);
}
/// Updates the next token of \p State to the next token after this
@@ -245,6 +260,7 @@
unsigned ContentStartColumn,
llvm::Regex &CommentPragmasRegex) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
+ unsigned ContentIndent,
WhitespaceManager &Whitespaces) const override;
void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
WhitespaceManager &Whitespaces) const override {}
@@ -354,7 +370,9 @@
unsigned getRemainingLength(unsigned LineIndex, unsigned Offset,
unsigned StartColumn) const override;
unsigned getContentStartColumn(unsigned LineIndex, bool Break) const override;
+ unsigned getContentIndent(unsigned LineIndex) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
+ unsigned ContentIndent,
WhitespaceManager &Whitespaces) const override;
Split getReflowSplit(unsigned LineIndex,
llvm::Regex &CommentPragmasRegex) const override;
@@ -368,6 +386,10 @@
bool mayReflow(unsigned LineIndex,
llvm::Regex &CommentPragmasRegex) const override;
+ // Contains Javadoc annotations that require additional indent when continued
+ // on multiple lines.
+ static const llvm::StringSet<> ContentIndentingJavadocAnnotations;
+
private:
// Rearranges the whitespace between Lines[LineIndex-1] and Lines[LineIndex].
//
@@ -423,6 +445,7 @@
unsigned StartColumn) const override;
unsigned getContentStartColumn(unsigned LineIndex, bool Break) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
+ unsigned ContentIndent,
WhitespaceManager &Whitespaces) const override;
Split getReflowSplit(unsigned LineIndex,
llvm::Regex &CommentPragmasRegex) const override;
Index: lib/Format/BreakableToken.cpp
===================================================================
--- lib/Format/BreakableToken.cpp
+++ lib/Format/BreakableToken.cpp
@@ -235,6 +235,7 @@
void BreakableStringLiteral::insertBreak(unsigned LineIndex,
unsigned TailOffset, Split Split,
+ unsigned ContentIndent,
WhitespaceManager &Whitespaces) const {
Whitespaces.replaceWhitespaceInToken(
Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
@@ -510,8 +511,25 @@
return std::max(0, ContentColumn[LineIndex]);
}
+const llvm::StringSet<>
+ BreakableBlockComment::ContentIndentingJavadocAnnotations = {
+ "@param", "@return", "@throws", "@type",
+ "@template", "@see", "@deprecated", "@define",
+};
+
+unsigned BreakableBlockComment::getContentIndent(unsigned LineIndex) const {
+ if (Style.Language != FormatStyle::LK_Java &&
+ Style.Language != FormatStyle::LK_JavaScript)
+ return 0;
+ StringRef FirstWord = Content[LineIndex].substr(
+ 0, Content[LineIndex].find_first_of(Blanks));
+ if (FirstWord == "@param")
+ return Style.ContinuationIndentWidth;
+ return 0;
+}
+
void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
- Split Split,
+ Split Split, unsigned ContentIndent,
WhitespaceManager &Whitespaces) const {
StringRef Text = Content[LineIndex].substr(TailOffset);
StringRef Prefix = Decoration;
@@ -532,19 +550,32 @@
Text.data() - tokenAt(LineIndex).TokenText.data() + Split.first;
unsigned CharsToRemove = Split.second;
assert(LocalIndentAtLineBreak >= Prefix.size());
+ std::string PrefixWithTrailingIndent = Prefix;
+ for (unsigned I = 0; I < ContentIndent; ++I)
+ PrefixWithTrailingIndent += " ";
Whitespaces.replaceWhitespaceInToken(
- tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "", Prefix,
- InPPDirective, /*Newlines=*/1,
- /*Spaces=*/LocalIndentAtLineBreak - Prefix.size());
+ tokenAt(LineIndex), BreakOffsetInToken, CharsToRemove, "",
+ PrefixWithTrailingIndent, InPPDirective, /*Newlines=*/1,
+ /*Spaces=*/LocalIndentAtLineBreak + ContentIndent -
+ PrefixWithTrailingIndent.size());
}
BreakableToken::Split
BreakableBlockComment::getReflowSplit(unsigned LineIndex,
llvm::Regex &CommentPragmasRegex) const {
if (!mayReflow(LineIndex, CommentPragmasRegex))
return Split(StringRef::npos, 0);
-
+
+ // If we're reflowing into a line with content indent, only reflow the next
+ // line if its starting whitespace matches the content indent.
size_t Trimmed = Content[LineIndex].find_first_not_of(Blanks);
+ if (LineIndex) {
+ unsigned PreviousContentIndent = getContentIndent(LineIndex - 1);
+ if (PreviousContentIndent && Trimmed != StringRef::npos &&
+ Trimmed != PreviousContentIndent)
+ return Split(StringRef::npos, 0);
+ }
+
return Split(0, Trimmed != StringRef::npos ? Trimmed : 0);
}
@@ -583,7 +614,8 @@
// break length are the same.
size_t BreakLength = Lines[0].substr(1).find_first_not_of(Blanks);
if (BreakLength != StringRef::npos)
- insertBreak(LineIndex, 0, Split(1, BreakLength), Whitespaces);
+ insertBreak(LineIndex, 0, Split(1, BreakLength), /*ContentIndent=*/0,
+ Whitespaces);
}
return;
}
@@ -754,7 +786,7 @@
void BreakableLineCommentSection::insertBreak(
unsigned LineIndex, unsigned TailOffset, Split Split,
- WhitespaceManager &Whitespaces) const {
+ unsigned ContentIndent, WhitespaceManager &Whitespaces) const {
StringRef Text = Content[LineIndex].substr(TailOffset);
// Compute the offset of the split relative to the beginning of the token
// text.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits