FLEXMethod.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //
  2. // FLEXMethod.h
  3. // FLEX
  4. //
  5. // Derived from MirrorKit.
  6. // Created by Tanner on 6/30/15.
  7. // Copyright (c) 2015 Tanner Bennett. All rights reserved.
  8. //
  9. #import <Foundation/Foundation.h>
  10. #import "FLEXMethodBase.h"
  11. #import "FLEXRuntimeUtility.h"
  12. #import <objc/runtime.h>
  13. NS_ASSUME_NONNULL_BEGIN
  14. /// A class representing a concrete method which already exists in a class.
  15. /// This class contains helper methods for swizzling or invoking the method.
  16. ///
  17. /// Any of the initializers will return nil if the type encoding
  18. /// of the method is unsupported by `NSMethodSignature`. In general,
  19. /// any method whose return type or parameters involve a struct with
  20. /// bitfields or arrays is unsupported.
  21. ///
  22. /// I do not remember why I didn't include \c signature in the base class
  23. /// when I originally wrote this, but I probably had a good reason. We can
  24. /// always go back and move it to \c FLEXMethodBase if we find we need to.
  25. @interface FLEXMethod : FLEXMethodBase
  26. /// Defaults to instance method
  27. + (nullable instancetype)method:(Method)method;
  28. + (nullable instancetype)method:(Method)method isInstanceMethod:(BOOL)isInstanceMethod;
  29. /// Constructs an \c FLEXMethod for the given method on the given class.
  30. /// @param cls the class, or metaclass if this is a class method
  31. /// @return The newly constructed \c FLEXMethod object, or \c nil if the
  32. /// specified class or its superclasses do not contain a method with the specified selector.
  33. + (nullable instancetype)selector:(SEL)selector class:(Class)cls;
  34. /// Constructs an \c FLEXMethod for the given method on the given class,
  35. /// only if the given class itself defines or overrides the desired method.
  36. /// @param cls the class, or metaclass if this is a class method
  37. /// @return The newly constructed \c FLEXMethod object, or \c nil \e if the
  38. /// specified class does not define or override, or if the specified class
  39. /// or its superclasses do not contain, a method with the specified selector.
  40. + (nullable instancetype)selector:(SEL)selector implementedInClass:(Class)cls;
  41. @property (nonatomic, readonly) Method objc_method;
  42. /// The implementation of the method.
  43. /// @discussion Setting \c implementation will change the implementation of this method
  44. /// for the entire class which implements said method. It will also not modify the selector of said method.
  45. @property (nonatomic ) IMP implementation;
  46. /// Whether the method is an instance method or not.
  47. @property (nonatomic, readonly) BOOL isInstanceMethod;
  48. /// The number of arguments to the method.
  49. @property (nonatomic, readonly) NSUInteger numberOfArguments;
  50. /// The \c NSMethodSignature object corresponding to the method's type encoding.
  51. @property (nonatomic, readonly) NSMethodSignature *signature;
  52. /// Same as \e typeEncoding but with parameter sizes up front and offsets after the types.
  53. @property (nonatomic, readonly) NSString *signatureString;
  54. /// The return type of the method.
  55. @property (nonatomic, readonly) FLEXTypeEncoding *returnType;
  56. /// The return size of the method.
  57. @property (nonatomic, readonly) NSUInteger returnSize;
  58. /// Like @code - (void)foo:(int)bar @endcode
  59. @property (nonatomic, readonly) NSString *description;
  60. /// Like @code -[Class foo:] @endcode
  61. - (NSString *)debugNameGivenClassName:(NSString *)name;
  62. /// Swizzles the recieving method with the given method.
  63. - (void)swapImplementations:(FLEXMethod *)method;
  64. #define FLEXMagicNumber 0xdeadbeef
  65. #define FLEXArg(expr) FLEXMagicNumber,/// @encode(__typeof__(expr)), (__typeof__(expr) []){ expr }
  66. /// Sends a message to \e target, and returns it's value, or \c nil if not applicable.
  67. /// @discussion You may send any message with this method. Primitive return values will be wrapped
  68. /// in instances of \c NSNumber and \c NSValue. \c void and bitfield returning methods return \c nil.
  69. /// \c SEL return types are converted to strings using \c NSStringFromSelector.
  70. /// @return The object returned by this method, or an instance of \c NSValue or \c NSNumber containing
  71. /// the primitive return type, or a string for \c SEL return types.
  72. - (id)sendMessage:(id)target, ...;
  73. /// Used internally by \c sendMessage:target,. Pass \c NULL to the first parameter for void methods.
  74. - (void)getReturnValue:(void *)retPtr forMessageSend:(id)target, ...;
  75. @end
  76. @interface FLEXMethod (Comparison)
  77. - (NSComparisonResult)compare:(FLEXMethod *)method;
  78. @end
  79. NS_ASSUME_NONNULL_END