From 2dbcbd357d1da1adf9c512d150e68424faa46d75 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 6 Nov 2020 10:33:23 +0100 Subject: [PATCH] [clang-format] do not break before { in JS comments In JavaScript some @tags can be followed by `{`, and machinery that parses these comments will fail to understand the comment if followed by a line break. clang-format already handles this case by not breaking before `{` in comments. However this was not working in cases when the column limit falls within `@tag` or between `@tag` and `{`. This adapts clang-format for this case. Reviewed By: mprobst Differential Revision: https://reviews.llvm.org/D90908 --- clang/lib/Format/BreakableToken.cpp | 16 +++++++++++++--- clang/unittests/Format/FormatTestJS.cpp | 10 ++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 15fbe3b..2ef1540 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -86,6 +86,18 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, MaxSplitBytes += BytesInChar; } + // In JavaScript, some @tags can be followed by {, and machinery that parses + // these comments will fail to understand the comment if followed by a line + // break. So avoid ever breaking before a {. + if (Style.Language == FormatStyle::LK_JavaScript) { + StringRef::size_type SpaceOffset = + Text.find_first_of(Blanks, MaxSplitBytes); + if (SpaceOffset != StringRef::npos && SpaceOffset + 1 < Text.size() && + Text[SpaceOffset + 1] == '{') { + MaxSplitBytes = SpaceOffset + 1; + } + } + StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes); static const auto kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\."); @@ -94,9 +106,7 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, // as a numbered list, which would prevent re-flowing in subsequent passes. if (kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks))) SpaceOffset = Text.find_last_of(Blanks, SpaceOffset); - // In JavaScript, some @tags can be followed by {, and machinery that parses - // these comments will fail to understand the comment if followed by a line - // break. So avoid ever breaking before a {. + // Avoid ever breaking before a { in JavaScript. else if (Style.Language == FormatStyle::LK_JavaScript && SpaceOffset + 1 < Text.size() && Text[SpaceOffset + 1] == '{') SpaceOffset = Text.find_last_of(Blanks, SpaceOffset); diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index da26a9b..d140fe5 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -2184,6 +2184,16 @@ TEST_F(FormatTestJS, JSDocAnnotations) { " * @lala {lala {lalala\n" " */\n", getGoogleJSStyleWithColumns(20)); + // cases where '{' is around the column limit + for (int ColumnLimit = 6; ColumnLimit < 13; ++ColumnLimit) { + verifyFormat("/**\n" + " * @param {type}\n" + " */", + "/**\n" + " * @param {type}\n" + " */", + getGoogleJSStyleWithColumns(ColumnLimit)); + } verifyFormat("/**\n" " * @see http://very/very/long/url/is/long\n" " */", -- 2.7.4