// 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
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);
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<ObjCMethodDecl>(R[0]))
if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) {
return false;
}
}
-
- return true;
+ if (HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod)
+ return true;
+ return false;
}
static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
@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 <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@end
+
+@implementation Test7
+@end
+
@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 <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@end
+
+@implementation Test7
+@end
+