property.m 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. TEST_BUILD_OUTPUT
  3. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  4. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  5. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  6. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  7. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  8. .*property.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
  9. END
  10. */
  11. #include "test.h"
  12. #include "testroot.i"
  13. #include <stdint.h>
  14. #include <string.h>
  15. #include <objc/objc-runtime.h>
  16. @protocol SuperProto
  17. @property(readonly) char superProtoProp;
  18. @property(class,readonly) char superProtoProp;
  19. @end
  20. @protocol SubProto <SuperProto>
  21. @property(readonly) uintptr_t subProtoProp;
  22. @property(class,readonly) uintptr_t subProtoProp;
  23. @property(readonly) uintptr_t subInstanceOnlyProtoProp;
  24. @property(class,readonly) uintptr_t subClassOnlyProtoProp;
  25. @end
  26. @interface Super : TestRoot <SuperProto> {
  27. @public
  28. char superIvar;
  29. }
  30. @property(readonly) char superProp;
  31. @property(class,readonly) char superProp;
  32. @end
  33. @implementation Super
  34. @synthesize superProp = superIvar;
  35. +(char)superProp { return 'a'; }
  36. -(char)superProtoProp { return 'a'; }
  37. +(char)superProtoProp { return 'a'; }
  38. @end
  39. @interface Sub : Super <SubProto> {
  40. @public
  41. uintptr_t subIvar;
  42. }
  43. @property(readonly) uintptr_t subProp;
  44. @property(class,readonly) uintptr_t subProp;
  45. @property(readonly) uintptr_t subInstanceOnlyProp;
  46. @property(class,readonly) uintptr_t subClassOnlyProp;
  47. @end
  48. @implementation Sub
  49. @synthesize subProp = subIvar;
  50. +(uintptr_t)subProp { return 'a'; }
  51. +(uintptr_t)subClassOnlyProp { return 'a'; }
  52. -(uintptr_t)subInstanceOnlyProp { return 'a'; }
  53. -(uintptr_t)subProtoProp { return 'a'; }
  54. +(uintptr_t)subProtoProp { return 'a'; }
  55. +(uintptr_t)subClassOnlyProtoProp { return 'a'; }
  56. -(uintptr_t)subInstanceOnlyProtoProp { return 'a'; }
  57. @end
  58. void test(Class subcls)
  59. {
  60. objc_property_t prop;
  61. Class supercls = class_getSuperclass(subcls);
  62. prop = class_getProperty(subcls, "subProp");
  63. testassert(prop);
  64. prop = class_getProperty(subcls, "subProtoProp");
  65. testassert(prop);
  66. prop = class_getProperty(supercls, "superProp");
  67. testassert(prop);
  68. testassert(prop == class_getProperty(subcls, "superProp"));
  69. prop = class_getProperty(supercls, "superProtoProp");
  70. testassert(prop);
  71. // These are distinct because Sub adopts SuperProto itself
  72. // in addition to Super's adoption of SuperProto.
  73. testassert(prop != class_getProperty(subcls, "superProtoProp"));
  74. prop = class_getProperty(supercls, "subProp");
  75. testassert(!prop);
  76. prop = class_getProperty(supercls, "subProtoProp");
  77. testassert(!prop);
  78. testassert(nil == class_getProperty(nil, "foo"));
  79. testassert(nil == class_getProperty(subcls, nil));
  80. testassert(nil == class_getProperty(nil, nil));
  81. }
  82. int main()
  83. {
  84. Class subcls = [Sub class];
  85. Class submeta = object_getClass(subcls);
  86. objc_property_t prop;
  87. // instance properties
  88. test(subcls);
  89. // class properties
  90. test(submeta);
  91. // properties must not appear on the wrong side
  92. testassert(nil == class_getProperty(subcls, "subClassOnlyProp"));
  93. testassert(nil == class_getProperty(submeta, "subInstanceOnlyProp"));
  94. testassert(nil == class_getProperty(subcls, "subClassOnlyProtoProp"));
  95. testassert(nil == class_getProperty(submeta, "subInstanceOnlyProtoProp"));
  96. // properties with the same name on both sides are distinct
  97. testassert(class_getProperty(subcls, "subProp") != class_getProperty(submeta, "subProp"));
  98. testassert(class_getProperty(subcls, "superProp") != class_getProperty(submeta, "superProp"));
  99. testassert(class_getProperty(subcls, "subProtoProp") != class_getProperty(submeta, "subProtoProp"));
  100. testassert(class_getProperty(subcls, "superProtoProp") != class_getProperty(submeta, "superProtoProp"));
  101. // protocol properties
  102. prop = protocol_getProperty(@protocol(SubProto), "subProtoProp", YES, YES);
  103. testassert(prop);
  104. prop = protocol_getProperty(@protocol(SuperProto), "superProtoProp", YES, YES);
  105. testassert(prop == protocol_getProperty(@protocol(SubProto), "superProtoProp", YES, YES));
  106. prop = protocol_getProperty(@protocol(SuperProto), "subProtoProp", YES, YES);
  107. testassert(!prop);
  108. // protocol properties must not appear on the wrong side
  109. testassert(nil == protocol_getProperty(@protocol(SubProto), "subClassOnlyProtoProp", YES, YES));
  110. testassert(nil == protocol_getProperty(@protocol(SubProto), "subInstanceOnlyProtoProp", YES, NO));
  111. // protocol properties with the same name on both sides are distinct
  112. testassert(protocol_getProperty(@protocol(SubProto), "subProtoProp", YES, YES) != protocol_getProperty(@protocol(SubProto), "subProtoProp", YES, NO));
  113. testassert(protocol_getProperty(@protocol(SubProto), "superProtoProp", YES, YES) != protocol_getProperty(@protocol(SubProto), "superProtoProp", YES, NO));
  114. testassert(nil == protocol_getProperty(nil, "foo", YES, YES));
  115. testassert(nil == protocol_getProperty(@protocol(SuperProto), nil, YES, YES));
  116. testassert(nil == protocol_getProperty(nil, nil, YES, YES));
  117. testassert(nil == protocol_getProperty(@protocol(SuperProto), "superProtoProp", NO, YES));
  118. testassert(nil == protocol_getProperty(@protocol(SuperProto), "superProtoProp", NO, NO));
  119. succeed(__FILE__);
  120. return 0;
  121. }