|
@@ -15,7 +15,18 @@
|
|
|
{
|
|
{
|
|
|
self = [super initWithArgumentTypeEncoding:typeEncoding];
|
|
self = [super initWithArgumentTypeEncoding:typeEncoding];
|
|
|
if (self) {
|
|
if (self) {
|
|
|
- self.targetSize = FLEXArgumentInputViewSizeLarge;
|
|
|
|
|
|
|
+ FLEXTypeEncoding type = typeEncoding[0];
|
|
|
|
|
+ if (type == FLEXTypeEncodingConst) {
|
|
|
|
|
+ // A crash here would mean an invalid type encoding string
|
|
|
|
|
+ type = typeEncoding[1];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Selectors don't need a multi-line text box
|
|
|
|
|
+ if (type == FLEXTypeEncodingSelector) {
|
|
|
|
|
+ self.targetSize = FLEXArgumentInputViewSizeSmall;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ self.targetSize = FLEXArgumentInputViewSizeLarge;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
return self;
|
|
return self;
|
|
|
}
|
|
}
|
|
@@ -24,28 +35,99 @@
|
|
|
{
|
|
{
|
|
|
if ([inputValue isKindOfClass:[NSString class]]) {
|
|
if ([inputValue isKindOfClass:[NSString class]]) {
|
|
|
self.inputTextView.text = inputValue;
|
|
self.inputTextView.text = inputValue;
|
|
|
- }
|
|
|
|
|
|
|
+ } else if ([inputValue isKindOfClass:[NSValue class]]) {
|
|
|
|
|
+ NSValue *value = (id)inputValue;
|
|
|
|
|
+ NSParameterAssert(strlen(value.objCType) == 1);
|
|
|
|
|
+
|
|
|
|
|
+ // C-String or SEL from NSValue
|
|
|
|
|
+ FLEXTypeEncoding type = value.objCType[0];
|
|
|
|
|
+ if (type == FLEXTypeEncodingConst) {
|
|
|
|
|
+ // A crash here would mean an invalid type encoding string
|
|
|
|
|
+ type = value.objCType[1];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // TODO: support NSValue coontaining char *
|
|
|
|
|
|
|
+ if (type == FLEXTypeEncodingCString) {
|
|
|
|
|
+ self.inputTextView.text = @((const char *)value.pointerValue);
|
|
|
|
|
+ } else if (type == FLEXTypeEncodingSelector) {
|
|
|
|
|
+ self.inputTextView.text = NSStringFromSelector((SEL)value.pointerValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- (id)inputValue
|
|
- (id)inputValue
|
|
|
{
|
|
{
|
|
|
|
|
+ NSString *text = self.inputTextView.text;
|
|
|
// Interpret empty string as nil. We loose the ability to set empty string as a string value,
|
|
// Interpret empty string as nil. We loose the ability to set empty string as a string value,
|
|
|
// but we accept that tradeoff in exchange for not having to type quotes for every string.
|
|
// but we accept that tradeoff in exchange for not having to type quotes for every string.
|
|
|
- return self.inputTextView.text.length > 0 ? [self.inputTextView.text copy] : nil;
|
|
|
|
|
|
|
+ if (!text.length) {
|
|
|
|
|
+ return nil;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Case: C-strings and SELs
|
|
|
|
|
+ if (self.typeEncoding.length <= 2) {
|
|
|
|
|
+ FLEXTypeEncoding type = [self.typeEncoding characterAtIndex:0];
|
|
|
|
|
+ if (type == FLEXTypeEncodingConst) {
|
|
|
|
|
+ // A crash here would mean an invalid type encoding string
|
|
|
|
|
+ type = [self.typeEncoding characterAtIndex:1];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (type == FLEXTypeEncodingCString || type == FLEXTypeEncodingSelector) {
|
|
|
|
|
+ const char *encoding = self.typeEncoding.UTF8String;
|
|
|
|
|
+ SEL selector = NSSelectorFromString(text);
|
|
|
|
|
+ return [NSValue valueWithBytes:&selector objCType:encoding];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Case: NSStrings
|
|
|
|
|
+ return self.inputTextView.text.copy;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TODO: Support using object address for strings, as in the object arg view.
|
|
// TODO: Support using object address for strings, as in the object arg view.
|
|
|
|
|
|
|
|
-#pragma mark -
|
|
|
|
|
-
|
|
|
|
|
+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value
|
|
+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value
|
|
|
{
|
|
{
|
|
|
NSParameterAssert(type);
|
|
NSParameterAssert(type);
|
|
|
|
|
+ unsigned long len = strlen(type);
|
|
|
|
|
+
|
|
|
|
|
+ BOOL isConst = type[0] == FLEXTypeEncodingConst;
|
|
|
|
|
+ NSInteger i = isConst ? 1 : 0;
|
|
|
|
|
+
|
|
|
BOOL typeIsString = strcmp(type, FLEXEncodeClass(NSString)) == 0;
|
|
BOOL typeIsString = strcmp(type, FLEXEncodeClass(NSString)) == 0;
|
|
|
- BOOL valueIsNilOrString = (!value || [value isKindOfClass:[NSString class]]);
|
|
|
|
|
- return typeIsString && valueIsNilOrString;
|
|
|
|
|
|
|
+ BOOL typeIsCString = len <= 2 && type[i] == FLEXTypeEncodingCString;
|
|
|
|
|
+ BOOL typeIsSEL = len <= 2 && type[i] == FLEXTypeEncodingSelector;
|
|
|
|
|
+ BOOL valueIsString = [value isKindOfClass:[NSString class]];
|
|
|
|
|
+
|
|
|
|
|
+ BOOL typeIsPrimitiveString = typeIsSEL || typeIsCString;
|
|
|
|
|
+ BOOL typeIsSupported = typeIsString || typeIsCString || typeIsSEL;
|
|
|
|
|
+
|
|
|
|
|
+ BOOL valueIsNSValueWithCorrectType = NO;
|
|
|
|
|
+ if ([value isKindOfClass:[NSValue class]]) {
|
|
|
|
|
+ NSValue *v = (id)value;
|
|
|
|
|
+ len = strlen(v.objCType);
|
|
|
|
|
+ if (len == 1) {
|
|
|
|
|
+ FLEXTypeEncoding type = v.objCType[i];
|
|
|
|
|
+ if (type == FLEXTypeEncodingCString && typeIsCString) {
|
|
|
|
|
+ valueIsNSValueWithCorrectType = YES;
|
|
|
|
|
+ } else if (type == FLEXTypeEncodingSelector && typeIsSEL) {
|
|
|
|
|
+ valueIsNSValueWithCorrectType = YES;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!value && typeIsSupported) {
|
|
|
|
|
+ return YES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (typeIsString && valueIsString) {
|
|
|
|
|
+ return YES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Primitive strings can be input as NSStrings or NSValues
|
|
|
|
|
+ if (typeIsPrimitiveString && (valueIsString || valueIsNSValueWithCorrectType)) {
|
|
|
|
|
+ return YES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NO;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
@end
|