From 9e543afe199812796fa5841f077e2dab615436cc Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 22 Jul 2013 23:50:04 +0000 Subject: [PATCH] ObjectiveC migration. Better handle migration to conforming protocols by ignoring cases where all protocol properties and methods are optional. llvm-svn: 186895 --- clang/lib/ARCMigrate/ObjCMT.cpp | 14 ++++++--- clang/test/ARCMT/objcmt-protocol-conformance.m | 35 ++++++++++++++++++++++ .../ARCMT/objcmt-protocol-conformance.m.result | 35 ++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 1bc0b8c..153ebbc 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -293,12 +293,14 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, // In auto-synthesis, protocol properties are not synthesized. So, // a conforming protocol must have its required properties declared // in class interface. + bool HasAtleastOneRequiredProperty = false; if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), E = PDecl->prop_end(); P != E; ++P) { ObjCPropertyDecl *Property = *P; if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional) continue; + HasAtleastOneRequiredProperty = true; DeclContext::lookup_const_result R = IDecl->lookup(Property->getDeclName()); if (R.size() == 0) { // Relax the rule and look into class's implementation for a synthesize @@ -317,12 +319,14 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, else return false; } + // At this point, all required properties in this protocol conform to those // declared in the class. // Check that class implements the required methods of the protocol too. + bool HasAtleastOneRequiredMethod = false; if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) { if (PDecl->meth_begin() == PDecl->meth_end()) - return false; + return HasAtleastOneRequiredProperty; for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(), MEnd = PDecl->meth_end(); M != MEnd; ++M) { ObjCMethodDecl *MD = (*M); @@ -330,10 +334,11 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, continue; if (MD->getImplementationControl() == ObjCMethodDecl::Optional) continue; - bool match = false; DeclContext::lookup_const_result R = ImpDecl->lookup(MD->getDeclName()); if (R.size() == 0) return false; + bool match = false; + HasAtleastOneRequiredMethod = true; for (unsigned I = 0, N = R.size(); I != N; ++I) if (ObjCMethodDecl *ImpMD = dyn_cast(R[0])) if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { @@ -344,8 +349,9 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, return false; } } - - return true; + if (HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod) + return true; + return false; } static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m b/clang/test/ARCMT/objcmt-protocol-conformance.m index 2b9c93f..849343d 100644 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m +++ b/clang/test/ARCMT/objcmt-protocol-conformance.m @@ -77,3 +77,38 @@ @implementation Test6 @end +@class UIDynamicAnimator, UIWindow; +@interface UIResponder : NSObject +@end + +@protocol EmptyProtocol +@end + +@protocol OptionalMethodsOnly +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol OptionalPropertiesOnly +@optional +@property (strong, nonatomic) id OptionalProperty; +@end + +@protocol OptionalEvrything +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +@property (strong, nonatomic) id OptionalProperty; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol UIApplicationDelegate +@end + +@interface Test7 : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation Test7 +@end + diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m.result b/clang/test/ARCMT/objcmt-protocol-conformance.m.result index ba32645..4f1ee77 100644 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m.result +++ b/clang/test/ARCMT/objcmt-protocol-conformance.m.result @@ -77,3 +77,38 @@ @implementation Test6 @end +@class UIDynamicAnimator, UIWindow; +@interface UIResponder : NSObject +@end + +@protocol EmptyProtocol +@end + +@protocol OptionalMethodsOnly +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol OptionalPropertiesOnly +@optional +@property (strong, nonatomic) id OptionalProperty; +@end + +@protocol OptionalEvrything +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +@property (strong, nonatomic) id OptionalProperty; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol UIApplicationDelegate +@end + +@interface Test7 : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation Test7 +@end + -- 2.7.4