You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

115 lines
5.2 KiB

//
// FLEXRuntimeUtility.h
// Flipboard
//
// Created by Ryan Olson on 6/8/14.
// Copyright (c) 2014 Flipboard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
extern const unsigned int kFLEXNumberOfImplicitArgs;
// See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
extern NSString *const kFLEXUtilityAttributeTypeEncoding;
extern NSString *const kFLEXUtilityAttributeBackingIvar;
extern NSString *const kFLEXUtilityAttributeReadOnly;
extern NSString *const kFLEXUtilityAttributeCopy;
extern NSString *const kFLEXUtilityAttributeRetain;
extern NSString *const kFLEXUtilityAttributeNonAtomic;
extern NSString *const kFLEXUtilityAttributeCustomGetter;
extern NSString *const kFLEXUtilityAttributeCustomSetter;
extern NSString *const kFLEXUtilityAttributeDynamic;
extern NSString *const kFLEXUtilityAttributeWeak;
extern NSString *const kFLEXUtilityAttributeGarbageCollectable;
extern NSString *const kFLEXUtilityAttributeOldStyleTypeEncoding;
typedef NS_ENUM(char, FLEXTypeEncoding)
{
FLEXTypeEncodingUnknown = '?',
FLEXTypeEncodingChar = 'c',
FLEXTypeEncodingInt = 'i',
FLEXTypeEncodingShort = 's',
FLEXTypeEncodingLong = 'l',
FLEXTypeEncodingLongLong = 'q',
FLEXTypeEncodingUnsignedChar = 'C',
FLEXTypeEncodingUnsignedInt = 'I',
FLEXTypeEncodingUnsignedShort = 'S',
FLEXTypeEncodingUnsignedLong = 'L',
FLEXTypeEncodingUnsignedLongLong = 'Q',
FLEXTypeEncodingFloat = 'f',
FLEXTypeEncodingDouble = 'd',
FLEXTypeEncodingLongDouble = 'D',
FLEXTypeEncodingCBool = 'B',
FLEXTypeEncodingVoid = 'v',
FLEXTypeEncodingCString = '*',
FLEXTypeEncodingObjcObject = '@',
FLEXTypeEncodingObjcClass = '#',
FLEXTypeEncodingSelector = ':',
FLEXTypeEncodingArrayBegin = '[',
FLEXTypeEncodingArrayEnd = ']',
FLEXTypeEncodingStructBegin = '{',
FLEXTypeEncodingStructEnd = '}',
FLEXTypeEncodingUnionBegin = '(',
FLEXTypeEncodingUnionEnd = ')',
FLEXTypeEncodingQuote = '\"',
FLEXTypeEncodingBitField = 'b',
FLEXTypeEncodingPointer = '^',
FLEXTypeEncodingConst = 'r'
};
#define FLEXEncodeClass(class) ("@\"" #class "\"")
#define FLEXEncodeObject(obj) (obj ? [NSString stringWithFormat:@"@\"%@\"", [obj class]].UTF8String : @encode(id))
@interface FLEXRuntimeUtility : NSObject
// General Helpers
+ (BOOL)pointerIsValidObjcObject:(const void *)pointer;
/// Unwraps raw pointers to objects stored in NSValue, and re-boxes C strings into NSStrings.
+ (id)potentiallyUnwrapBoxedPointer:(id)returnedObjectOrNil type:(const FLEXTypeEncoding *)returnType;
/// Some fields have a name in their encoded string (e.g. \"width\"d)
/// @return the offset to skip the field name, 0 if there is no name
+ (NSUInteger)fieldNameOffsetForTypeEncoding:(const FLEXTypeEncoding *)typeEncoding;
/// @return The class hierarchy for the given object or class,
/// from the current class to the root-most class.
+ (NSArray<Class> *)classHierarchyOfObject:(id)objectOrClass;
// Property Helpers
+ (NSString *)prettyNameForProperty:(objc_property_t)property;
+ (NSString *)typeEncodingForProperty:(objc_property_t)property;
+ (BOOL)isReadonlyProperty:(objc_property_t)property;
+ (SEL)setterSelectorForProperty:(objc_property_t)property;
+ (NSString *)fullDescriptionForProperty:(objc_property_t)property;
+ (id)valueForProperty:(objc_property_t)property onObject:(id)object;
+ (NSString *)descriptionForIvarOrPropertyValue:(id)value;
+ (void)tryAddPropertyWithName:(const char *)name attributes:(NSDictionary<NSString *, NSString *> *)attributePairs toClass:(__unsafe_unretained Class)theClass;
// Ivar Helpers
+ (NSString *)prettyNameForIvar:(Ivar)ivar;
+ (id)valueForIvar:(Ivar)ivar onObject:(id)object;
+ (void)setValue:(id)value forIvar:(Ivar)ivar onObject:(id)object;
// Method Helpers
+ (NSString *)prettyNameForMethod:(Method)method isClassMethod:(BOOL)isClassMethod;
+ (NSArray *)prettyArgumentComponentsForMethod:(Method)method;
+ (FLEXTypeEncoding *)returnTypeForMethod:(Method)method;
// Method Calling/Field Editing
+ (id)performSelector:(SEL)selector
onObject:(id)object
withArguments:(NSArray *)arguments
error:(NSError * __autoreleasing *)error;
+ (NSString *)editableJSONStringForObject:(id)object;
+ (id)objectValueFromEditableJSONString:(NSString *)string;
+ (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString;
+ (void)enumerateTypesInStructEncoding:(const char *)structEncoding
usingBlock:(void (^)(NSString *structName,
const char *fieldTypeEncoding,
NSString *prettyTypeEncoding,
NSUInteger fieldIndex,
NSUInteger fieldOffset))typeBlock;
+ (NSValue *)valueForPrimitivePointer:(void *)pointer objCType:(const char *)type;
@end