From 6e19a38a868acf59198715d73d4db72e92483193 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Thu, 8 Feb 2018 10:47:12 +0000 Subject: [PATCH] [clang-format] Do not break before long string literals in protos Summary: This patch is a follow-up to r323319 (which disables string literal breaking for text protos) and it disables breaking before long string literals. For example this: ``` keyyyyy: "long string literal" ``` used to get broken into: ``` keyyyyy: "long string literal" ``` While at it, I also enabled it for LK_Proto and fixed a bug in the mustBreak code. Reviewers: djasper, sammccall Reviewed By: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D42957 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324591 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/ContinuationIndenter.cpp | 2 +- lib/Format/Format.cpp | 11 ++++++----- lib/Format/TokenAnnotator.cpp | 8 +++++++- unittests/Format/FormatTestProto.cpp | 9 +++++++++ unittests/Format/FormatTestTextProto.cpp | 7 +++++++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 96281db954..6ee299566e 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -1992,7 +1992,7 @@ bool ContinuationIndenter::nextIsMultilineString(const LineState &State) { if (Current.getNextNonComment() && Current.getNextNonComment()->isStringLiteral()) return true; // Implicit concatenation. - if (Style.ColumnLimit != 0 && + if (Style.ColumnLimit != 0 && Style.BreakStringLiterals && State.Column + Current.ColumnWidth + Current.UnbreakableTailLength > Style.ColumnLimit) return true; // String will be split. diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 5fb775a0d3..ff437f119e 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -686,11 +686,6 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto); GoogleStyle.Language = FormatStyle::LK_TextProto; - // Text protos are currently mostly formatted inside C++ raw string literals - // and often the current breaking behavior of string literals is not - // beneficial there. Investigate turning this on once proper string reflow - // has been implemented. - GoogleStyle.BreakStringLiterals = false; return GoogleStyle; } @@ -762,6 +757,12 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; GoogleStyle.SpacesInContainerLiterals = false; GoogleStyle.Cpp11BracedListStyle = false; + // This affects protocol buffer options specifications and text protos. + // Text protos are currently mostly formatted inside C++ raw string literals + // and often the current breaking behavior of string literals is not + // beneficial there. Investigate turning this on once proper string reflow + // has been implemented. + GoogleStyle.BreakStringLiterals = false; } else if (Language == FormatStyle::LK_ObjC) { GoogleStyle.ColumnLimit = 100; } diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 993c937a77..d8c3366941 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -2830,11 +2830,17 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Right.is(TT_ObjCMethodExpr) && !Right.is(tok::r_square) && Left.isNot(TT_SelectorName)) return true; + if (Right.is(tok::colon) && !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon)) return false; - if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) + if (Left.is(tok::colon) && Left.isOneOf(TT_DictLiteral, TT_ObjCMethodExpr)) { + if ((Style.Language == FormatStyle::LK_Proto || + Style.Language == FormatStyle::LK_TextProto) && + Right.isStringLiteral()) + return false; return true; + } if (Right.is(TT_SelectorName) || (Right.is(tok::identifier) && Right.Next && Right.Next->is(TT_ObjCMethodExpr))) return Left.isNot(tok::period); // FIXME: Properly parse ObjC calls. diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp index 3889bc6776..d667ec2b3e 100644 --- a/unittests/Format/FormatTestProto.cpp +++ b/unittests/Format/FormatTestProto.cpp @@ -412,5 +412,14 @@ TEST_F(FormatTestProto, FormatsImports) { "}"); } +TEST_F(FormatTestProto, KeepsLongStringLiteralsOnSameLine) { + verifyFormat( + "option (MyProto.options) = {\n" + " foo: {\n" + " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaa\"\n" + " }\n" + "}"); +} + } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestTextProto.cpp b/unittests/Format/FormatTestTextProto.cpp index 1206a2b514..de9225d35a 100644 --- a/unittests/Format/FormatTestTextProto.cpp +++ b/unittests/Format/FormatTestTextProto.cpp @@ -306,5 +306,12 @@ TEST_F(FormatTestTextProto, DiscardsUnbreakableTailIfCanBreakAfter) { " }\n" "}"); } + +TEST_F(FormatTestTextProto, KeepsLongStringLiteralsOnSameLine) { + verifyFormat( + "foo: {\n" + " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaaaa\"\n" + "}"); +} } // end namespace tooling } // end namespace clang