diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp | 128 |
1 files changed, 100 insertions, 28 deletions
diff --git a/gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp b/gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp index 4735ab3564f..fc2f891e085 100644 --- a/gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp +++ b/gnu/llvm/tools/clang/lib/Format/BreakableToken.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Contains implementation of BreakableToken class and classes derived +/// Contains implementation of BreakableToken class and classes derived /// from it. /// //===----------------------------------------------------------------------===// @@ -44,7 +44,8 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment, const FormatStyle &Style) { static const char *const KnownCStylePrefixes[] = {"///<", "//!<", "///", "//", "//!"}; - static const char *const KnownTextProtoPrefixes[] = {"//", "#"}; + static const char *const KnownTextProtoPrefixes[] = {"//", "#", "##", "###", + "####"}; ArrayRef<const char *> KnownPrefixes(KnownCStylePrefixes); if (Style.Language == FormatStyle::LK_TextProto) KnownPrefixes = KnownTextProtoPrefixes; @@ -67,8 +68,9 @@ static BreakableToken::Split getCommentSplit(StringRef Text, unsigned ColumnLimit, unsigned TabWidth, encoding::Encoding Encoding) { - DEBUG(llvm::dbgs() << "Comment split: \"" << Text << ", " << ColumnLimit - << "\", Content start: " << ContentStartColumn << "\n"); + LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text << ", " << ColumnLimit + << "\", Content start: " << ContentStartColumn + << "\n"); if (ColumnLimit <= ContentStartColumn + 1) return BreakableToken::Split(StringRef::npos, 0); @@ -89,9 +91,9 @@ static BreakableToken::Split getCommentSplit(StringRef Text, // Do not split before a number followed by a dot: this would be interpreted // as a numbered list, which would prevent re-flowing in subsequent passes. - static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\."); + static auto *const kNumberedListRegexp = new llvm::Regex("^[1-9][0-9]?\\."); if (SpaceOffset != StringRef::npos && - kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks))) + kNumberedListRegexp->match(Text.substr(SpaceOffset).ltrim(Blanks))) SpaceOffset = Text.find_last_of(Blanks, SpaceOffset); if (SpaceOffset == StringRef::npos || @@ -214,11 +216,11 @@ unsigned BreakableStringLiteral::getContentStartColumn(unsigned LineIndex, BreakableStringLiteral::BreakableStringLiteral( const FormatToken &Tok, unsigned StartColumn, StringRef Prefix, - StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding, - const FormatStyle &Style) + StringRef Postfix, unsigned UnbreakableTailLength, bool InPPDirective, + encoding::Encoding Encoding, const FormatStyle &Style) : BreakableToken(Tok, InPPDirective, Encoding, Style), StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix), - UnbreakableTailLength(Tok.UnbreakableTailLength) { + UnbreakableTailLength(UnbreakableTailLength) { assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix)); Line = Tok.TokenText.substr( Prefix.size(), Tok.TokenText.size() - Prefix.size() - Postfix.size()); @@ -233,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, @@ -284,10 +287,9 @@ static bool mayReflowContent(StringRef Content) { Content = Content.trim(Blanks); // Lines starting with '@' commonly have special meaning. // Lines starting with '-', '-#', '+' or '*' are bulleted/numbered lists. - static const SmallVector<StringRef, 8> kSpecialMeaningPrefixes = { - "@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* "}; bool hasSpecialMeaningPrefix = false; - for (StringRef Prefix : kSpecialMeaningPrefixes) { + for (StringRef Prefix : + {"@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* "}) { if (Content.startswith(Prefix)) { hasSpecialMeaningPrefix = true; break; @@ -297,9 +299,9 @@ static bool mayReflowContent(StringRef Content) { // Numbered lists may also start with a number followed by '.' // To avoid issues if a line starts with a number which is actually the end // of a previous line, we only consider numbers with up to 2 digits. - static llvm::Regex kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\. "); + static auto *const kNumberedListRegexp = new llvm::Regex("^[1-9][0-9]?\\. "); hasSpecialMeaningPrefix = - hasSpecialMeaningPrefix || kNumberedListRegexp.match(Content); + hasSpecialMeaningPrefix || kNumberedListRegexp->match(Content); // Simple heuristic for what to reflow: content should contain at least two // characters and either the first or second character must be @@ -425,7 +427,7 @@ BreakableBlockComment::BreakableBlockComment( } } - DEBUG({ + LLVM_DEBUG({ llvm::dbgs() << "IndentAtLineBreak " << IndentAtLineBreak << "\n"; llvm::dbgs() << "DelimitersOnNewline " << DelimitersOnNewline << "\n"; for (size_t i = 0; i < Lines.size(); ++i) { @@ -509,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; @@ -531,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 @@ -543,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); } @@ -582,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; } @@ -753,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. @@ -788,16 +829,47 @@ BreakableComment::Split BreakableLineCommentSection::getReflowSplit( void BreakableLineCommentSection::reflow(unsigned LineIndex, WhitespaceManager &Whitespaces) const { - // Reflow happens between tokens. Replace the whitespace between the - // tokens by the empty string. - Whitespaces.replaceWhitespace( - *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0, - /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false); + if (LineIndex > 0 && Tokens[LineIndex] != Tokens[LineIndex - 1]) { + // Reflow happens between tokens. Replace the whitespace between the + // tokens by the empty string. + Whitespaces.replaceWhitespace( + *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0, + /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false); + } else if (LineIndex > 0) { + // In case we're reflowing after the '\' in: + // + // // line comment \ + // // line 2 + // + // the reflow happens inside the single comment token (it is a single line + // comment with an unescaped newline). + // Replace the whitespace between the '\' and '//' with the empty string. + // + // Offset points to after the '\' relative to start of the token. + unsigned Offset = Lines[LineIndex - 1].data() + + Lines[LineIndex - 1].size() - + tokenAt(LineIndex - 1).TokenText.data(); + // WhitespaceLength is the number of chars between the '\' and the '//' on + // the next line. + unsigned WhitespaceLength = + Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data() - Offset; + Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], + Offset, + /*ReplaceChars=*/WhitespaceLength, + /*PreviousPostfix=*/"", + /*CurrentPrefix=*/"", + /*InPPDirective=*/false, + /*Newlines=*/0, + /*Spaces=*/0); + + } // Replace the indent and prefix of the token with the reflow prefix. + unsigned Offset = + Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data(); unsigned WhitespaceLength = - Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data(); + Content[LineIndex].data() - Lines[LineIndex].data(); Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], - /*Offset=*/0, + Offset, /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"", /*CurrentPrefix=*/ReflowPrefix, |
