[clang-Format] Fix indentation of member call after block
authorIlya Biryukov <ibiryukov@google.com>
Mon, 17 Sep 2018 07:46:20 +0000 (07:46 +0000)
committerIlya Biryukov <ibiryukov@google.com>
Mon, 17 Sep 2018 07:46:20 +0000 (07:46 +0000)
Summary:
before patch:
> echo "test() {([]() -> {int b = 32;return 3;}).as("");});" | clang-format -style=Google

```
test() {
  ([]() -> {
    int b = 32;
    return 3;
  })
      .as();
});
```

after patch:
> echo "test() {([]() -> {int b = 32;return 3;}).as("");});" | clang-format -style=Google

```
test() {
  ([]() -> {
    int b = 32;
    return 3;
  }).as();
});
```

Patch by Anders Karlsson (ank)!

Reviewers: klimek

Reviewed By: klimek

Subscribers: danilaml, acoomans, klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D45719

llvm-svn: 342363

clang/lib/Format/ContinuationIndenter.cpp
clang/lib/Format/FormatToken.h
clang/unittests/Format/FormatTest.cpp

index f035aa7..c9c9645 100644 (file)
@@ -403,7 +403,9 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
       //   }.bind(...));
       // FIXME: We should find a more generic solution to this problem.
       !(State.Column <= NewLineColumn &&
-        Style.Language == FormatStyle::LK_JavaScript))
+        Style.Language == FormatStyle::LK_JavaScript) &&
+      !(Previous.closesScopeAfterBlock() &&
+        State.Column <= NewLineColumn))
     return true;
 
   // If the template declaration spans multiple lines, force wrap before the
index d9bff01..e3b31f9 100644 (file)
@@ -325,6 +325,14 @@ struct FormatToken {
   }
   template <typename T> bool isNot(T Kind) const { return !is(Kind); }
 
+  bool closesScopeAfterBlock() const {
+    if (BlockKind == BK_Block)
+      return true;
+    if (closesScope())
+      return Previous->closesScopeAfterBlock();
+    return false;
+  }
+
   /// \c true if this token starts a sequence with the given tokens in order,
   /// following the ``Next`` pointers, ignoring comments.
   template <typename A, typename... Ts>
index 70bc9e0..db2e226 100644 (file)
@@ -4557,6 +4557,40 @@ TEST_F(FormatTest, FormatsBuilderPattern) {
   verifyFormat("aaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
                "    .aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+
+  // Dont break if only closing statements before member call
+  verifyFormat("test() {\n"
+               "  ([]() -> {\n"
+               "    int b = 32;\n"
+               "    return 3;\n"
+               "  }).foo();\n"
+               "}");
+  verifyFormat("test() {\n"
+               "  (\n"
+               "      []() -> {\n"
+               "        int b = 32;\n"
+               "        return 3;\n"
+               "      },\n"
+               "      foo, bar)\n"
+               "      .foo();\n"
+               "}");
+  verifyFormat("test() {\n"
+               "  ([]() -> {\n"
+               "    int b = 32;\n"
+               "    return 3;\n"
+               "  })\n"
+               "      .foo()\n"
+               "      .bar();\n"
+               "}");
+  verifyFormat("test() {\n"
+               "  ([]() -> {\n"
+               "    int b = 32;\n"
+               "    return 3;\n"
+               "  })\n"
+               "      .foo(\"aaaaaaaaaaaaaaaaa\"\n"
+               "           \"bbbb\");\n"
+               "}",
+               getLLVMStyleWithColumns(30));
 }
 
 TEST_F(FormatTest, BreaksAccordingToOperatorPrecedence) {