Skip to content

[clang-format] Don't break between string literal operands of << #69871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2023

Conversation

owenca
Copy link
Contributor

@owenca owenca commented Oct 22, 2023

Fixes #44363.

@llvmbot
Copy link
Member

llvmbot commented Oct 22, 2023

@llvm/pr-subscribers-clang-format

Author: Owen Pan (owenca)

Changes

Fixes #44363.


Full diff: https://github.com/llvm/llvm-project/pull/69871.diff

2 Files Affected:

  • (modified) clang/lib/Format/TokenAnnotator.cpp (-4)
  • (modified) clang/unittests/Format/FormatTest.cpp (+4)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 7f85f48de2ed2ed..e185afaa2885123 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5118,10 +5118,6 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
     return true;
   if (Left.IsUnterminatedLiteral)
     return true;
-  if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
-      Right.Next->is(tok::string_literal)) {
-    return true;
-  }
   if (Right.is(TT_RequiresClause)) {
     switch (Style.RequiresClausePosition) {
     case FormatStyle::RCPS_OwnLine:
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0a87cfc4f1d6af9..0841ea1bcb66fa9 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26459,6 +26459,10 @@ TEST_F(FormatTest, AllowBreakBeforeNoexceptSpecifier) {
                Style);
 }
 
+TEST_F(FormatTest, StreamOutputOperator) {
+  verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
+}
+
 } // namespace
 } // namespace test
 } // namespace format

@s1Sharp
Copy link

s1Sharp commented Oct 23, 2023

this is good to be respectful. Please, lets check my mr #69859 also

@s1Sharp
Copy link

s1Sharp commented Oct 23, 2023

I think adding the possibility of breaking '<<' is a good idea if it's optional, what do u think?

@owenca
Copy link
Contributor Author

owenca commented Oct 23, 2023

I think adding the possibility of breaking '<<' is a good idea if it's optional, what do u think?

+1, but see also #69859 (comment).

@owenca owenca merged commit d68826d into llvm:main Oct 24, 2023
@owenca owenca deleted the 44363 branch October 24, 2023 09:42
@petrhosek
Copy link
Member

We have noticed that after this change, clang-format would behave differently depending on the input formatting.

(I'm using --style="{BasedOnStyle: google, ColumnLimit: 0}" in the examples below.)

For example, if the input is

return os << "ClientEnd<"
          << "test_anonymous::SomeProtocol"
          << ">(" << value.channel().get() << ")";

the output format would be the same before and after this change.

However, if the input is

return os << "ClientEnd<" << "test_anonymous::SomeProtocol" << ">(" << value.channel().get() << ")";

prior to this change we would reformat it as

return os << "ClientEnd<"
          << "test_anonymous::SomeProtocol"
          << ">(" << value.channel().get() << ")";

but after this change we would format it as

return os << "ClientEnd<" << "test_anonymous::SomeProtocol" << ">(" << value.channel().get() << ")";

that is the same as input.

Is that behavior intentional?

@owenca
Copy link
Contributor Author

owenca commented Oct 27, 2023

IMO, the new behavior is consistent with the documentation for ColumnLimt: 0.

@mydeveloperday
Copy link
Contributor

I wish we'd made this removal an option rather than just removing it, what we are seeing is reasonably formatted json or xml being streamed out is now poorly written

osjson << "{\n"
       <<"  \"name\": \"value\",\n"
       <<"  \"key\": \"abc\", \n"
       <<" }";

now becomes

osjson << "{\n" <<"  \"name\": \"value\",\n <<"  \"key\": \"abc\",\n  << "}";

While i understand its correct for column width its not as nicer.

These rules about breaking between << were part of the original author rules for now to best try and format c++ and I sort of feel we should at least honour it via an option.

I also feel that this will create a large amount of complaints about us changing defaults.

@mydeveloperday
Copy link
Contributor

see #88483

@owenca
Copy link
Contributor Author

owenca commented Apr 14, 2024

I wish we'd made this removal an option rather than just removing it, what we are seeing is reasonably formatted json or xml being streamed out is now poorly written

osjson << "{\n"
       <<"  \"name\": \"value\",\n"
       <<"  \"key\": \"abc\", \n"
       <<" }";

now becomes

osjson << "{\n" <<"  \"name\": \"value\",\n <<"  \"key\": \"abc\",\n  << "}";

What version was used? I've just tried clang-format 18.1.3, and it's totally fine:

$ cat lessless.cpp
osjson << "{\n"
       << "  \"name\": \"value\",\n"
       << "  \"key\": \"abc\", \n"
       << " }";
$ clang-format -version
clang-format version 18.1.3
$ clang-format lessless.cpp | diff lessless.cpp -
$ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A newline is added after a string token if the next 2 tokens are lessless and string
7 participants