From: Daniel Jasper Date: Tue, 28 Oct 2014 16:53:38 +0000 (+0000) Subject: clang-format: [ObjC] Add separate flag to control indentation in blocks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=347e3d7dd0125ab7701df488e900639b7699dd16;p=clang clang-format: [ObjC] Add separate flag to control indentation in blocks Apparently, people are very much divided on what the "correct" indentation is. So, best to give them a choice. The new flag is called ObjCBlockIndentWidth and the default is now set to the same value as IndentWidth for the pre-defined styles. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220784 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index a979886add..286a669ac9 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -244,6 +244,9 @@ struct FormatStyle { /// initializer lists. unsigned ConstructorInitializerIndentWidth; + /// \brief The number of characters to use for indentation of ObjC blocks. + unsigned ObjCBlockIndentWidth; + /// \brief If \c true, always break after function definition return types. /// /// More truthfully called 'break before the identifier following the type @@ -390,8 +393,6 @@ struct FormatStyle { bool operator==(const FormatStyle &R) const { return AccessModifierOffset == R.AccessModifierOffset && - ConstructorInitializerIndentWidth == - R.ConstructorInitializerIndentWidth && AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft && AlignTrailingComments == R.AlignTrailingComments && AllowAllParametersOfDeclarationOnNextLine == @@ -418,6 +419,8 @@ struct FormatStyle { ColumnLimit == R.ColumnLimit && ConstructorInitializerAllOnOneLineOrOnePerLine == R.ConstructorInitializerAllOnOneLineOrOnePerLine && + ConstructorInitializerIndentWidth == + R.ConstructorInitializerIndentWidth && DerivePointerAlignment == R.DerivePointerAlignment && ExperimentalAutoDetectBinPacking == R.ExperimentalAutoDetectBinPacking && @@ -428,6 +431,7 @@ struct FormatStyle { KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && NamespaceIndentation == R.NamespaceIndentation && + ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && PenaltyBreakComment == R.PenaltyBreakComment && diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index a6fb40ece7..41dc09b11d 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -917,10 +917,10 @@ void ContinuationIndenter::moveStateToNewBlock(LineState &State) { if (fakeRParenSpecialCase(State)) consumeRParens(State, *State.NextToken->MatchingParen); - // For some reason, ObjC blocks are indented like continuations. + // ObjC block sometimes follow special indentation rules. unsigned NewIndent = State.Stack.back().LastSpace + (State.NextToken->Type == TT_ObjCBlockLBrace - ? Style.ContinuationIndentWidth + ? Style.ObjCBlockIndentWidth : Style.IndentWidth); State.Stack.push_back(ParenState( NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1, diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index e0cce7d982..e2aff03e88 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -170,8 +170,6 @@ template <> struct MappingTraits { } IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); - IO.mapOptional("ConstructorInitializerIndentWidth", - Style.ConstructorInitializerIndentWidth); IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", @@ -203,6 +201,8 @@ template <> struct MappingTraits { IO.mapOptional("ColumnLimit", Style.ColumnLimit); IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", Style.ConstructorInitializerAllOnOneLineOrOnePerLine); + IO.mapOptional("ConstructorInitializerIndentWidth", + Style.ConstructorInitializerIndentWidth); IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); IO.mapOptional("ExperimentalAutoDetectBinPacking", Style.ExperimentalAutoDetectBinPacking); @@ -215,6 +215,7 @@ template <> struct MappingTraits { IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); + IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); @@ -357,6 +358,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.MaxEmptyLinesToKeep = 1; LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; + LLVMStyle.ObjCBlockIndentWidth = 2; LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; @@ -463,6 +465,7 @@ FormatStyle getWebKitStyle() { Style.ColumnLimit = 0; Style.IndentWidth = 4; Style.NamespaceIndentation = FormatStyle::NI_Inner; + Style.ObjCBlockIndentWidth = 4; Style.ObjCSpaceAfterProperty = true; Style.PointerAlignment = FormatStyle::PAS_Left; Style.Standard = FormatStyle::LS_Cpp03; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 56163f7007..40231adabc 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -8119,13 +8119,13 @@ TEST_F(FormatTest, AllmanBraceBreaking) { // This shouldn't affect ObjC blocks.. verifyFormat("[self doSomeThingWithACompletionHandler:^{\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" "}];", AllmanBraceStyle); verifyFormat("void (^block)(void) = ^{\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" "};", AllmanBraceStyle); // .. or dict literals. @@ -8459,6 +8459,7 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("AccessModifierOffset: -1234", AccessModifierOffset, -1234); CHECK_PARSE("ConstructorInitializerIndentWidth: 1234", ConstructorInitializerIndentWidth, 1234u); + CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u); CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u); CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u); CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234", @@ -9177,82 +9178,89 @@ TEST_F(FormatTest, FormatsBlocks) { verifyFormat("{ void (^block)(Object *x); }", ShortBlocks); verifyFormat("[operation setCompletionBlock:^{\n" - " [self onOperationDone];\n" + " [self onOperationDone];\n" "}];"); verifyFormat("int i = {[operation setCompletionBlock:^{\n" - " [self onOperationDone];\n" + " [self onOperationDone];\n" "}]};"); verifyFormat("[operation setCompletionBlock:^(int *i) {\n" - " f();\n" + " f();\n" "}];"); verifyFormat("int a = [operation block:^int(int *i) {\n" - " return 1;\n" + " return 1;\n" "}];"); verifyFormat("[myObject doSomethingWith:arg1\n" " aaa:^int(int *a) {\n" - " return 1;\n" + " return 1;\n" " }\n" " bbb:f(a * bbbbbbbb)];"); verifyFormat("[operation setCompletionBlock:^{\n" - " [self.delegate newDataAvailable];\n" + " [self.delegate newDataAvailable];\n" "}];", getLLVMStyleWithColumns(60)); verifyFormat("dispatch_async(_fileIOQueue, ^{\n" - " NSString *path = [self sessionFilePath];\n" - " if (path) {\n" - " // ...\n" - " }\n" + " NSString *path = [self sessionFilePath];\n" + " if (path) {\n" + " // ...\n" + " }\n" "});"); verifyFormat("[[SessionService sharedService]\n" " loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" - " if (window) {\n" - " [self windowDidLoad:window];\n" - " } else {\n" - " [self errorLoadingWindow];\n" - " }\n" + " if (window) {\n" + " [self windowDidLoad:window];\n" + " } else {\n" + " [self errorLoadingWindow];\n" + " }\n" " }];"); verifyFormat("void (^largeBlock)(void) = ^{\n" - " // ...\n" + " // ...\n" "};\n", getLLVMStyleWithColumns(40)); verifyFormat("[[SessionService sharedService]\n" " loadWindowWithCompletionBlock: //\n" " ^(SessionWindow *window) {\n" - " if (window) {\n" - " [self windowDidLoad:window];\n" - " } else {\n" - " [self errorLoadingWindow];\n" - " }\n" + " if (window) {\n" + " [self windowDidLoad:window];\n" + " } else {\n" + " [self errorLoadingWindow];\n" + " }\n" " }];", getLLVMStyleWithColumns(60)); verifyFormat("[myObject doSomethingWith:arg1\n" " firstBlock:^(Foo *a) {\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" " }\n" " secondBlock:^(Bar *b) {\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" " }\n" " thirdBlock:^Foo(Bar *b) {\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" " }];"); verifyFormat("[myObject doSomethingWith:arg1\n" " firstBlock:-1\n" " secondBlock:^(Bar *b) {\n" - " // ...\n" - " int i;\n" + " // ...\n" + " int i;\n" " }];"); verifyFormat("f(^{\n" - " @autoreleasepool {\n" - " if (a) {\n" - " g();\n" - " }\n" + " @autoreleasepool {\n" + " if (a) {\n" + " g();\n" " }\n" + " }\n" "});"); + + FormatStyle FourIndent = getLLVMStyle(); + FourIndent.ObjCBlockIndentWidth = 4; + verifyFormat("[operation setCompletionBlock:^{\n" + " [self onOperationDone];\n" + "}];", + FourIndent); } TEST_F(FormatTest, SupportsCRLF) {