Bläddra i källkod

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 7 år sedan
förälder
incheckning
78a34a8437

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

@@ -195,22 +195,35 @@ typedef NS_ENUM(NSUInteger, FLEXArgInputObjectType) {
         if (strcmp(type, @encode(id)) != 0) {
         if (strcmp(type, @encode(id)) != 0) {
             BOOL isJSONSerializableType = NO;
             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
             // Note: we can't use @encode(NSString) here because that drops
             // the class information and just goes to @encode(id).
             // 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
             // 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;
                     isJSONSerializableType = YES;
                     break;
                     break;
                 }
                 }

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

@@ -32,6 +32,7 @@
     return [self.inputTextView.text length] > 0 ? [self.inputTextView.text copy] : nil;
     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 -
 #pragma mark -
 
 

+ 8 - 2
Classes/Editing/FLEXDefaultEditorViewController.m

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

+ 3 - 0
Classes/Editing/FLEXIvarEditorViewController.m

@@ -52,6 +52,9 @@
 - (void)actionButtonPressed:(id)sender
 - (void)actionButtonPressed:(id)sender
 {
 {
     [super actionButtonPressed: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];
     [FLEXRuntimeUtility setValue:self.firstInputView.inputValue forIvar:self.ivar onObject:self.target];
     self.firstInputView.inputValue = [FLEXRuntimeUtility valueForIvar: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 FLEXEncodeClass(class) ("@\"" #class "\"")
+#define FLEXEncodeObject(obj) (obj ? [NSString stringWithFormat:@"@\"%@\"", [obj class]].UTF8String : @encode(id))
 
 
 @interface FLEXRuntimeUtility : NSObject
 @interface FLEXRuntimeUtility : NSObject