summaryrefslogtreecommitdiff
path: root/lib/Format
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Format')
-rw-r--r--lib/Format/BreakableToken.cpp52
-rw-r--r--lib/Format/BreakableToken.h27
-rw-r--r--lib/Format/ContinuationIndenter.cpp25
-rw-r--r--lib/Format/ContinuationIndenter.h2
-rw-r--r--lib/Format/Format.cpp9
5 files changed, 100 insertions, 15 deletions
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index cc68f70100e36..fc2f891e0857e 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -235,6 +235,7 @@ BreakableToken::Split BreakableStringLiteral::getSplit(
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,33 @@ unsigned BreakableBlockComment::getContentStartColumn(unsigned LineIndex,
return std::max(0, ContentColumn[LineIndex]);
}
+const llvm::StringSet<>
+ BreakableBlockComment::ContentIndentingJavadocAnnotations = {
+ "@param", "@return", "@returns", "@throws", "@type", "@template",
+ "@see", "@deprecated", "@define", "@exports", "@mods", "@private",
+};
+
+unsigned BreakableBlockComment::getContentIndent(unsigned LineIndex) const {
+ if (Style.Language != FormatStyle::LK_Java &&
+ Style.Language != FormatStyle::LK_JavaScript)
+ return 0;
+ // The content at LineIndex 0 of a comment like:
+ // /** line 0 */
+ // is "* line 0", so we need to skip over the decoration in that case.
+ StringRef ContentWithNoDecoration = Content[LineIndex];
+ if (LineIndex == 0 && ContentWithNoDecoration.startswith("*")) {
+ ContentWithNoDecoration = ContentWithNoDecoration.substr(1).ltrim(Blanks);
+ }
+ StringRef FirstWord = ContentWithNoDecoration.substr(
+ 0, ContentWithNoDecoration.find_first_of(Blanks));
+ if (ContentIndentingJavadocAnnotations.find(FirstWord) !=
+ ContentIndentingJavadocAnnotations.end())
+ 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,10 +558,14 @@ void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
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
@@ -544,7 +574,16 @@ BreakableBlockComment::getReflowSplit(unsigned LineIndex,
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 +622,8 @@ void BreakableBlockComment::adaptStartOfLine(
// 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 +794,7 @@ unsigned BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex,
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.
diff --git a/lib/Format/BreakableToken.h b/lib/Format/BreakableToken.h
index 0fac8f08c0268..10e1801780214 100644
--- a/lib/Format/BreakableToken.h
+++ b/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,21 @@ public:
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.
+ ///
+ // (Next lines do not start with `///` since otherwise -Wdocumentation picks
+ // up the example annotations and generates warnings for them)
+ // 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 +162,7 @@ public:
/// 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 +227,7 @@ public:
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 +262,7 @@ public:
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 +372,9 @@ public:
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 +388,10 @@ public:
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 +447,7 @@ public:
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;
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 90d2a9997111e..7ca588a675b5a 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -1809,6 +1809,7 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
if (!DryRun)
Token->adaptStartOfLine(0, Whitespaces);
+ unsigned ContentIndent = 0;
unsigned Penalty = 0;
LLVM_DEBUG(llvm::dbgs() << "Breaking protruding token at column "
<< StartColumn << ".\n");
@@ -1930,11 +1931,28 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
}
}
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. Also never intent the last line.
+ 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);
+ if (NewRemainingTokenColumns == 0) {
+ // No content to indent.
+ ContentIndent = 0;
+ ContentStartColumn =
+ Token->getContentStartColumn(LineIndex, /*Break=*/true);
+ NewRemainingTokenColumns = Token->getRemainingLength(
+ LineIndex, TailOffset + Split.first + Split.second,
+ ContentStartColumn);
+ }
// When breaking before a tab character, it may be moved by a few columns,
// but will still be expanded to the next tab stop, so we don't save any
@@ -1948,7 +1966,8 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
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;
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
index 4ff05ba99f1a4..fde89db864b18 100644
--- a/lib/Format/ContinuationIndenter.h
+++ b/lib/Format/ContinuationIndenter.h
@@ -107,7 +107,7 @@ private:
void moveStateToNewBlock(LineState &State);
/// Reformats a raw string literal.
- ///
+ ///
/// \returns An extra penalty induced by reformatting the token.
unsigned reformatRawStringLiteral(const FormatToken &Current,
LineState &State,
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 59d34308c0a9c..9a2da69e89b1f 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -777,9 +777,11 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
{
"EqualsProto",
"EquivToProto",
+ "PARSE_PARTIAL_TEXT_PROTO",
"PARSE_TEST_PROTO",
"PARSE_TEXT_PROTO",
"ParseTextOrDie",
+ "ParseTextProtoOrDie",
},
/*CanonicalDelimiter=*/"",
/*BasedOnStyle=*/"google",
@@ -808,10 +810,9 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeTernaryOperators = false;
- // taze:, triple slash directives (`/// <...`), @tag followed by { for a lot
- // of JSDoc tags, and @see, which is commonly followed by overlong URLs.
- GoogleStyle.CommentPragmas =
- "(taze:|^/[ \t]*<|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
+ // taze:, triple slash directives (`/// <...`), @see, which is commonly
+ // followed by overlong URLs.
+ GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|@see)";
GoogleStyle.MaxEmptyLinesToKeep = 3;
GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
GoogleStyle.SpacesInContainerLiterals = false;