================ @@ -11224,6 +11224,328 @@ TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { Style); } +TEST_F(FormatTest, BreakBeforeTemplateCloser) { + FormatStyle Style = getLLVMStyle(); + // Begin with tests covering the case where there is no constraint on the + // column limit. + Style.ColumnLimit = 0; + // When BreakBeforeTemplateCloser is turned off, the line break that it adds + // shall be 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.BreakBeforeTemplateCloser = true; + // BreakBeforeTemplateCloser should NOT force template declarations onto + // multiple lines. + verifyFormat("template <typename Foo>\n" + "void foo() {}", + Style); + verifyFormat("template <typename Foo, typename Bar>\n" + "void foo() {}", + Style); + // It should allow a line break, even when the typename is short. + // verifyNoChange is needed because the default behavior is one line. + verifyNoChange("template <\n" + " typename Foo\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <\n" + " typename Foo,\n" + " typename Bar\n" + ">\n" + "void foo() {}", + Style); + verifyNoChange("template <typename Foo,\n" + " typename Bar>\n" + "void foo() {}", + Style); + // It should add a line break before > 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 accordingly: + 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 https://github.com/llvm/llvm-project/issues/80049: + verifyFormat( + "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", + "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", + Style); + + // Test lambda goes to next line: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + " typename T\n" + " >(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T>(T t){\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" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T, typename Foo>(T t){\n" + " };\n" + "}", + Style); + // Or on different lines: + verifyFormat("void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo\n" + " >(T t) {\n" + " };\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T,\n" + " typename Foo>(T t){\n" + " };\n" + "}", + Style); + + // Note that this is the same line (no \n): + verifyFormat("void foo() {\n" + " auto lambda = []<typename T>(T t) {};\n" + "}", + Style); + + // Test template usage goes to next line too: + verifyFormat("void foo() {\n" + " myFunc<\n" + " T\n" + " >();\n" + "}", + "void foo() {\n" + " myFunc<\n" + " T>();\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. Note that these names are exactly 1 + // character too long for the ColumnLimit. + verifyFormat("template <\n" + " typename Foo,\n" + " typename Barrrrrrrrrrrrrrrrrrrr\n" + ">\n" + "void foo() {}", + Style); + // Note that this "Foo" is 1 character shorter than the previous "Bar" because + // of the comma. + verifyFormat("template <\n" + " typename Foooooooooooooooooooo,\n" + " typename Bar\n" + ">\n" + "void foo() {}", + Style); + // BlockIndent style is used when the ColumnLimit allows it: + verifyFormat("template <typename Foo,\n" + " typename Barrrrrrrrrrrrrrrrrr>\n" + "void foo() {}", + Style); + verifyFormat("template <typename Fooooooooooooooooooo,\n" + " typename Bar>\n" + "void foo() {}", + Style); + // Same check for only one template parameter. + // Note how the first line is exactly 40 chars: + verifyFormat("template <typename Barrrrrrrrrrrrrrrrrr>\n" + "void foo() {}", + Style); + // And when one more "r" is added, it breaks properly: + verifyFormat("template <\n" + " typename Barrrrrrrrrrrrrrrrrrr\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" + " auto lambda =\n" + " []<\n" + " typename Loooooooooooooooooooooooooooooooooong\n" + " >(T t) {};\n" + " auto lambda =\n" + " [looooooooooooooong]<\n" + " typename Loooooooooooooooooooooooooooooooooong\n" + " >(T t) {};\n" + " auto lambda =\n" + " []<\n" + " typename T,\n" + " typename Loooooooooooooooooooooooooooooooooong\n" + " >(T t) {};\n" + // Nested: + " auto lambda =\n" + " []<\n" + " template <typename, typename>\n" + " typename Looooooooooooooooooong\n" + " >(T t) {};\n" + // Same idea, the "T" is now short rather than Looong: + " auto lambda =\n" + " []<template <typename, typename>\n" + " typename T>(T t) {};\n" + // Nested with long capture forces the style to block indent: + " auto lambda =\n" + " [loooooooooooooooooooong]<\n" + " template <typename, typename>\n" + " typename Looooooooooooooooooong\n" + " >(T t) {};\n" + // But *now* it stays block indented even when T is short: + " auto lambda =\n" + " [loooooooooooooooooooong]<\n" + " template <typename, typename>\n" + " typename T\n" + " >(T t) {};\n" + // Nested, with long name and long captures: + " auto lambda =\n" + " [loooooooooooooooooooong]<\n" + " template <\n" + " typename Foooooooooooooooo,\n" + " typename\n" + " >\n" + " typename T\n" + " >(T t) {};\n" + // Allow the nested template to be on the same line: + " auto lambda =\n" + " [loooooooooooooooooooong]<\n" + " template <typename Fooooooooo,\n" + " typename>\n" + " typename T\n" + " >(T t) {};\n" + "}", + Style); + // Test that if the type is NOT long, it pulls it back into one line: + verifyFormat("void foo() {\n" + " auto lambda = []<typename T>(T t) {};\n" + "}", + "void foo() {\n" + " auto lambda = []<\n" + " typename T\n" + " >(T t) {};\n" + "}", + Style); + + // Test template usage goes to next line only if the type is looong: + verifyFormat("void foo() { myFunc<T>(); }", Style); ---------------- owenca wrote:
Delete. Current behavior. 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