diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 7a09b1b088ca..c13d3fbe2078 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -163,6 +163,10 @@ struct FormatStyle { /// line. bool AllowShortFunctionsOnASingleLine; + /// \brief Add a space after \c @property in Objective-C, i.e. use + /// @property (readonly) instead of @property(readonly). + bool ObjCSpaceAfterProperty; + /// \brief Add a space in front of an Objective-C protocol list, i.e. use /// Foo instead of \c Foo. bool ObjCSpaceBeforeProtocolList; @@ -329,6 +333,7 @@ struct FormatStyle { IndentWidth == R.IndentWidth && Language == R.Language && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && NamespaceIndentation == R.NamespaceIndentation && + ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && PenaltyBreakComment == R.PenaltyBreakComment && PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f715ce2810c9..1eca6cf79cf9 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -164,6 +164,7 @@ template <> struct MappingTraits { IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); + IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); IO.mapOptional("PenaltyBreakBeforeFirstCallParameter", @@ -267,6 +268,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.TabWidth = 8; LLVMStyle.MaxEmptyLinesToKeep = 1; LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; + LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerBindsToType = false; LLVMStyle.SpacesBeforeTrailingComments = 1; @@ -305,6 +307,7 @@ FormatStyle getGoogleStyle() { GoogleStyle.DerivePointerBinding = true; GoogleStyle.IndentCaseLabels = true; GoogleStyle.IndentFunctionDeclarationAfterType = true; + GoogleStyle.ObjCSpaceAfterProperty = false; GoogleStyle.ObjCSpaceBeforeProtocolList = false; GoogleStyle.PointerBindsToType = true; GoogleStyle.SpacesBeforeTrailingComments = 2; @@ -349,6 +352,7 @@ FormatStyle getMozillaStyle() { MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; MozillaStyle.DerivePointerBinding = true; MozillaStyle.IndentCaseLabels = true; + MozillaStyle.ObjCSpaceAfterProperty = true; MozillaStyle.ObjCSpaceBeforeProtocolList = false; MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; MozillaStyle.PointerBindsToType = true; @@ -365,6 +369,7 @@ FormatStyle getWebKitStyle() { Style.ColumnLimit = 0; Style.IndentWidth = 4; Style.NamespaceIndentation = FormatStyle::NI_Inner; + Style.ObjCSpaceAfterProperty = true; Style.PointerBindsToType = true; return Style; } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index edaf48f1f94b..17ae49e595df 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1260,6 +1260,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, (Left.TokenText == "returns" || Left.TokenText == "option")) return true; } + if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty && + Left.Tok.getObjCKeywordID() == tok::objc_property) + return true; if (Right.is(tok::hashhash)) return Left.is(tok::hash); if (Left.isOneOf(tok::hashhash, tok::hash)) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 95c04b47eff5..1a1975457549 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -5872,6 +5872,12 @@ TEST_F(FormatTest, ObjCSnippets) { verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;"); verifyFormat("@property(assign, getter=isEditable) BOOL editable;"); verifyGoogleFormat("@property(assign, getter=isEditable) BOOL editable;"); + verifyFormat("@property (assign, getter=isEditable) BOOL editable;", + getMozillaStyle()); + verifyFormat("@property BOOL editable;", getMozillaStyle()); + verifyFormat("@property (assign, getter=isEditable) BOOL editable;", + getWebKitStyle()); + verifyFormat("@property BOOL editable;", getWebKitStyle()); verifyFormat("@import foo.bar;\n" "@import baz;"); @@ -7323,6 +7329,7 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine); CHECK_PARSE_BOOL(DerivePointerBinding); CHECK_PARSE_BOOL(IndentCaseLabels); + CHECK_PARSE_BOOL(ObjCSpaceAfterProperty); CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); CHECK_PARSE_BOOL(PointerBindsToType); CHECK_PARSE_BOOL(Cpp11BracedListStyle);