Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adds a nondestructive -attributeTypeName property to attributes #86

Merged
merged 4 commits into from

3 participants

@robrix

It is usable as a replacement for both -scalarAttributeType and -objectAttributeType, and pulls from the attributeValueTypeName userInfo field if available.

@robrix robrix Adds -attributeTypeName to attributes.
-attributeTypeName uses the “attributeValueTypeName” field in userInfo if available, defaulting to the scalarAttributeType if any, or else the objectAttributeType suffixed with a *.

Intended for use in the templates, deprecating both -scalarAttributeType and -objectAttributeType.

Use case: transformable attributes with “id” as their type (as opposed to the unidiomatic and frankly weird NSObject *).
01e5043
@robrix

I should note, this would close #85.

@robrix robrix Adds scalar int*_t support.
This is done by adding -scalarAttributeTypeName, -scalarAccessorMethodName, and -scalarFactoryMethodName to NSAttributeDescription.

-scalarAttributeTypeName returns the same thing as -scalarAttributeType, except that where that uses short, int, and long long, the new method uses int16_t, int32_t, and int64_t.

To allow simple boxing and unboxing with NSNumber, -scalarAccessorMethodName and -scalarFactoryMethodName return the appropriate values for the scalar type, e.g. boolValue, longLongValue, and numberWithShort:.
fd2b556
@robrix

I did not mean to add the second commit to this pull request! Oh well, it provides a fix for #2. Do with it what you will! I leave my code humbly at your mercy.

@rentzsch rentzsch merged commit c82f11a into from
@rentzsch
Owner

I found some other issues examining the test mule MOs, which I fixed up here: 25bc9fc

You may want to take a look, especially since I removed support for attributeValueTypeName attribute userInfo key since I couldn't figure how it differs from the existing attributeValueClassName support. Maybe I'm missing something?

@robrix

Main difference with attributeValueTypeName was that it would allow you to specify e.g. id without having the * appended onto it. attributeValueClassName seems to handle that by replacing NSObject * with id.

On the other hand, other type names would also be possible with attributeValueTypeName that aren’t with this handling of attributeValueClassName, for example Class and id<SomeProtocol>.

The intention was basically “type name, verbatim.” I still kind of feel like this is valuable for the protocol case especially (without resorting to NSObject<SomeProtocol> *), which is something I’ve occasionally wanted. What do you think?

Sorry about the NSNumber mistakes. Derp :)

@rentzsch
Owner

Ah, I see.

I don't think we need direct "type name, verbatim" support if we keep the generation code smart enough. For instance, I added NSObject* detection, replacing it with an id. So I think we already have all the bases covered with that simple heuristic.

Let me know if you have any other examples that aren't correctly handled.

@robrix
@rentzsch
Owner

Oh, I misunderstood your text. Yup, those aren't covered. I'm more inclined to make attributeValueClassName mean "type name, verbatim" than add another userInfo key, and accept the fact folks will need to tweak their model to add the asterisk.

@robrix
@robrix
@JoeOsborn

Devil's advocate time, I guess: What's wrong with special-casing an understanding of Class and id and id<ProtocolName[,…]> when generating from an attributeValueClassName? It seems irritating to have to throw asterisks all over the place in userInfo fields in the data model.

@robrix
@rentzsch
Owner

@JoeOsborn: yup, I was already thinking along those lines myself. Good to hear you're on the same wavelength.

I'm thinking about something like this (in mostly-JavaScript):

if (attributeValueClassName.match(/Class/)) return attributeValueClassName; // Class
if (attributeValueClassName.match(/</)) return attributeValueClassName; // id<Protocol1,Protocol2>
if (attributeValueClassName.match(/NSObject */)) return "id"; // NSObject *
return attributeValueClassName;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 7, 2012
  1. @robrix

    Adds -attributeTypeName to attributes.

    robrix authored
    -attributeTypeName uses the “attributeValueTypeName” field in userInfo if available, defaulting to the scalarAttributeType if any, or else the objectAttributeType suffixed with a *.
    
    Intended for use in the templates, deprecating both -scalarAttributeType and -objectAttributeType.
    
    Use case: transformable attributes with “id” as their type (as opposed to the unidiomatic and frankly weird NSObject *).
  2. @robrix

    Adds scalar int*_t support.

    robrix authored
    This is done by adding -scalarAttributeTypeName, -scalarAccessorMethodName, and -scalarFactoryMethodName to NSAttributeDescription.
    
    -scalarAttributeTypeName returns the same thing as -scalarAttributeType, except that where that uses short, int, and long long, the new method uses int16_t, int32_t, and int64_t.
    
    To allow simple boxing and unboxing with NSNumber, -scalarAccessorMethodName and -scalarFactoryMethodName return the appropriate values for the scalar type, e.g. boolValue, longLongValue, and numberWithShort:.
  3. @robrix

    The default template uses the new attr methods.

    robrix authored
    Also defaulted to using int*_t for scalars at the same time.
  4. @robrix
This page is out of date. Refresh to see the latest.
View
4 mogenerator.h
@@ -30,8 +30,12 @@
@interface NSAttributeDescription (scalarAttributeType)
- (BOOL)hasScalarAttributeType;
- (NSString*)scalarAttributeType;
+- (NSString*)scalarAttributeTypeName;
+- (NSString*)scalarAccessorMethodName;
+- (NSString*)scalarFactoryMethodName;
- (BOOL)hasDefinedAttributeType;
- (NSString*)objectAttributeType;
+- (NSString*)attributeTypeName;
- (BOOL)hasTransformableAttributeType;
@end
View
78 mogenerator.m
@@ -248,6 +248,78 @@ - (NSString*)scalarAttributeType {
return nil;
}
}
+- (NSString*)scalarAttributeTypeName {
+ switch ([self attributeType]) {
+ case NSInteger16AttributeType:
+ return @"int16_t";
+ break;
+ case NSInteger32AttributeType:
+ return @"int32_t";
+ break;
+ case NSInteger64AttributeType:
+ return @"int64_t";
+ break;
+ case NSDoubleAttributeType:
+ return @"double";
+ break;
+ case NSFloatAttributeType:
+ return @"float";
+ break;
+ case NSBooleanAttributeType:
+ return @"BOOL";
+ break;
+ default:
+ return nil;
+ }
+}
+- (NSString*)scalarAccessorMethodName {
+ switch ([self attributeType]) {
+ case NSInteger16AttributeType:
+ return @"shortValue";
+ break;
+ case NSInteger32AttributeType:
+ return @"intValue";
+ break;
+ case NSInteger64AttributeType:
+ return @"longLongValue";
+ break;
+ case NSDoubleAttributeType:
+ return @"doubleValue";
+ break;
+ case NSFloatAttributeType:
+ return @"floatValue";
+ break;
+ case NSBooleanAttributeType:
+ return @"boolValue";
+ break;
+ default:
+ return nil;
+ }
+}
+- (NSString*)scalarFactoryMethodName {
+ switch ([self attributeType]) {
+ case NSInteger16AttributeType:
+ return @"numberWithShortValue:";
+ break;
+ case NSInteger32AttributeType:
+ return @"numberWithIntValue:";
+ break;
+ case NSInteger64AttributeType:
+ return @"numberWithLongLongValue:";
+ break;
+ case NSDoubleAttributeType:
+ return @"numberWithDoubleValue:";
+ break;
+ case NSFloatAttributeType:
+ return @"numberWithFloatValue:";
+ break;
+ case NSBooleanAttributeType:
+ return @"numberWithBoolValue:";
+ break;
+ default:
+ return nil;
+ }
+}
- (BOOL)hasDefinedAttributeType {
return [self attributeType] != NSUndefinedAttributeType;
}
@@ -259,6 +331,12 @@ - (NSString*)objectAttributeType {
return [self attributeValueClassName];
}
}
+- (NSString*)attributeTypeName {
+ return
+ [[self userInfo] objectForKey:@"attributeValueTypeName"]
+ ?: [self scalarAttributeTypeName]
+ ?: [[self objectAttributeType] stringByAppendingString:@"*"];
+}
- (BOOL)hasTransformableAttributeType {
return ([self attributeType] == NSTransformableAttributeType);
View
18 templates/machine.h.motemplate
@@ -32,14 +32,14 @@ extern const struct <$managedObjectClassName$>FetchedProperties {<$foreach Fetch
<$foreach Attribute noninheritedAttributes do$>
<$if Attribute.hasDefinedAttributeType$>
<$if TemplateVar.arc$>
-@property (nonatomic, strong) <$Attribute.objectAttributeType$> *<$Attribute.name$>;
+@property (nonatomic, strong) <$Attribute.attributeTypeName$> <$Attribute.name$>;
<$else$>
-@property (nonatomic, retain) <$Attribute.objectAttributeType$> *<$Attribute.name$>;
+@property (nonatomic, retain) <$Attribute.attributeTypeName$> <$Attribute.name$>;
<$endif$>
<$if Attribute.hasScalarAttributeType$>
-@property <$Attribute.scalarAttributeType$> <$Attribute.name$>Value;
-- (<$Attribute.scalarAttributeType$>)<$Attribute.name$>Value;
-- (void)set<$Attribute.name.initialCapitalString$>Value:(<$Attribute.scalarAttributeType$>)value_;
+@property <$Attribute.attributeTypeName$> <$Attribute.name$>Value;
+- (<$Attribute.attributeTypeName$>)<$Attribute.name$>Value;
+- (void)set<$Attribute.name.initialCapitalString$>Value:(<$Attribute.attributeTypeName$>)value_;
<$endif$>
//- (BOOL)validate<$Attribute.name.initialCapitalString$>:(id*)value_ error:(NSError**)error_;
<$endif$>
@@ -87,11 +87,11 @@ extern const struct <$managedObjectClassName$>FetchedProperties {<$foreach Fetch
@interface _<$managedObjectClassName$> (CoreDataGeneratedPrimitiveAccessors)
<$foreach Attribute noninheritedAttributes do$>
<$if Attribute.hasDefinedAttributeType$>
-- (<$Attribute.objectAttributeType$>*)primitive<$Attribute.name.initialCapitalString$>;
-- (void)setPrimitive<$Attribute.name.initialCapitalString$>:(<$Attribute.objectAttributeType$>*)value;
+- (<$Attribute.attributeTypeName$>)primitive<$Attribute.name.initialCapitalString$>;
+- (void)setPrimitive<$Attribute.name.initialCapitalString$>:(<$Attribute.attributeTypeName$>)value;
<$if Attribute.hasScalarAttributeType$>
-- (<$Attribute.scalarAttributeType$>)primitive<$Attribute.name.initialCapitalString$>Value;
-- (void)setPrimitive<$Attribute.name.initialCapitalString$>Value:(<$Attribute.scalarAttributeType$>)value_;
+- (<$Attribute.attributeTypeName$>)primitive<$Attribute.name.initialCapitalString$>Value;
+- (void)setPrimitive<$Attribute.name.initialCapitalString$>Value:(<$Attribute.attributeTypeName$>)value_;
<$endif$>
<$endif$>
<$endforeach do$>
View
14 templates/machine.m.motemplate
@@ -56,22 +56,22 @@ const struct <$managedObjectClassName$>FetchedProperties <$managedObjectClassNam
<$if Attribute.hasScalarAttributeType$>
-- (<$Attribute.scalarAttributeType$>)<$Attribute.name$>Value {
+- (<$Attribute.attributeTypeName$>)<$Attribute.name$>Value {
NSNumber *result = [self <$Attribute.name$>];
- return [result <$Attribute.scalarAttributeType.camelCaseString$>Value];
+ return [result <$Attribute.scalarAccessorMethodName$>];
}
-- (void)set<$Attribute.name.initialCapitalString$>Value:(<$Attribute.scalarAttributeType$>)value_ {
- [self set<$Attribute.name.initialCapitalString$>:[NSNumber numberWith<$Attribute.scalarAttributeType.camelCaseString.initialCapitalString$>:value_]];
+- (void)set<$Attribute.name.initialCapitalString$>Value:(<$Attribute.attributeTypeName$>)value_ {
+ [self set<$Attribute.name.initialCapitalString$>:[NSNumber <$Attribute.scalarFactoryMethodName$>value_]];
}
-- (<$Attribute.scalarAttributeType$>)primitive<$Attribute.name.initialCapitalString$>Value {
+- (<$Attribute.attributeTypeName$>)primitive<$Attribute.name.initialCapitalString$>Value {
NSNumber *result = [self primitive<$Attribute.name.initialCapitalString$>];
- return [result <$Attribute.scalarAttributeType.camelCaseString$>Value];
+ return [result <$Attribute.scalarAccessorMethodName$>];
}
- (void)setPrimitive<$Attribute.name.initialCapitalString$>Value:(<$Attribute.scalarAttributeType$>)value_ {
- [self setPrimitive<$Attribute.name.initialCapitalString$>:[NSNumber numberWith<$Attribute.scalarAttributeType.camelCaseString.initialCapitalString$>:value_]];
+ [self setPrimitive<$Attribute.name.initialCapitalString$>:[NSNumber <$Attribute.scalarFactoryMethodName$>value_]];
}
<$endif$>
<$endif$>
Something went wrong with that request. Please try again.