diff options
Diffstat (limited to 'lib/Format')
-rw-r--r-- | lib/Format/BreakableToken.cpp | 52 | ||||
-rw-r--r-- | lib/Format/BreakableToken.h | 27 | ||||
-rw-r--r-- | lib/Format/ContinuationIndenter.cpp | 25 | ||||
-rw-r--r-- | lib/Format/ContinuationIndenter.h | 2 | ||||
-rw-r--r-- | lib/Format/Format.cpp | 9 |
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; |