FLEXRuntimeKeyPath.m 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // FLEXRuntimeKeyPath.m
  3. // FLEX
  4. //
  5. // Created by Tanner on 3/22/17.
  6. // Copyright © 2017 Tanner Bennett. All rights reserved.
  7. //
  8. #import "FLEXRuntimeKeyPath.h"
  9. #include <dlfcn.h>
  10. @interface FLEXRuntimeKeyPath () {
  11. NSString *flex_description;
  12. }
  13. @end
  14. @implementation FLEXRuntimeKeyPath
  15. + (instancetype)empty {
  16. static FLEXRuntimeKeyPath *empty = nil;
  17. static dispatch_once_t onceToken;
  18. dispatch_once(&onceToken, ^{
  19. FLEXSearchToken *any = FLEXSearchToken.any;
  20. empty = [self new];
  21. empty->_bundleKey = any;
  22. empty->flex_description = @"";
  23. });
  24. return empty;
  25. }
  26. + (instancetype)bundle:(FLEXSearchToken *)bundle
  27. class:(FLEXSearchToken *)cls
  28. method:(FLEXSearchToken *)method
  29. isInstance:(NSNumber *)instance
  30. string:(NSString *)keyPathString {
  31. FLEXRuntimeKeyPath *keyPath = [self new];
  32. keyPath->_bundleKey = bundle;
  33. keyPath->_classKey = cls;
  34. keyPath->_methodKey = method;
  35. keyPath->_instanceMethods = instance;
  36. // Remove irrelevant trailing '*' for equality purposes
  37. if ([keyPathString hasSuffix:@"*"]) {
  38. keyPathString = [keyPathString substringToIndex:keyPathString.length];
  39. }
  40. keyPath->flex_description = keyPathString;
  41. if (bundle.isAny && cls.isAny && method.isAny) {
  42. [self initializeWebKitLegacy];
  43. }
  44. return keyPath;
  45. }
  46. + (void)initializeWebKitLegacy {
  47. static dispatch_once_t onceToken;
  48. dispatch_once(&onceToken, ^{
  49. void *handle = dlopen(
  50. "/System/Library/PrivateFrameworks/WebKitLegacy.framework/WebKitLegacy",
  51. RTLD_LAZY
  52. );
  53. void (*WebKitInitialize)() = dlsym(handle, "WebKitInitialize");
  54. if (WebKitInitialize) {
  55. NSAssert(NSThread.isMainThread,
  56. @"WebKitInitialize can only be called on the main thread"
  57. );
  58. WebKitInitialize();
  59. }
  60. });
  61. }
  62. - (NSString *)description {
  63. return flex_description;
  64. }
  65. - (NSUInteger)hash {
  66. return flex_description.hash;
  67. }
  68. - (BOOL)isEqual:(id)object {
  69. if ([object isKindOfClass:[FLEXRuntimeKeyPath class]]) {
  70. FLEXRuntimeKeyPath *kp = object;
  71. return [flex_description isEqualToString:kp->flex_description];
  72. }
  73. return NO;
  74. }
  75. @end