123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- //
- // FLEXProperty.h
- // FLEX
- //
- // Derived from MirrorKit.
- // Created by Tanner on 6/30/15.
- // Copyright (c) 2020 FLEX Team. All rights reserved.
- //
- #import "FLEXRuntimeConstants.h"
- @class FLEXPropertyAttributes, FLEXMethodBase;
- #pragma mark FLEXProperty
- @interface FLEXProperty : NSObject
- /// You may use this initializer instead of \c property:onClass: if you don't need
- /// to know anything about the uniqueness of this property or where it comes from.
- + (instancetype)property:(objc_property_t)property;
- /// This initializer can be used to access additional information
- /// in an efficient manner. That information being whether this property
- /// is certainly not unique and the name of the binary image which declares it.
- /// @param cls the class, or metaclass if this is a class property.
- + (instancetype)property:(objc_property_t)property onClass:(Class)cls;
- /// @param cls the class, or metaclass if this is a class property
- + (instancetype)named:(NSString *)name onClass:(Class)cls;
- /// Constructs a new property with the given name and attributes.
- + (instancetype)propertyWithName:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes;
- /// \c 0 if the instance was created via \c +propertyWithName:attributes,
- /// otherwise this is the first property in \c objc_properties
- @property (nonatomic, readonly) objc_property_t objc_property;
- @property (nonatomic, readonly) objc_property_t *objc_properties;
- @property (nonatomic, readonly) NSInteger objc_propertyCount;
- @property (nonatomic, readonly) BOOL isClassProperty;
- /// The name of the property.
- @property (nonatomic, readonly) NSString *name;
- /// The type of the property. Get the full type from the attributes.
- @property (nonatomic, readonly) FLEXTypeEncoding type;
- /// The property's attributes.
- @property (nonatomic ) FLEXPropertyAttributes *attributes;
- /// The (likely) setter, regardless of whether the property is readonly.
- /// For example, this might be the custom setter.
- @property (nonatomic, readonly) SEL likelySetter;
- @property (nonatomic, readonly) NSString *likelySetterString;
- /// Not valid unless initialized with the owning class.
- @property (nonatomic, readonly) BOOL likelySetterExists;
- /// The (likely) getter. For example, this might be the custom getter.
- @property (nonatomic, readonly) SEL likelyGetter;
- @property (nonatomic, readonly) NSString *likelyGetterString;
- /// Not valid unless initialized with the owning class.
- @property (nonatomic, readonly) BOOL likelyGetterExists;
- /// Whether there are certainly multiple definitions of this property,
- /// such as in categories in other binary images or something.
- /// @return Whether \c objc_property matches the return value of \c class_getProperty,
- /// or \c NO if this property was not created with \c property:onClass
- @property (nonatomic, readonly) BOOL multiple;
- /// @return The bundle of the image that contains this property definition,
- /// or \c nil if this property was not created with \c property:onClass or
- /// if this property was probably defined at runtime.
- @property (nonatomic, readonly) NSString *imageName;
- /// The full path of the image that contains this property definition,
- /// or \c nil if this property was not created with \c property:onClass or
- /// if this property was probably defined at runtime.
- @property (nonatomic, readonly) NSString *imagePath;
- /// For internal use
- @property (nonatomic) id tag;
- /// @return The value of this property on \c target as given by \c -valueForKey:
- /// A source-like description of the property, with all of its attributes.
- @property (nonatomic, readonly) NSString *fullDescription;
- /// If this is a class property, you must class the class object.
- - (id)getValue:(id)target;
- /// Calls into -getValue: and passes that value into
- /// -[FLEXRuntimeUtility potentiallyUnwrapBoxedPointer:type:]
- /// and returns the result.
- ///
- /// If this is a class property, you must class the class object.
- - (id)getPotentiallyUnboxedValue:(id)target;
- /// Safe to use regardless of how the \c FLEXProperty instance was initialized.
- ///
- /// This uses \c self.objc_property if it exists, otherwise it uses \c self.attributes
- - (objc_property_attribute_t *)copyAttributesList:(unsigned int *)attributesCount;
- /// Replace the attributes of the current property in the given class,
- /// using the attributes in \c self.attributes
- ///
- /// What happens when the property does not exist is undocumented.
- - (void)replacePropertyOnClass:(Class)cls;
- #pragma mark Convenience getters and setters
- /// @return A getter for the property with the given implementation.
- /// @discussion Consider using the \c FLEXPropertyGetter macros.
- - (FLEXMethodBase *)getterWithImplementation:(IMP)implementation;
- /// @return A setter for the property with the given implementation.
- /// @discussion Consider using the \c FLEXPropertySetter macros.
- - (FLEXMethodBase *)setterWithImplementation:(IMP)implementation;
- #pragma mark FLEXMethod property getter / setter macros
- // Easier than using the above methods yourself in most cases
- /// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and
- /// uses the \c FLEXProperty's \c attribute's \c backingIvarName to get the Ivar.
- #define FLEXPropertyGetter(FLEXProperty, type) [FLEXProperty \
- getterWithImplementation:imp_implementationWithBlock(^(id self) { \
- return *(type *)[self getIvarAddressByName:FLEXProperty.attributes.backingIvar]; \
- }) \
- ];
- /// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and
- /// uses the \c FLEXProperty's \c attribute's \c backingIvarName to set the Ivar.
- #define FLEXPropertySetter(FLEXProperty, type) [FLEXProperty \
- setterWithImplementation:imp_implementationWithBlock(^(id self, type value) { \
- [self setIvarByName:FLEXProperty.attributes.backingIvar value:&value size:sizeof(type)]; \
- }) \
- ];
- /// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and an Ivar name string to get the Ivar.
- #define FLEXPropertyGetterWithIvar(FLEXProperty, ivarName, type) [FLEXProperty \
- getterWithImplementation:imp_implementationWithBlock(^(id self) { \
- return *(type *)[self getIvarAddressByName:ivarName]; \
- }) \
- ];
- /// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and an Ivar name string to set the Ivar.
- #define FLEXPropertySetterWithIvar(FLEXProperty, ivarName, type) [FLEXProperty \
- setterWithImplementation:imp_implementationWithBlock(^(id self, type value) { \
- [self setIvarByName:ivarName value:&value size:sizeof(type)]; \
- }) \
- ];
- @end
|