mirror of
https://github.com/darlinghq/darling-libobjc2.git
synced 2024-11-23 12:19:44 +00:00
Be more lenient when accepting property encodings produced by clang. Cf. gnustep/libobjc2#5.
This commit is contained in:
parent
f4b83fbd53
commit
9c62645bf1
@ -244,6 +244,52 @@ __attribute__((objc_root_class))
|
|||||||
#define ATTR(n, v) (objc_property_attribute_t){(n), (v)}
|
#define ATTR(n, v) (objc_property_attribute_t){(n), (v)}
|
||||||
#define ATTRS(...) (objc_property_attribute_t[]){ __VA_ARGS__ }, \
|
#define ATTRS(...) (objc_property_attribute_t[]){ __VA_ARGS__ }, \
|
||||||
sizeof((objc_property_attribute_t[]){ __VA_ARGS__ }) / sizeof(objc_property_attribute_t)
|
sizeof((objc_property_attribute_t[]){ __VA_ARGS__ }) / sizeof(objc_property_attribute_t)
|
||||||
|
#define OPT_ASSERT(stmt) if (abort) { \
|
||||||
|
assert(stmt);\
|
||||||
|
} else { \
|
||||||
|
if (!(stmt)) { return NO; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL testPropertyForProperty_alt(objc_property_t p,
|
||||||
|
const char *name,
|
||||||
|
const char *types,
|
||||||
|
objc_property_attribute_t* list,
|
||||||
|
unsigned int size, BOOL abort)
|
||||||
|
{
|
||||||
|
OPT_ASSERT(0 != p);
|
||||||
|
OPT_ASSERT(strcmp(name, property_getName(p)) == 0);
|
||||||
|
const char *attrs = property_getAttributes(p);
|
||||||
|
OPT_ASSERT(0 != attrs);
|
||||||
|
OPT_ASSERT(strcmp(types, attrs) == 0);
|
||||||
|
unsigned int attrsCount = 0;
|
||||||
|
objc_property_attribute_t *attrsList = property_copyAttributeList(p, &attrsCount);
|
||||||
|
OPT_ASSERT(0 != attrsList);
|
||||||
|
OPT_ASSERT(attrsCount == size);
|
||||||
|
for (unsigned int index=0; index<size; index++) {
|
||||||
|
int found = 0;
|
||||||
|
for (unsigned int attrsIndex=0; attrsIndex<attrsCount; attrsIndex++) {
|
||||||
|
if (strcmp(attrsList[attrsIndex].name, list[index].name) == 0) {
|
||||||
|
OPT_ASSERT(strcmp(attrsList[attrsIndex].value, list[index].value) == 0);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OPT_ASSERT(found);
|
||||||
|
}
|
||||||
|
free(attrsList);
|
||||||
|
attrsList = property_copyAttributeList(p, NULL);
|
||||||
|
OPT_ASSERT(0 != attrsList);
|
||||||
|
objc_property_attribute_t *ra;
|
||||||
|
for (attrsCount = 0, ra = attrsList; ra->name != NULL; attrsCount++, ra++) {}
|
||||||
|
OPT_ASSERT(attrsCount == size);
|
||||||
|
free(attrsList);
|
||||||
|
for (unsigned int index=0; index<size; index++) {
|
||||||
|
const char* value = property_copyAttributeValue(p, list[index].name);
|
||||||
|
OPT_ASSERT(0 != value);
|
||||||
|
OPT_ASSERT(strcmp(value, list[index].value) == 0);
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void testPropertyForProperty(objc_property_t p,
|
static void testPropertyForProperty(objc_property_t p,
|
||||||
const char *name,
|
const char *name,
|
||||||
@ -251,37 +297,7 @@ static void testPropertyForProperty(objc_property_t p,
|
|||||||
objc_property_attribute_t* list,
|
objc_property_attribute_t* list,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
assert(0 != p);
|
testPropertyForProperty_alt(p, name, types, list, size, YES);
|
||||||
assert(strcmp(name, property_getName(p)) == 0);
|
|
||||||
const char *attrs = property_getAttributes(p);
|
|
||||||
assert(0 != attrs);
|
|
||||||
assert(strcmp(types, attrs) == 0);
|
|
||||||
unsigned int attrsCount = 0;
|
|
||||||
objc_property_attribute_t *attrsList = property_copyAttributeList(p, &attrsCount);
|
|
||||||
assert(0 != attrsList);
|
|
||||||
assert(attrsCount == size);
|
|
||||||
for (unsigned int index=0; index<size; index++) {
|
|
||||||
int found = 0;
|
|
||||||
for (unsigned int attrsIndex=0; attrsIndex<attrsCount; attrsIndex++) {
|
|
||||||
if (strcmp(attrsList[attrsIndex].name, list[index].name) == 0) {
|
|
||||||
assert(strcmp(attrsList[attrsIndex].value, list[index].value) == 0);
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(found);
|
|
||||||
}
|
|
||||||
free(attrsList);
|
|
||||||
attrsList = property_copyAttributeList(p, NULL);
|
|
||||||
assert(0 != attrsList);
|
|
||||||
objc_property_attribute_t *ra;
|
|
||||||
for (attrsCount = 0, ra = attrsList; ra->name != NULL; attrsCount++, ra++) {}
|
|
||||||
assert(attrsCount == size);
|
|
||||||
free(attrsList);
|
|
||||||
for (unsigned int index=0; index<size; index++) {
|
|
||||||
const char* value = property_copyAttributeValue(p, list[index].name);
|
|
||||||
assert(0 != value);
|
|
||||||
assert(strcmp(value, list[index].value) == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testPropertyForClass(Class testClass,
|
static void testPropertyForClass(Class testClass,
|
||||||
@ -299,25 +315,43 @@ static void testPropertyForClass(Class testClass,
|
|||||||
testPropertyForProperty(class_getProperty(testClass, addPropertyName), addPropertyName, types, list, size);
|
testPropertyForProperty(class_getProperty(testClass, addPropertyName), addPropertyName, types, list, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL testPropertyForProtocol_alt(Protocol *testProto,
|
||||||
|
const char *name,
|
||||||
|
const char *types,
|
||||||
|
objc_property_attribute_t* list,
|
||||||
|
unsigned int size, BOOL abort)
|
||||||
|
{
|
||||||
|
if (!testPropertyForProperty_alt(protocol_getProperty(testProto, name, YES, YES), name, types, list, size, abort))
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int addPropertyForProtocolIndex = 0;
|
||||||
|
char addPropertyName[32];
|
||||||
|
sprintf(addPropertyName, "addPropertyForProtocol%d", ++addPropertyForProtocolIndex);
|
||||||
|
protocol_addProperty(testProto, addPropertyName, list, size, YES, YES);
|
||||||
|
OPT_ASSERT(0 == protocol_getProperty(testProto, addPropertyName, YES, YES));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
static void testPropertyForProtocol(Protocol *testProto,
|
static void testPropertyForProtocol(Protocol *testProto,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *types,
|
const char *types,
|
||||||
objc_property_attribute_t* list,
|
objc_property_attribute_t* list,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
testPropertyForProperty(protocol_getProperty(testProto, name, YES, YES), name, types, list, size);
|
testPropertyForProtocol_alt(testProto, name, types, list, size, YES);
|
||||||
|
}
|
||||||
|
|
||||||
static int addPropertyForProtocolIndex = 0;
|
static BOOL testProperty_alt(const char *name, const char *types, objc_property_attribute_t* list, unsigned int size, BOOL abort)
|
||||||
char addPropertyName[32];
|
{
|
||||||
sprintf(addPropertyName, "addPropertyForProtocol%d", ++addPropertyForProtocolIndex);
|
return testPropertyForProperty_alt(class_getProperty(objc_getClass("PropertyTest"), name), name, types, list, size, abort)
|
||||||
protocol_addProperty(testProto, addPropertyName, list, size, YES, YES);
|
&& testPropertyForProperty_alt(class_getProperty(objc_getClass("PropertyProtocolTest"), name), name, types, list, size, abort);
|
||||||
assert(0 == protocol_getProperty(testProto, addPropertyName, YES, YES));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testProperty(const char *name, const char *types, objc_property_attribute_t* list, unsigned int size)
|
static void testProperty(const char *name, const char *types, objc_property_attribute_t* list, unsigned int size)
|
||||||
{
|
{
|
||||||
testPropertyForProperty(class_getProperty(objc_getClass("PropertyTest"), name), name, types, list, size);
|
testProperty_alt(name, types, list, size, YES);
|
||||||
testPropertyForProperty(class_getProperty(objc_getClass("PropertyProtocolTest"), name), name, types, list, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testAddPropertyForClass(Class testClass)
|
static void testAddPropertyForClass(Class testClass)
|
||||||
@ -517,10 +551,20 @@ int main(void)
|
|||||||
ATTR("R", ""),
|
ATTR("R", ""),
|
||||||
ATTR("N", ""),
|
ATTR("N", ""),
|
||||||
ATTR("V", "idReadonlyRetainNonatomic")));
|
ATTR("V", "idReadonlyRetainNonatomic")));
|
||||||
testProperty("idReadonlyWeakNonatomic", "T@,R,N,VidReadonlyWeakNonatomic", ATTRS(ATTR("T", "@"),
|
/**
|
||||||
|
* The weak attribute was not present for earlier versions of clang, so we test
|
||||||
|
* for all variants that the compiler may produce.
|
||||||
|
*/
|
||||||
|
if (!testProperty_alt("idReadonlyWeakNonatomic", "T@,R,W,N,VidReadonlyWeakNonatomic", ATTRS(ATTR("T", "@"),
|
||||||
|
ATTR("R", ""),
|
||||||
|
ATTR("N", ""),
|
||||||
|
ATTR("V", "idReadonlyWeakNonatomic")), NO))
|
||||||
|
{
|
||||||
|
testProperty("idReadonlyWeakNonatomic", "T@,R,N,VidReadonlyWeakNonatomic", ATTRS(ATTR("T", "@"),
|
||||||
ATTR("R", ""),
|
ATTR("R", ""),
|
||||||
ATTR("N", ""),
|
ATTR("N", ""),
|
||||||
ATTR("V", "idReadonlyWeakNonatomic")));
|
ATTR("V", "idReadonlyWeakNonatomic")));
|
||||||
|
}
|
||||||
testProperty("idOther", "T@,&,V_idOther", ATTRS(ATTR("T", "@"), ATTR("&", ""), ATTR("V", "_idOther")));
|
testProperty("idOther", "T@,&,V_idOther", ATTRS(ATTR("T", "@"), ATTR("&", ""), ATTR("V", "_idOther")));
|
||||||
testProperty("idDynamic", "T@,&,D", ATTRS(ATTR("T", "@"), ATTR("&", ""), ATTR("D", "")));
|
testProperty("idDynamic", "T@,&,D", ATTRS(ATTR("T", "@"), ATTR("&", ""), ATTR("D", "")));
|
||||||
testProperty("idDynamicGetterSetter", "T@,&,D,N,GdynamicGetterSetter,SsetDynamicGetterSetter:", ATTRS(ATTR("T", "@"),
|
testProperty("idDynamicGetterSetter", "T@,&,D,N,GdynamicGetterSetter,SsetDynamicGetterSetter:", ATTRS(ATTR("T", "@"),
|
||||||
@ -580,9 +624,18 @@ int main(void)
|
|||||||
testPropertyForProtocol(testProto, "idReadonlyRetainNonatomic", "T@,R,&,N", ATTRS(ATTR("T", "@"),
|
testPropertyForProtocol(testProto, "idReadonlyRetainNonatomic", "T@,R,&,N", ATTRS(ATTR("T", "@"),
|
||||||
ATTR("R", ""),
|
ATTR("R", ""),
|
||||||
ATTR("N", "")));
|
ATTR("N", "")));
|
||||||
testPropertyForProtocol(testProto, "idReadonlyWeakNonatomic", "T@,R,N", ATTRS(ATTR("T", "@"),
|
/*
|
||||||
|
* Again, different clang versions emit slightly different property declarations.
|
||||||
|
*/
|
||||||
|
if (!testPropertyForProtocol_alt(testProto, "idReadonlyWeakNonatomic", "T@,R,W,N", ATTRS(ATTR("T", "@"),
|
||||||
|
ATTR("R", ""),
|
||||||
|
ATTR("N", "")), NO))
|
||||||
|
{
|
||||||
|
|
||||||
|
testPropertyForProtocol(testProto, "idReadonlyWeakNonatomic", "T@,R,N", ATTRS(ATTR("T", "@"),
|
||||||
ATTR("R", ""),
|
ATTR("R", ""),
|
||||||
ATTR("N", "")));
|
ATTR("N", "")));
|
||||||
|
}
|
||||||
testPropertyForProtocol(testProto, "idOther", "T@,&", ATTRS(ATTR("T", "@"), ATTR("&", "")));
|
testPropertyForProtocol(testProto, "idOther", "T@,&", ATTRS(ATTR("T", "@"), ATTR("&", "")));
|
||||||
testPropertyForProtocol(testProto, "idDynamic", "T@,&", ATTRS(ATTR("T", "@"), ATTR("&", "")));
|
testPropertyForProtocol(testProto, "idDynamic", "T@,&", ATTRS(ATTR("T", "@"), ATTR("&", "")));
|
||||||
testPropertyForProtocol(testProto, "idDynamicGetterSetter", "T@,&,N,GdynamicGetterSetter,SsetDynamicGetterSetter:", ATTRS(ATTR("T", "@"),
|
testPropertyForProtocol(testProto, "idDynamicGetterSetter", "T@,&,N,GdynamicGetterSetter,SsetDynamicGetterSetter:", ATTRS(ATTR("T", "@"),
|
||||||
|
Loading…
Reference in New Issue
Block a user