Quellcode durchsuchen

Fix bug in FLEXArgumentInputObjectView

Class was not properly detecting JSON encodable classes. We now parse class names out of the type encoding and turn them into Class objects to check where they fall in the class hierarchy.
Tanner Bennett vor 7 Jahren
Ursprung
Commit
78a34a8437

+ 24 - 11
Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.m

@@ -195,22 +195,35 @@ typedef NS_ENUM(NSUInteger, FLEXArgInputObjectType) {
         if (strcmp(type, @encode(id)) != 0) {
             BOOL isJSONSerializableType = NO;
 
+            // Parse class name out of the string,
+            // which is in the form `@"ClassName"`
+            Class cls = NSClassFromString(({
+                NSString *className = nil;
+                NSScanner *scan = [NSScanner scannerWithString:@(type)];
+                NSCharacterSet *allowed = [NSCharacterSet
+                    characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$"
+                ];
+
+                // Skip over the @" then scan the name
+                if ([scan scanString:@"@\"" intoString:nil]) {
+                    [scan scanCharactersFromSet:allowed intoString:&className];
+                }
+
+                className;
+            }));
+
             // Note: we can't use @encode(NSString) here because that drops
             // the class information and just goes to @encode(id).
-            NSArray *jsonTypes = @[
-                @(FLEXEncodeClass(NSString)),
-                @(FLEXEncodeClass(NSNumber)),
-                @(FLEXEncodeClass(NSArray)),
-                @(FLEXEncodeClass(NSDictionary)),
-                @(FLEXEncodeClass(NSMutableString)),
-                @(FLEXEncodeClass(NSMutableArray)),
-                @(FLEXEncodeClass(NSMutableDictionary)),
+            NSArray<Class> *jsonTypes = @[
+                [NSString class],
+                [NSNumber class],
+                [NSArray class],
+                [NSDictionary class],
             ];
 
             // Look for matching types
-            NSString *typeStr = @(type);
-            for (NSString *encodedClass in jsonTypes) {
-                if ([typeStr isEqualToString:encodedClass]) {
+            for (Class jsonClass in jsonTypes) {
+                if ([cls isSubclassOfClass:jsonClass]) {
                     isJSONSerializableType = YES;
                     break;
                 }

+ 1 - 0
Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m

@@ -32,6 +32,7 @@
     return [self.inputTextView.text length] > 0 ? [self.inputTextView.text copy] : nil;
 }
 
+// TODO: Support using object address for strings, as in the object arg view.
 
 #pragma mark -
 

+ 8 - 2
Classes/Editing/FLEXDefaultEditorViewController.m

@@ -43,7 +43,10 @@
     self.fieldEditorView.fieldDescription = self.key;
 
     id currentValue = [self.defaults objectForKey:self.key];
-    FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:@encode(id) currentValue:currentValue];
+    FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory
+        argumentInputViewForTypeEncoding:FLEXEncodeObject(currentValue)
+        currentValue:currentValue
+    ];
     inputView.backgroundColor = self.view.backgroundColor;
     inputView.inputValue = currentValue;
     self.fieldEditorView.argumentInputViews = @[inputView];
@@ -73,7 +76,10 @@
 
 + (BOOL)canEditDefaultWithValue:(id)currentValue
 {
-    return [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:@encode(id) currentValue:currentValue];
+    return [FLEXArgumentInputViewFactory
+        canEditFieldWithTypeEncoding:FLEXEncodeObject(currentValue)
+        currentValue:currentValue
+    ];
 }
 
 @end

+ 3 - 0
Classes/Editing/FLEXIvarEditorViewController.m

@@ -52,6 +52,9 @@
 - (void)actionButtonPressed:(id)sender
 {
     [super actionButtonPressed:sender];
+
+    // TODO: check mutability and use mutableCopy if necessary;
+    // this currently could and would assign NSArray to NSMutableArray
     
     [FLEXRuntimeUtility setValue:self.firstInputView.inputValue forIvar:self.ivar onObject:self.target];
     self.firstInputView.inputValue = [FLEXRuntimeUtility valueForIvar:self.ivar onObject:self.target];

+ 1 - 0
Classes/Utility/FLEXRuntimeUtility.h

@@ -55,6 +55,7 @@ typedef NS_ENUM(char, FLEXTypeEncoding)
 };
 
 #define FLEXEncodeClass(class) ("@\"" #class "\"")
+#define FLEXEncodeObject(obj) (obj ? [NSString stringWithFormat:@"@\"%@\"", [obj class]].UTF8String : @encode(id))
 
 @interface FLEXRuntimeUtility : NSObject