diff options
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 102 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 2 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTestObjC.cpp | 10 |
3 files changed, 68 insertions, 46 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 3fac75dc6fe..e41af026dfc 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -943,49 +943,6 @@ void UnwrappedLineParser::parseStructuralElement() { return; } switch (FormatTok->Tok.getKind()) { - case tok::at: - nextToken(); - if (FormatTok->Tok.is(tok::l_brace)) { - nextToken(); - parseBracedList(); - break; - } - switch (FormatTok->Tok.getObjCKeywordID()) { - case tok::objc_public: - case tok::objc_protected: - case tok::objc_package: - case tok::objc_private: - return parseAccessSpecifier(); - case tok::objc_interface: - case tok::objc_implementation: - return parseObjCInterfaceOrImplementation(); - case tok::objc_protocol: - return parseObjCProtocol(); - case tok::objc_end: - return; // Handled by the caller. - case tok::objc_optional: - case tok::objc_required: - nextToken(); - addUnwrappedLine(); - return; - case tok::objc_autoreleasepool: - nextToken(); - if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BraceWrapping.AfterObjCDeclaration) - addUnwrappedLine(); - parseBlock(/*MustBeDeclaration=*/false); - } - addUnwrappedLine(); - return; - case tok::objc_try: - // This branch isn't strictly necessary (the kw_try case below would - // do this too after the tok::at is parsed above). But be explicit. - parseTryCatch(); - return; - default: - break; - } - break; case tok::kw_asm: nextToken(); if (FormatTok->is(tok::l_brace)) { @@ -1132,6 +1089,44 @@ void UnwrappedLineParser::parseStructuralElement() { if (FormatTok->Tok.is(tok::l_brace)) { nextToken(); parseBracedList(); + break; + } + switch (FormatTok->Tok.getObjCKeywordID()) { + case tok::objc_public: + case tok::objc_protected: + case tok::objc_package: + case tok::objc_private: + return parseAccessSpecifier(); + case tok::objc_interface: + case tok::objc_implementation: + return parseObjCInterfaceOrImplementation(); + case tok::objc_protocol: + if (parseObjCProtocol()) + return; + break; + case tok::objc_end: + return; // Handled by the caller. + case tok::objc_optional: + case tok::objc_required: + nextToken(); + addUnwrappedLine(); + return; + case tok::objc_autoreleasepool: + nextToken(); + if (FormatTok->Tok.is(tok::l_brace)) { + if (Style.BraceWrapping.AfterObjCDeclaration) + addUnwrappedLine(); + parseBlock(/*MustBeDeclaration=*/false); + } + addUnwrappedLine(); + return; + case tok::objc_try: + // This branch isn't strictly necessary (the kw_try case below would + // do this too after the tok::at is parsed above). But be explicit. + parseTryCatch(); + return; + default: + break; } break; case tok::kw_enum: @@ -2128,6 +2123,8 @@ void UnwrappedLineParser::parseObjCUntilAtEnd() { } void UnwrappedLineParser::parseObjCInterfaceOrImplementation() { + assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_interface || + FormatTok->Tok.getObjCKeywordID() == tok::objc_implementation); nextToken(); nextToken(); // interface name @@ -2155,8 +2152,21 @@ void UnwrappedLineParser::parseObjCInterfaceOrImplementation() { parseObjCUntilAtEnd(); } -void UnwrappedLineParser::parseObjCProtocol() { +// Returns true for the declaration/definition form of @protocol, +// false for the expression form. +bool UnwrappedLineParser::parseObjCProtocol() { + assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_protocol); nextToken(); + + if (FormatTok->is(tok::l_paren)) + // The expression form of @protocol, e.g. "Protocol* p = @protocol(foo);". + return false; + + // The definition/declaration form, + // @protocol Foo + // - (int)someMethod; + // @end + nextToken(); // protocol name if (FormatTok->Tok.is(tok::less)) @@ -2165,11 +2175,13 @@ void UnwrappedLineParser::parseObjCProtocol() { // Check for protocol declaration. if (FormatTok->Tok.is(tok::semi)) { nextToken(); - return addUnwrappedLine(); + addUnwrappedLine(); + return true; } addUnwrappedLine(); parseObjCUntilAtEnd(); + return true; } void UnwrappedLineParser::parseJavaScriptEs6ImportExport() { diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 1d8ccabbd0f..62238aba879 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -119,7 +119,7 @@ private: void parseObjCProtocolList(); void parseObjCUntilAtEnd(); void parseObjCInterfaceOrImplementation(); - void parseObjCProtocol(); + bool parseObjCProtocol(); void parseJavaScriptEs6ImportExport(); bool tryToParseLambda(); bool tryToParseLambdaIntroducer(); diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp index 6cb5729e252..879932db0db 100644 --- a/clang/unittests/Format/FormatTestObjC.cpp +++ b/clang/unittests/Format/FormatTestObjC.cpp @@ -215,6 +215,12 @@ TEST_F(FormatTestObjC, FormatObjCInterface) { "@end"); verifyFormat("@interface Foo : Bar\n" + "@property(assign, readwrite) NSInteger bar;\n" + "+ (id)init;\n" + "@end"); + + verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @interface Foo : Bar\n" + "@property(assign, readwrite) NSInteger bar;\n" "+ (id)init;\n" "@end"); @@ -394,6 +400,10 @@ TEST_F(FormatTestObjC, FormatObjCProtocol) { "@protocol Bar\n" "@end"); + verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @protocol Foo\n" + "@property(assign, readwrite) NSInteger bar;\n" + "@end"); + verifyFormat("@protocol myProtocol\n" "- (void)mandatoryWithInt:(int)i;\n" "@optional\n" |