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

  1. //
  2. // FLEXRuntimeUtility.h
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 6/8/14.
  6. // Copyright (c) 2014 Flipboard. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import <objc/runtime.h>
  10. extern const unsigned int kFLEXNumberOfImplicitArgs;
  11. // See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
  12. extern NSString *const kFLEXUtilityAttributeTypeEncoding;
  13. extern NSString *const kFLEXUtilityAttributeBackingIvar;
  14. extern NSString *const kFLEXUtilityAttributeReadOnly;
  15. extern NSString *const kFLEXUtilityAttributeCopy;
  16. extern NSString *const kFLEXUtilityAttributeRetain;
  17. extern NSString *const kFLEXUtilityAttributeNonAtomic;
  18. extern NSString *const kFLEXUtilityAttributeCustomGetter;
  19. extern NSString *const kFLEXUtilityAttributeCustomSetter;
  20. extern NSString *const kFLEXUtilityAttributeDynamic;
  21. extern NSString *const kFLEXUtilityAttributeWeak;
  22. extern NSString *const kFLEXUtilityAttributeGarbageCollectable;
  23. extern NSString *const kFLEXUtilityAttributeOldStyleTypeEncoding;
  24. typedef NS_ENUM(char, FLEXTypeEncoding)
  25. {
  26. FLEXTypeEncodingUnknown = '?',
  27. FLEXTypeEncodingChar = 'c',
  28. FLEXTypeEncodingInt = 'i',
  29. FLEXTypeEncodingShort = 's',
  30. FLEXTypeEncodingLong = 'l',
  31. FLEXTypeEncodingLongLong = 'q',
  32. FLEXTypeEncodingUnsignedChar = 'C',
  33. FLEXTypeEncodingUnsignedInt = 'I',
  34. FLEXTypeEncodingUnsignedShort = 'S',
  35. FLEXTypeEncodingUnsignedLong = 'L',
  36. FLEXTypeEncodingUnsignedLongLong = 'Q',
  37. FLEXTypeEncodingFloat = 'f',
  38. FLEXTypeEncodingDouble = 'd',
  39. FLEXTypeEncodingLongDouble = 'D',
  40. FLEXTypeEncodingCBool = 'B',
  41. FLEXTypeEncodingVoid = 'v',
  42. FLEXTypeEncodingCString = '*',
  43. FLEXTypeEncodingObjcObject = '@',
  44. FLEXTypeEncodingObjcClass = '#',
  45. FLEXTypeEncodingSelector = ':',
  46. FLEXTypeEncodingArrayBegin = '[',
  47. FLEXTypeEncodingArrayEnd = ']',
  48. FLEXTypeEncodingStructBegin = '{',
  49. FLEXTypeEncodingStructEnd = '}',
  50. FLEXTypeEncodingUnionBegin = '(',
  51. FLEXTypeEncodingUnionEnd = ')',
  52. FLEXTypeEncodingQuote = '\"',
  53. FLEXTypeEncodingBitField = 'b',
  54. FLEXTypeEncodingPointer = '^',
  55. FLEXTypeEncodingConst = 'r'
  56. };
  57. #define FLEXEncodeClass(class) ("@\"" #class "\"")
  58. #define FLEXEncodeObject(obj) (obj ? [NSString stringWithFormat:@"@\"%@\"", [obj class]].UTF8String : @encode(id))
  59. @interface FLEXRuntimeUtility : NSObject
  60. // General Helpers
  61. + (BOOL)pointerIsValidObjcObject:(const void *)pointer;
  62. /// Unwraps raw pointers to objects stored in NSValue, and re-boxes C strings into NSStrings.
  63. + (id)potentiallyUnwrapBoxedPointer:(id)returnedObjectOrNil type:(const FLEXTypeEncoding *)returnType;
  64. /// Some fields have a name in their encoded string (e.g. \"width\"d)
  65. /// @return the offset to skip the field name, 0 if there is no name
  66. + (NSUInteger)fieldNameOffsetForTypeEncoding:(const FLEXTypeEncoding *)typeEncoding;
  67. /// @return The class hierarchy for the given object or class,
  68. /// from the current class to the root-most class.
  69. + (NSArray<Class> *)classHierarchyOfObject:(id)objectOrClass;
  70. // Property Helpers
  71. + (NSString *)prettyNameForProperty:(objc_property_t)property;
  72. + (NSString *)typeEncodingForProperty:(objc_property_t)property;
  73. + (BOOL)isReadonlyProperty:(objc_property_t)property;
  74. + (SEL)setterSelectorForProperty:(objc_property_t)property;
  75. + (NSString *)fullDescriptionForProperty:(objc_property_t)property;
  76. + (id)valueForProperty:(objc_property_t)property onObject:(id)object;
  77. + (NSString *)descriptionForIvarOrPropertyValue:(id)value;
  78. + (void)tryAddPropertyWithName:(const char *)name attributes:(NSDictionary<NSString *, NSString *> *)attributePairs toClass:(__unsafe_unretained Class)theClass;
  79. // Ivar Helpers
  80. + (NSString *)prettyNameForIvar:(Ivar)ivar;
  81. + (id)valueForIvar:(Ivar)ivar onObject:(id)object;
  82. + (void)setValue:(id)value forIvar:(Ivar)ivar onObject:(id)object;
  83. // Method Helpers
  84. + (NSString *)prettyNameForMethod:(Method)method isClassMethod:(BOOL)isClassMethod;
  85. + (NSArray *)prettyArgumentComponentsForMethod:(Method)method;
  86. + (FLEXTypeEncoding *)returnTypeForMethod:(Method)method;
  87. // Method Calling/Field Editing
  88. + (id)performSelector:(SEL)selector
  89. onObject:(id)object
  90. withArguments:(NSArray *)arguments
  91. error:(NSError * __autoreleasing *)error;
  92. + (NSString *)editableJSONStringForObject:(id)object;
  93. + (id)objectValueFromEditableJSONString:(NSString *)string;
  94. + (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString;
  95. + (void)enumerateTypesInStructEncoding:(const char *)structEncoding
  96. usingBlock:(void (^)(NSString *structName,
  97. const char *fieldTypeEncoding,
  98. NSString *prettyTypeEncoding,
  99. NSUInteger fieldIndex,
  100. NSUInteger fieldOffset))typeBlock;
  101. + (NSValue *)valueForPrimitivePointer:(void *)pointer objCType:(const char *)type;
  102. @end