================
@@ -11077,6 +11077,281 @@ TEST_F(FormatTest, 
WrapsTemplateDeclarationsWithComments) {
       Style);
 }
 
+TEST_F(FormatTest, BreakBeforeTemplateClose) {
+  FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
+  Style.ColumnLimit = 0;
+  verifyNoChange("template <typename Foo>\n"
+                 "void foo() {}",
+                 Style);
+  verifyNoChange("template <\n"
+                 "    typename Foo,\n"
+                 "    typename Bar>\n"
+                 "void foo() {}",
+                 Style);
+  // when BreakBeforeTemplateClose is off, this line break is removed:
+  verifyFormat("template <\n"
+               "    typename Foo,\n"
+               "    typename Bar>\n"
+               "void foo() {}",
+               "template <\n"
+               "    typename Foo,\n"
+               "    typename Bar\n"
+               ">\n"
+               "void foo() {}",
+               Style);
+  Style.BreakBeforeTemplateClose = true;
+  // BreakBeforeTemplateClose should NOT force multiline templates
+  verifyNoChange("template <typename Foo>\n"
+                 "void foo() {}",
+                 Style);
+  verifyNoChange("template <typename Foo, typename Bar>\n"
+                 "void foo() {}",
+                 Style);
+  // it should allow a line break:
+  verifyNoChange("template <\n"
+                 "    typename Foo\n"
+                 ">\n"
+                 "void foo() {}",
+                 Style);
+  verifyNoChange("template <\n"
+                 "    typename Foo,\n"
+                 "    typename Bar\n"
+                 ">\n"
+                 "void foo() {}",
+                 Style);
+  // it should add a line break if not already present:
+  verifyFormat("template <\n"
+               "    typename Foo\n"
+               ">\n"
+               "void foo() {}",
+               "template <\n"
+               "    typename Foo>\n"
+               "void foo() {}",
+               Style);
+  verifyFormat("template <\n"
+               "    typename Foo,\n"
+               "    typename Bar\n"
+               ">\n"
+               "void foo() {}",
+               "template <\n"
+               "    typename Foo,\n"
+               "    typename Bar>\n"
+               "void foo() {}",
+               Style);
+  // when within an indent scope, the > should be placed appropriately:
+  verifyFormat("struct Baz {\n"
+               "  template <\n"
+               "      typename Foo,\n"
+               "      typename Bar\n"
+               "  >\n"
+               "  void foo() {}\n"
+               "};",
+               "struct Baz {\n"
+               "  template <\n"
+               "      typename Foo,\n"
+               "      typename Bar>\n"
+               "  void foo() {}\n"
+               "};",
+               Style);
+
+  // test from issue #80049
+  verifyFormat(
+      "void foo() {\n"
+      "  using type = std::remove_cv_t<\n"
+      "      add_common_cv_reference<\n"
+      "          std::common_type_t<std::decay_t<T0>, std::decay_t<T1>>,\n"
+      "          T0,\n"
+      "          T1\n"
+      "      >\n"
+      "  >;\n"
+      "}\n",
+      "void foo() {\n"
+      "  using type = std::remove_cv_t<\n"
+      "      add_common_cv_reference<\n"
+      "          std::common_type_t<std::decay_t<T0>, std::decay_t<T1>>,\n"
+      "          T0,\n"
+      "          T1>>;\n"
+      "}\n",
+      Style);
+
+  // test lambda goes to next line:
+  verifyFormat("void foo() {\n"
+               "  auto lambda = []<\n"
+               "                    typename T\n"
+               "                >(T t) {\n"
+               "  };\n"
+               "}\n",
+               "void foo() {\n"
+               "  auto lambda = []<\n"
+               "  typename T>(T t){\n"
+               "  };\n"
+               "}\n",
+               Style);
+  // with no column limit, two parameters can go on the same line:
+  verifyFormat("void foo() {\n"
+               "  auto lambda = []<\n"
+               "                    typename T, typename Foo\n"
+               "                >(T t) {\n"
+               "  };\n"
+               "}\n",
+               "void foo() {\n"
+               "  auto lambda = []<\n"
+               "  typename T, typename Foo>(T t){\n"
+               "  };\n"
+               "}\n",
+               Style);
+  // or on different lines:
+  verifyFormat("void foo() {\n"
+               "  auto lambda = []<\n"
+               "                    typename T,\n"
+               "                    typename Foo\n"
+               "                >(T t) {\n"
+               "  };\n"
+               "}\n",
+               "void foo() {\n"
+               "  auto lambda = []<\n"
+               "  typename T,\n"
+               "  typename Foo>(T t){\n"
+               "  };\n"
+               "}\n",
+               Style);
+
+  // same line with no column limit
+  verifyFormat("void foo() {\n"
+               "  auto lambda = []<typename "
+               "Looooooooooooooooooooooooooooong>("
+               "Looooooooooooooooooooooooooooong t) {};\n"
+               "}\n",
+               Style);
+
+  // test template usage goes to next line:
+  verifyFormat("void foo() {\n"
+               "  myFunc<\n"
+               "      T\n"
+               "  >();\n"
+               "}\n",
+               "void foo() {\n"
+               "  myFunc<\n"
+               "  T>();\n"
+               "}\n",
+               Style);
+
+  // now test that it handles the cases when the column limit forces wrapping
+  Style.ColumnLimit = 40;
+  // when the column limit allows it, the template should be combined back into
+  // one line:
+  verifyFormat("template <typename Foo, typename Bar>\n"
+               "void foo() {}",
+               "template <\n"
+               "    typename Foo,\n"
+               "    typename Bar\n"
+               ">\n"
+               "void foo() {}",
+               Style);
+  // but not when the name is looong
+  verifyFormat("template <\n"
+               "    typename Foo,\n"
+               "    typename Barrrrrrrrrrrrrrrrrrrrrrrrrr\n"
+               ">\n"
+               "void foo() {}",
+               Style);
+  verifyFormat("template <\n"
+               "    typename Fooooooooooooooooooooooooooo,\n"
+               "    typename Bar\n"
+               ">\n"
+               "void foo() {}",
+               Style);
+  // additionally, long names should be split in one step:
+  verifyFormat(
+      "template <\n"
+      "    typename Foo,\n"
+      "    typename Barrrrrrrrrrrrrrrrrrrrrrrrrr\n"
+      ">\n"
+      "void foo() {}",
+      "template <typename Foo, typename Barrrrrrrrrrrrrrrrrrrrrrrrrr>\n"
+      "void foo() {}",
+      Style);
+  verifyFormat(
+      "template <\n"
+      "    typename Fooooooooooooooooooooooooooo,\n"
+      "    typename Bar\n"
+      ">\n"
+      "void foo() {}",
+      "template <typename Fooooooooooooooooooooooooooo, typename Bar>\n"
+      "void foo() {}",
+      Style);
+  // even when there is only one long name:
+  verifyFormat("template <\n"
+               "    typename Fooooooooooooooooooooooooooo\n"
+               ">\n"
+               "void foo() {}",
+               "template <typename Fooooooooooooooooooooooooooo>\n"
+               "void foo() {}",
+               Style);
+  // test lambda goes to next line if the type is looong:
+  verifyFormat(
+      "void foo() {\n"
+      // in this case, breaking "typename Looong" onto the next line would
+      // actually exceed the column limit by even more. same goes for "auto
+      // lambda = []<\n" because then the continuation indent would be all the
+      // way to the "[". therefore, this is correct for the column limited 
case:
+      "  auto lambda =\n"
+      "      []<typename Loooooooooooooooooooooooooooooooooong\n"
+      "      >(T t) {};\n"
+      // for completeness, let's also make sure it's willing to break if and
+      // when doing so is helpful. if we put something long into the square
+      // brackets, now it's worth it:
+      "  auto lambda =\n"
+      "      [looooooooooooooong]<\n"
+      "          typename Loooooooooooooooooooooooooooooooooong\n"
+      "      >(T t) {};\n"
+      "  auto lambda =\n"
+      "      []<typename T,\n"
+      "         typename Loooooooooooooooooooooooooooooooooong\n"
+      "      >(T t) {};\n"
+      // nested:
+      "  auto lambda =\n"
+      "      []<template <typename, typename>\n"
+      "         typename Looooooooooooooooooong\n"
+      "      >(T t) {};\n"
+      // nested with long capture:
+      "  auto lambda =\n"
+      "      [loooooooooooooooooooong]<\n"
+      "          template <typename, typename>\n"
----------------
leijurv wrote:

No, I don't think so, because the matching `<` is on the same line. In this 
part of the test, there is a column limit, and it pulls the template back onto 
one line whenever it can, which I think is good behavior. When there is no 
column limit, it keeps the state of multiple lines versus one line, which is 
also covered by the tests.

The analogy would be: if you set `AlignAfterOpenBracket: BlockIndent`, what if 
it didn't allow you to write `f(x)`, it would always force line breaks after 
the `(` and before the `)`, meaning all your functions calls were forced to 
look like this:
```c++
    f(
        x
    )
```

See these parts of the test:

With a column limit, everything gets pulled onto one line, except if the 
template name is long:
```c++
  // now test that it handles the cases when the column limit forces wrapping
  Style.ColumnLimit = 40;
  // when the column limit allows it, the template should be combined back into
  // one line:
  verifyFormat("template <typename Foo, typename Bar>\n"
               "void foo() {}",
               "template <\n"
               "    typename Foo,\n"
               "    typename Bar\n"
               ">\n"
               "void foo() {}",
               Style);
  // but not when the name is looong
  verifyFormat("template <\n"
               "    typename Foo,\n"
               "    typename Barrrrrrrrrrrrrrrrrrrrrrrrrr\n"
               ">\n"
               "void foo() {}",
               Style);
...
  verifyFormat("void foo() { myFunc<T>(); }\n", Style);
  verifyFormat("void foo() {\n"
               "  myFunc<\n"
               "      Loooooooooooooooooooooooooooooooooooooooong\n"
               "  >();\n"
               "}\n",
               Style);
```

And for the no column limit case, these are the relevant tests to your question:

```c++
  verifyNoChange("template <typename Foo>\n"
                 "void foo() {}",
                 Style);
  verifyNoChange("template <typename Foo, typename Bar>\n"
                 "void foo() {}",
                 Style);
...
  // it should add a line break if not already present:
  verifyFormat("template <\n"
               "    typename Foo\n"
               ">\n"
               "void foo() {}",
               "template <\n"
               "    typename Foo>\n"
               "void foo() {}",
               Style);
  verifyFormat("template <\n"
               "    typename Foo,\n"
               "    typename Bar\n"
               ">\n"
               "void foo() {}",
               "template <\n"
               "    typename Foo,\n"
               "    typename Bar>\n"
               "void foo() {}",
               Style);
```

https://github.com/llvm/llvm-project/pull/118046
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to