Просмотр исходного кода

Improve readability of FLEXRuntimeUtility

Tanner Bennett лет назад: 6
Родитель
Сommit
46652ac73d
2 измененных файлов с 99 добавлено и 29 удалено
  1. 10 2
      Classes/Utility/FLEXRuntimeUtility.h
  2. 89 27
      Classes/Utility/FLEXRuntimeUtility.m

+ 10 - 2
Classes/Utility/FLEXRuntimeUtility.h

@@ -97,11 +97,19 @@ typedef NS_ENUM(char, FLEXTypeEncoding)
 + (FLEXTypeEncoding *)returnTypeForMethod:(Method)method;
 
 // Method Calling/Field Editing
-+ (id)performSelector:(SEL)selector onObject:(id)object withArguments:(NSArray *)arguments error:(NSError * __autoreleasing *)error;
++ (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;
++ (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

+ 89 - 27
Classes/Utility/FLEXRuntimeUtility.m

@@ -139,7 +139,11 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
     NSString *setterSelectorString = [[self attributesDictionaryForProperty:property] objectForKey:kFLEXUtilityAttributeCustomSetter];
     if (!setterSelectorString) {
         NSString *propertyName = @(property_getName(property));
-        setterSelectorString = [NSString stringWithFormat:@"set%@%@:", [[propertyName substringToIndex:1] uppercaseString], [propertyName substringFromIndex:1]];
+        setterSelectorString = [NSString
+            stringWithFormat:@"set%@%@:",
+            [propertyName substringToIndex:1].uppercaseString,
+            [propertyName substringFromIndex:1]
+        ];
     }
     if (setterSelectorString) {
         setterSelector = NSSelectorFromString(setterSelectorString);
@@ -248,7 +252,9 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
     return description;
 }
 
-+ (void)tryAddPropertyWithName:(const char *)name attributes:(NSDictionary<NSString *, NSString *> *)attributePairs toClass:(__unsafe_unretained Class)theClass
++ (void)tryAddPropertyWithName:(const char *)name
+                    attributes:(NSDictionary<NSString *, NSString *> *)attributePairs
+                       toClass:(__unsafe_unretained Class)theClass
 {
     objc_property_t property = class_getProperty(theClass, name);
     if (!property) {
@@ -313,13 +319,18 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
         NSValue *valueValue = (NSValue *)value;
 
         // Make sure that the box contained the correct type.
-        NSAssert(strcmp([valueValue objCType], typeEncodingCString) == 0, @"Type encoding mismatch (value: %s; ivar: %s) in setting ivar named: %s on object: %@", [valueValue objCType], typeEncodingCString, ivar_getName(ivar), object);
+        NSAssert(
+            strcmp(valueValue.objCType, typeEncodingCString) == 0,
+            @"Type encoding mismatch (value: %s; ivar: %s) in setting ivar named: %s on object: %@",
+            valueValue.objCType, typeEncodingCString, ivar_getName(ivar), object
+        );
 
         NSUInteger bufferSize = 0;
         @try {
             // NSGetSizeAndAlignment barfs on type encoding for bitfields.
             NSGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL);
         } @catch (NSException *exception) { }
+
         if (bufferSize > 0) {
             void *buffer = calloc(bufferSize, 1);
             [valueValue getValue:buffer];
@@ -372,7 +383,11 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
         char *argType = method_copyArgumentType(method, argIndex + kFLEXNumberOfImplicitArgs);
         NSString *readableArgType = (argType != NULL) ? [self readableTypeForEncoding:@(argType)] : nil;
         free(argType);
-        NSString *prettyComponent = [NSString stringWithFormat:@"%@:(%@) ", [selectorComponents objectAtIndex:argIndex], readableArgType];
+        NSString *prettyComponent = [NSString
+            stringWithFormat:@"%@:(%@) ",
+            selectorComponents[argIndex],
+            readableArgType
+        ];
         [components addObject:prettyComponent];
     }
 
@@ -387,13 +402,24 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
 
 #pragma mark - Method Calling/Field Editing (Public)
 
-+ (id)performSelector:(SEL)selector onObject:(id)object withArguments:(NSArray *)arguments error:(NSError * __autoreleasing *)error
++ (id)performSelector:(SEL)selector
+             onObject:(id)object
+        withArguments:(NSArray *)arguments
+                error:(NSError * __autoreleasing *)error
 {
     // Bail if the object won't respond to this selector.
     if (![object respondsToSelector:selector]) {
         if (error) {
-            NSDictionary<NSString *, id> *userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"%@ does not respond to the selector %@", object, NSStringFromSelector(selector)]};
-            *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain code:FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector userInfo:userInfo];
+            NSString *msg = [NSString
+                stringWithFormat:@"%@ does not respond to the selector %@",
+                object, NSStringFromSelector(selector)
+            ];
+            NSDictionary<NSString *, id> *userInfo = @{ NSLocalizedDescriptionKey : msg };
+            *error = [NSError
+                errorWithDomain:FLEXRuntimeUtilityErrorDomain
+                code:FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector
+                userInfo:userInfo
+            ];
         }
         return nil;
     }
@@ -424,13 +450,17 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
         NSUInteger argumentsArrayIndex = argumentIndex - kFLEXNumberOfImplicitArgs;
         id argumentObject = arguments.count > argumentsArrayIndex ? arguments[argumentsArrayIndex] : nil;
 
-        // NSNull in the arguments array can be passed as a placeholder to indicate nil. We only need to set the argument if it will be non-nil.
+        // NSNull in the arguments array can be passed as a placeholder to indicate nil.
+        // We only need to set the argument if it will be non-nil.
         if (argumentObject && ![argumentObject isKindOfClass:[NSNull class]]) {
             const char *typeEncodingCString = [methodSignature getArgumentTypeAtIndex:argumentIndex];
-            if (typeEncodingCString[0] == FLEXTypeEncodingObjcObject || typeEncodingCString[0] == FLEXTypeEncodingObjcClass || [self isTollFreeBridgedValue:argumentObject forCFType:typeEncodingCString]) {
+            if (typeEncodingCString[0] == FLEXTypeEncodingObjcObject ||
+              typeEncodingCString[0] == FLEXTypeEncodingObjcClass ||
+              [self isTollFreeBridgedValue:argumentObject forCFType:typeEncodingCString]) {
                 // Object
                 [invocation setArgument:&argumentObject atIndex:argumentIndex];
-            } else if (strcmp(typeEncodingCString, @encode(CGColorRef)) == 0 && [argumentObject isKindOfClass:[UIColor class]]) {
+            } else if (strcmp(typeEncodingCString, @encode(CGColorRef)) == 0 &&
+                    [argumentObject isKindOfClass:[UIColor class]]) {
                 // Bridging UIColor to CGColorRef
                 CGColorRef colorRef = [argumentObject CGColor];
                 [invocation setArgument:&colorRef atIndex:argumentIndex];
@@ -441,8 +471,17 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
                 // Ensure that the type encoding on the NSValue matches the type encoding of the argument in the method signature
                 if (strcmp([argumentValue objCType], typeEncodingCString) != 0) {
                     if (error) {
-                        NSDictionary<NSString *, id> *userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Type encoding mismatch for argument at index %lu. Value type: %s; Method argument type: %s.", (unsigned long)argumentsArrayIndex, [argumentValue objCType], typeEncodingCString]};
-                        *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain code:FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch userInfo:userInfo];
+                        NSString *msg =  [NSString
+                            stringWithFormat:@"Type encoding mismatch for argument at index %lu. "
+                            "Value type: %s; Method argument type: %s.",
+                            (unsigned long)argumentsArrayIndex, argumentValue.objCType, typeEncodingCString
+                        ];
+                        NSDictionary<NSString *, id> *userInfo = @{ NSLocalizedDescriptionKey : msg };
+                        *error = [NSError
+                            errorWithDomain:FLEXRuntimeUtilityErrorDomain
+                            code:FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch
+                            userInfo:userInfo
+                        ];
                     }
                     return nil;
                 }
@@ -494,11 +533,10 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
             NSString *class = NSStringFromClass([object class]);
             NSString *calledOn = object == [object class] ? class : [@"an instance of " stringByAppendingString:class];
 
-            NSString *message = [NSString stringWithFormat:@"Exception '%@' thrown while performing selector '%@' on %@.\nReason:\n\n%@",
-                                 exception.name,
-                                 NSStringFromSelector(selector),
-                                 calledOn,
-                                 exception.reason];
+            NSString *message = [NSString
+                stringWithFormat:@"Exception '%@' thrown while performing selector '%@' on %@.\nReason:\n\n%@",
+                exception.name, NSStringFromSelector(selector), calledOn, exception.reason
+            ];
 
             *error = [NSError errorWithDomain:FLEXRuntimeUtilityErrorDomain
                                          code:FLEXRuntimeUtilityErrorCodeInvocationFailed
@@ -557,7 +595,8 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
         // We always wrap the object inside an array and then strip the outer square braces off the final string.
         NSArray *wrappedObject = @[object];
         if ([NSJSONSerialization isValidJSONObject:wrappedObject]) {
-            NSString *wrappedDescription = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:wrappedObject options:0 error:NULL] encoding:NSUTF8StringEncoding];
+            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:wrappedObject options:0 error:NULL];
+            NSString *wrappedDescription = [NSString stringWithUTF8String:jsonData.bytes];
             editableDescription = [wrappedDescription substringWithRange:NSMakeRange(1, wrappedDescription.length - 2)];
         }
     }
@@ -569,8 +608,12 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
 {
     id value = nil;
     // nil for empty string/whitespace
-    if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0) {
-        value = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:NULL];
+    if ([string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length) {
+        value = [NSJSONSerialization
+            JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
+            options:NSJSONReadingAllowFragments
+            error:NULL
+        ];
     }
     return value;
 }
@@ -627,13 +670,20 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
     return value;
 }
 
-+ (void)enumerateTypesInStructEncoding:(const char *)structEncoding usingBlock:(void (^)(NSString *structName, const char *fieldTypeEncoding, NSString *prettyTypeEncoding, NSUInteger fieldIndex, NSUInteger fieldOffset))typeBlock
++ (void)enumerateTypesInStructEncoding:(const char *)structEncoding
+                            usingBlock:(void (^)(NSString *structName,
+                                                 const char *fieldTypeEncoding,
+                                                 NSString *prettyTypeEncoding,
+                                                 NSUInteger fieldIndex,
+                                                 NSUInteger fieldOffset))typeBlock
 {
     if (structEncoding && structEncoding[0] == FLEXTypeEncodingStructBegin) {
         const char *equals = strchr(structEncoding, '=');
         if (equals) {
             const char *nameStart = structEncoding + 1;
-            NSString *structName = [@(structEncoding) substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart)];
+            NSString *structName = [@(structEncoding)
+                substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart)
+            ];
 
             NSUInteger fieldAlignment = 0;
             NSUInteger structSize = 0;
@@ -650,14 +700,22 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
                     NSUInteger fieldSize = 0;
                     // If the struct type encoding was successfully handled by NSGetSizeAndAlignment above, we *should* be ok with the field here.
                     const char *nextTypeStart = NSGetSizeAndAlignment(typeStart, &fieldSize, NULL);
-                    NSString *typeEncoding = [@(structEncoding) substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart)];
+                    NSString *typeEncoding = [@(structEncoding)
+                        substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart)
+                    ];
                     // Padding to keep proper alignment. __attribute((packed)) structs will break here.
                     // The type encoding is no different for packed structs, so it's not clear there's anything we can do for those.
                     const NSUInteger currentSizeSum = runningFieldOffset % fieldAlignment;
                     if (currentSizeSum != 0 && currentSizeSum + fieldSize > fieldAlignment) {
                         runningFieldOffset += fieldAlignment - currentSizeSum;
                     }
-                    typeBlock(structName, typeEncoding.UTF8String, [self readableTypeForEncoding:typeEncoding], runningFieldIndex, runningFieldOffset);
+                    typeBlock(
+                        structName,
+                        typeEncoding.UTF8String,
+                        [self readableTypeForEncoding:typeEncoding],
+                        runningFieldIndex,
+                        runningFieldOffset
+                    );
                     runningFieldOffset += fieldSize;
                     runningFieldIndex++;
                     typeStart = nextTypeStart;
@@ -712,7 +770,9 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
         // According to https://github.com/nygard/class-dump/commit/33fb5ed221810685f57c192e1ce8ab6054949a7c,
         // there are some consecutive quoted strings, so use `_` to concatenate the names.
         NSString *const fieldNamesString = [encodingString substringWithRange:NSMakeRange(0, fieldNameOffset)];
-        NSArray<NSString *> *const fieldNames = [fieldNamesString componentsSeparatedByString:[NSString stringWithFormat:@"%c", FLEXTypeEncodingQuote]];
+        NSArray<NSString *> *const fieldNames = [fieldNamesString
+            componentsSeparatedByString:[NSString stringWithFormat:@"%c", FLEXTypeEncodingQuote]
+        ];
         NSMutableString *finalFieldNamesString = [NSMutableString string];
         for (NSString *const fieldName in fieldNames) {
             if (fieldName.length > 0) {
@@ -729,7 +789,7 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
     // Objects
     if (encodingCString[0] == FLEXTypeEncodingObjcObject) {
         NSString *class = [encodingString substringFromIndex:1];
-        class = [class stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%c", FLEXTypeEncodingQuote] withString:@""];
+        class = [class stringByReplacingOccurrencesOfString:@"\"" withString:@""];
         if (class.length == 0 || (class.length == 1 && [class characterAtIndex:0] == FLEXTypeEncodingUnknown)) {
             class = @"id";
         } else {
@@ -821,7 +881,9 @@ const unsigned int kFLEXNumberOfImplicitArgs = 2;
             if (nameStart[0] == FLEXTypeEncodingUnknown) {
                 return @"anonymous struct";
             } else {
-                NSString *const structName = [encodingString substringWithRange:NSMakeRange(nameStart - encodingCString, equals - nameStart)];
+                NSString *const structName = [encodingString
+                    substringWithRange:NSMakeRange(nameStart - encodingCString, equals - nameStart)
+                ];
                 return structName;
             }
         }