diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 4f81a084dd65b..1bd34fc7e3ba2 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5538,6 +5538,18 @@ the configuration (without a prefix: ``Auto``). Add a space after ``@property`` in Objective-C, i.e. use ``@property (readonly)`` instead of ``@property(readonly)``. +.. _ObjCSpaceBeforeMethodDeclColon: + +**ObjCSpaceBeforeMethodDeclColon** (``Boolean``) :versionbadge:`clang-format 22` :ref:`¶ ` + Add or remove a space between the '-'/'+' and the return type in + Objective-C method declarations. i.e + + .. code-block:: objc + + false: true: + + -(void)method vs. - (void)method + .. _ObjCSpaceBeforeProtocolList: **ObjCSpaceBeforeProtocolList** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f31e1c343e8aa..f85cd495a662f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -746,6 +746,8 @@ clang-format - Rename ``(Binary|Decimal|Hex)MinDigits`` to ``...MinDigitsInsert`` and add ``(Binary|Decimal|Hex)MaxDigitsSeparator`` suboptions to ``IntegerLiteralSeparator``. +- Add ``ObjCSpaceBeforeMethodDeclColon`` option to control space between the + '-'/'+' and the return type in Objective-C method declarations libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index c7e57d47f9ed1..240a00e3c27d4 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3936,6 +3936,16 @@ struct FormatStyle { /// \version 3.7 bool ObjCSpaceAfterProperty; + /// Add or remove a space between the '-'/'+' and the return type in + /// Objective-C method declarations. i.e + /// \code{.objc} + /// false: true: + /// + /// -(void)method vs. - (void)method + /// \endcode + /// \version 22 + bool ObjCSpaceBeforeMethodDeclColon; + /// Add a space in front of an Objective-C protocol list, i.e. use /// ``Foo `` instead of ``Foo``. /// \version 3.7 @@ -5772,6 +5782,7 @@ struct FormatStyle { R.ObjCBreakBeforeNestedBlockParam && ObjCPropertyAttributeOrder == R.ObjCPropertyAttributeOrder && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && + ObjCSpaceBeforeMethodDeclColon == R.ObjCSpaceBeforeMethodDeclColon && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && OneLineFormatOffRegex == R.OneLineFormatOffRegex && PackConstructorInitializers == R.PackConstructorInitializers && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f0e9aff2fd21a..04ea6b094cbcd 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1246,6 +1246,8 @@ template <> struct MappingTraits { IO.mapOptional("ObjCPropertyAttributeOrder", Style.ObjCPropertyAttributeOrder); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); + IO.mapOptional("ObjCSpaceBeforeMethodDeclColon", + Style.ObjCSpaceBeforeMethodDeclColon); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); IO.mapOptional("OneLineFormatOffRegex", Style.OneLineFormatOffRegex); @@ -1788,6 +1790,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ObjCBlockIndentWidth = 2; LLVMStyle.ObjCBreakBeforeNestedBlockParam = true; LLVMStyle.ObjCSpaceAfterProperty = false; + LLVMStyle.ObjCSpaceBeforeMethodDeclColon = true; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 79cfa73001e54..af48d804b4518 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5437,7 +5437,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return Right.hasWhitespaceBefore(); if (Line.Type == LT_ObjCMethodDecl) { if (Left.is(TT_ObjCMethodSpecifier)) - return true; + return Style.ObjCSpaceBeforeMethodDeclColon; if (Left.is(tok::r_paren) && Left.isNot(TT_AttributeRParen) && canBeObjCSelectorComponent(Right)) { // Don't space between ')' and or ')' and 'new'. 'new' is not a diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 3ff784035dd44..bd98051872fcf 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -15623,6 +15623,22 @@ TEST_F(FormatTest, FormatForObjectiveCMethodDecls) { verifyGoogleFormat("- foo:(int)foo;"); } +TEST_F(FormatTest, SpaceBeforeObjCMethodDeclColon) { + FormatStyle Style = getLLVMStyle(); + verifyFormat("- (void)method;", "-(void)method;", Style); + verifyFormat("+ (int)foo:(int)x;", "+ (int) foo:(int)x;", Style); + verifyFormat("- foo;", "-foo;", Style); + verifyFormat("- foo:(int)f;", "-foo:(int)f;", Style); + + Style.ObjCSpaceBeforeMethodDeclColon = false; + verifyFormat("-(void)method;", "- (void) method;", Style); + verifyFormat("+(int)foo:(int)x;", "+ (int)foo:(int)x;", Style); + verifyFormat("+(int)foo:(int)x;", "+ (int)foo:(int)x;", Style); + + verifyFormat("-foo;", "- foo;", Style); + verifyFormat("-foo:(int)f;", "- foo:(int)f;", Style); +} + TEST_F(FormatTest, BreaksStringLiterals) { // FIXME: unstable test case EXPECT_EQ("\"some text \"\n"