308 lines · cpp
1//===- unittest/Format/FormatMacroExpansion.cpp - Formatting unit tests ---===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FormatTestBase.h"10 11#define DEBUG_TYPE "format-test-macro-expansion"12 13namespace clang {14namespace format {15namespace test {16namespace {17 18class FormatTestMacroExpansion : public FormatTestBase {};19 20TEST_F(FormatTestMacroExpansion, UnexpandConfiguredMacros) {21 FormatStyle Style = getLLVMStyle();22 Style.Macros.push_back("CLASS=class C {");23 Style.Macros.push_back("SEMI=;");24 Style.Macros.push_back("STMT=f();");25 Style.Macros.push_back("ID(x)=x");26 Style.Macros.push_back("ID3(x, y, z)=x y z");27 Style.Macros.push_back("CALL(x)=f([] { x })");28 Style.Macros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");29 Style.Macros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");30 Style.Macros.push_back("MOCK_METHOD(r, n, a, s)=r n a s");31 32 verifyFormat("ID(nested(a(b, c), d))", Style);33 verifyFormat("CLASS\n"34 " a *b;\n"35 "};",36 Style);37 verifyFormat("SEMI\n"38 "SEMI\n"39 "SEMI",40 Style);41 verifyFormat("STMT\n"42 "STMT\n"43 "STMT",44 Style);45 verifyFormat("void f() { ID(a *b); }", Style);46 verifyFormat("ID(\n"47 " {\n"48 " ID(a *b);\n"49 " });",50 Style);51 verifyIncompleteFormat("ID3({, ID(a *b),\n"52 " ;\n"53 " });",54 Style);55 56 verifyFormat("ID(CALL(CALL(return a * b;)));", Style);57 58 verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n"59 " MySomewhatLongFunction(SomethingElse()));",60 Style);61 verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n"62 " MySomewhatLongFunction(SomethingElse()), "63 "ReturnMe());",64 Style);65 66 verifyFormat(R"(67#define MACRO(a, b) ID(a + b)68)",69 Style);70 EXPECT_EQ(R"(71int a;72int b;73int c;74int d;75int e;76int f;77ID(78 namespace foo {79 int a;80 }81) // namespace k82)",83 format(R"(84int a;85int b;86int c;87int d;88int e;89int f;90ID(namespace foo { int a; }) // namespace k91)",92 Style));93 verifyFormat(R"(ID(94 //95 ({ ; }))96)",97 Style);98 99 Style.ColumnLimit = 35;100 // FIXME: Arbitrary formatting of macros where the end of the logical101 // line is in the middle of a macro call are not working yet.102 verifyFormat(R"(ID(103 void f();104 void)105ID(g) ID(()) ID(106 ;107 void g();)108)",109 Style);110 111 Style.ColumnLimit = 10;112 verifyFormat("STMT\n"113 "STMT\n"114 "STMT",115 Style);116 117 EXPECT_EQ(R"(118ID(CALL(CALL(119 a *b)));120)",121 format(R"(122ID(CALL(CALL(a * b)));123)",124 Style));125 126 // FIXME: If we want to support unbalanced braces or parens from macro127 // expansions we need to re-think how we propagate errors in128 // TokenAnnotator::parseLine; for investigation, switching the inner loop of129 // TokenAnnotator::parseLine to return LT_Other instead of LT_Invalid in case130 // of !consumeToken() changes the formatting of the test below and makes it131 // believe it has a fully correct formatting.132 EXPECT_EQ(R"(133ID3(134 {135 CLASS136 a *b;137 };138 },139 ID(x *y);140 ,141 STMT142 STMT143 STMT)144void f();145)",146 format(R"(147ID3({CLASS a*b; };}, ID(x*y);, STMT STMT STMT)148void f();149)",150 Style));151 152 verifyFormat("ID(a(\n"153 "#ifdef A\n"154 " b, c\n"155 "#else\n"156 " d(e)\n"157 "#endif\n"158 " ))",159 Style);160 Style.ColumnLimit = 80;161 verifyFormat(R"(ASSIGN_OR_RETURN(162 // Comment163 a b, c);164)",165 Style);166 Style.ColumnLimit = 30;167 verifyFormat(R"(ASSIGN_OR_RETURN(168 // Comment169 //170 a b,171 xxxxxxxxxxxx(172 yyyyyyyyyyyyyyyyy,173 zzzzzzzzzzzzzzzzzz),174 f([]() {175 a();176 b();177 }));178)",179 Style);180 verifyFormat(R"(int a = []() {181 ID(182 x;183 y;184 z;)185 ;186}();187)",188 Style);189 EXPECT_EQ(190 R"(ASSIGN_OR_RETURN((191====192#))193})",194 format(R"(ASSIGN_OR_RETURN((195====196#))197})",198 Style, SC_ExpectIncomplete));199 EXPECT_EQ(R"(ASSIGN_OR_RETURN(200}201(202====203#),204 a))",205 format(R"(ASSIGN_OR_RETURN(206}207(208====209#),210a))",211 Style, SC_ExpectIncomplete));212 EXPECT_EQ(R"(ASSIGN_OR_RETURN(a213//214====215#216 <))",217 format(R"(ASSIGN_OR_RETURN(a218//219====220#221 <))",222 Style));223 verifyFormat("class C {\n"224 " MOCK_METHOD(R, f,\n"225 " (a *b, c *d),\n"226 " (override));\n"227 "};",228 Style);229}230 231TEST_F(FormatTestMacroExpansion, KeepParensWhenExpandingObjectLikeMacros) {232 FormatStyle Style = getLLVMStyle();233 Style.Macros.push_back("FN=class C { int f");234 verifyFormat("void f() {\n"235 " FN(a *b);\n"236 " };\n"237 "}",238 Style);239}240 241TEST_F(FormatTestMacroExpansion, DoesNotExpandFunctionLikeMacrosWithoutParens) {242 FormatStyle Style = getLLVMStyle();243 Style.Macros.push_back("CLASS()=class C {");244 verifyFormat("CLASS void f();\n"245 "}\n"246 ";",247 Style);248}249 250TEST_F(FormatTestMacroExpansion,251 ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro) {252 FormatStyle Style = getLLVMStyle();253 Style.Macros.push_back("O=class {");254 verifyIncompleteFormat("O(auto x = [](){\n"255 " f();}",256 Style);257}258 259TEST_F(FormatTestMacroExpansion, CommaAsOperator) {260 FormatStyle Style = getGoogleStyleWithColumns(42);261 Style.Macros.push_back("MACRO(a, b, c)=a=(b); if(x) c");262 verifyFormat("MACRO(auto a,\n"263 " looooongfunction(first, second,\n"264 " third),\n"265 " fourth);",266 Style);267}268 269TEST_F(FormatTestMacroExpansion, ForcedBreakDiffers) {270 FormatStyle Style = getGoogleStyleWithColumns(40);271 Style.Macros.push_back("MACRO(a, b)=a=(b)");272 verifyFormat("//\n"273 "MACRO(const type variable,\n"274 " functtioncall(\n"275 " first, longsecondarg, third));",276 Style);277}278 279TEST_F(FormatTestMacroExpansion,280 PreferNotBreakingBetweenReturnTypeAndFunction) {281 FormatStyle Style = getGoogleStyleWithColumns(22);282 Style.Macros.push_back("MOCK_METHOD(r, n, a)=r n a");283 // In the expanded code, we parse a full function signature, and afterwards284 // know that we prefer not to break before the function name.285 verifyFormat("MOCK_METHOD(\n"286 " type, variable,\n"287 " (type));",288 Style);289}290 291TEST_F(FormatTestMacroExpansion, IndentChildrenWithinMacroCall) {292 FormatStyle Style = getGoogleStyleWithColumns(22);293 Style.Macros.push_back("MACRO(a, b)=a=(b)");294 verifyFormat("void f() {\n"295 " MACRO(a b, call([] {\n"296 " if (expr) {\n"297 " indent();\n"298 " }\n"299 " }));\n"300 "}",301 Style);302}303 304} // namespace305} // namespace test306} // namespace format307} // namespace clang308