Skip to content

Commit

Permalink
Use smaller enum types to reduce object sizes. (#207)
Browse files Browse the repository at this point in the history
* Use smaller enum types to reduce object sizes.

If a model has lots of enums, making them smaller instead of 64-bit NSInteger types will help. Apple only uses 64-bit enums since they need to guarantee binary compatibility for years, even after they add new enum values. Since this is generated source and re-compiled into applications, this does not apply.

Building the integration models works. However Pinterest builds with -Werror -Wconversion. This means the -decodeIntegerForKey: needs a cast to the enumeration type name. However down in decodeStatement I do not see how to get the enumeration type name for casting.

This is only applicable to ObjC, since it is the place where these C types will save some space.

* mark location where enum type needed

* fix lints

* update linux tests

* run swiftformat

* Add notes where mz thinks this should occur.

* Determine enum range by looking at the actual values before emitting code this time.

* emit type name when decoding. delete now useless tests.

* remove deleted tests from linux too

* cast enum type name when initing from dictionary

* run swiftformat

* run integration_test

* remove files not part of this PR

* rename to underlyingIntegralType

* move EnumType to integraltype into a helper function for testing. Add tests.

* run swiftformat

* add new linux tests

* Use string enumeration for ObjC enum integral types.

* run swiftformat and fix tests

* add code comment explaining the motivation and effects

* run swift lint

* clean up and correct comment information

* make a func on the enum to do the conversion as reviewed by jparise

* Improve code by improving tests. Add new enumeration types to everything.json.

* run format

* group the enum properties together in property declarations in the category to group them together in memory layout.

* Update Sources/Core/ObjectiveCIR.swift

Thanks!

Co-Authored-By: Jon Parise <[email protected]>

* rename all of them

* run format

* Move enum tests to their own file and separate them out individually.

* remove unnecessary isEmpty check as caught in review

* rename enumerationIntegralTypeFor to forValue as per review

* use --> as per review
  • Loading branch information
bolsinga authored and rahul-malik committed Jun 7, 2019
1 parent ef88906 commit d3c6322
Show file tree
Hide file tree
Showing 19 changed files with 1,089 additions and 73 deletions.
291 changes: 284 additions & 7 deletions Examples/Cocoa/Sources/Objective_C/Everything.m

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions Examples/Cocoa/Sources/Objective_C/Pin.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder
if (!(self = [super init])) {
return self;
}
_internalType = [aDecoder decodeIntegerForKey:@"internal_type"];
_internalType = (PinAttributionObjectsInternalType)[aDecoder decodeIntegerForKey:@"internal_type"];
_value0 = [aDecoder decodeObjectOfClass:[Board class] forKey:@"value0"];
_value1 = [aDecoder decodeObjectOfClass:[User class] forKey:@"value1"];
return self;
Expand Down Expand Up @@ -144,6 +144,9 @@ - (void)encodeWithCoder:(NSCoder *)aCoder
};

@interface Pin ()
{
PinInStock _inStock;
}
@property (nonatomic, assign, readwrite) struct PinDirtyProperties pinDirtyProperties;
@end

Expand Down Expand Up @@ -301,7 +304,7 @@ - (instancetype)initWithModelDictionary:(NS_VALID_UNTIL_END_OF_SCOPE NSDictionar
__unsafe_unretained id value = modelDictionary[@"in_stock"]; // Collection will retain.
if (value != nil) {
if (value != (id)kCFNull) {
self->_inStock = [value integerValue];
self->_inStock = (PinInStock)[value integerValue];
}
self->_pinDirtyProperties.PinDirtyPropertyInStock = 1;
}
Expand Down Expand Up @@ -786,7 +789,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder
_descriptionText = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"description"];
_identifier = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"id"];
_image = [aDecoder decodeObjectOfClass:[Image class] forKey:@"image"];
_inStock = [aDecoder decodeIntegerForKey:@"in_stock"];
_inStock = (PinInStock)[aDecoder decodeIntegerForKey:@"in_stock"];
_link = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"link"];
_media = [aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class]]] forKey:@"media"];
_note = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"note"];
Expand Down
5 changes: 4 additions & 1 deletion Examples/Cocoa/Sources/Objective_C/User.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
};

@interface User ()
{
UserEmailFrequency _emailFrequency;
}
@property (nonatomic, assign, readwrite) struct UserDirtyProperties userDirtyProperties;
@end

Expand Down Expand Up @@ -440,7 +443,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder
_bio = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"bio"];
_counts = [aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSNumber class]]] forKey:@"counts"];
_createdAt = [aDecoder decodeObjectOfClass:[NSDate class] forKey:@"created_at"];
_emailFrequency = [aDecoder decodeIntegerForKey:@"email_frequency"];
_emailFrequency = (UserEmailFrequency)[aDecoder decodeIntegerForKey:@"email_frequency"];
_firstName = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"first_name"];
_identifier = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"id"];
_image = [aDecoder decodeObjectOfClass:[Image class] forKey:@"image"];
Expand Down
64 changes: 57 additions & 7 deletions Examples/Cocoa/Sources/Objective_C/include/Everything.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, EverythingMapPolymorphicValuesInternalType) {
typedef NS_ENUM(unsigned char, EverythingMapPolymorphicValuesInternalType) {
EverythingMapPolymorphicValuesInternalTypeUser = 1,
EverythingMapPolymorphicValuesInternalTypeBoard = 2,
EverythingMapPolymorphicValuesInternalTypeImage = 3,
Expand Down Expand Up @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, EverythingPolymorphicPropInternalType) {
typedef NS_ENUM(unsigned char, EverythingPolymorphicPropInternalType) {
EverythingPolymorphicPropInternalTypeUser = 1,
EverythingPolymorphicPropInternalTypeBoard = 2,
EverythingPolymorphicPropInternalTypeImage = 3,
Expand Down Expand Up @@ -81,18 +81,47 @@ typedef NS_ENUM(NSInteger, EverythingPolymorphicPropInternalType) {

NS_ASSUME_NONNULL_END

typedef NS_ENUM(NSInteger, EverythingIntEnum) {
EverythingIntEnumIntCase1 = 1,
EverythingIntEnumIntCase2 = 2,
EverythingIntEnumIntCase3 = 3
typedef NS_ENUM(char, EverythingCharEnum) {
EverythingCharEnumCharCase1 = -1
};

typedef NS_ENUM(NSInteger, EverythingStringEnum) {
typedef NS_ENUM(int, EverythingIntEnum) {
EverythingIntEnumIntCase1 = -1,
EverythingIntEnumIntCase2 = 65536
};

typedef NS_ENUM(NSInteger, EverythingNsintegerEnum) {
EverythingNsintegerEnumNsintegerCase1 = -1,
EverythingNsintegerEnumNsintegerCase2 = 4294967295
};

typedef NS_ENUM(NSUInteger, EverythingNsuintegerEnum) {
EverythingNsuintegerEnumNsuintegerCase2 = 4294967296
};

typedef NS_ENUM(short, EverythingShortEnum) {
EverythingShortEnumShortCase1 = -1,
EverythingShortEnumShortCase2 = 256
};

typedef NS_ENUM(unsigned char, EverythingStringEnum) {
EverythingStringEnumCase1 /* case1 */,
EverythingStringEnumCase2 /* case2 */,
EverythingStringEnumCase3 /* case3 */
};

typedef NS_ENUM(unsigned char, EverythingUnsignedCharEnum) {
EverythingUnsignedCharEnumUnsignedCharCase2 = 255
};

typedef NS_ENUM(unsigned int, EverythingUnsignedIntEnum) {
EverythingUnsignedIntEnumUnsignedIntCase2 = 65536
};

typedef NS_ENUM(unsigned short, EverythingUnsignedShortEnum) {
EverythingUnsignedShortEnumCharCase2 = 256
};

extern NSString * _Nonnull EverythingStringEnumToString(EverythingStringEnum enumType);

extern EverythingStringEnum EverythingStringEnumFromString(NSString * _Nonnull str);
Expand All @@ -102,6 +131,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface Everything : NSObject<NSCopying, NSSecureCoding>
@property (nullable, nonatomic, strong, readonly) NSArray * arrayProp;
@property (nonatomic, assign, readonly) BOOL booleanProp;
@property (nonatomic, assign, readonly) EverythingCharEnum charEnum;
@property (nullable, nonatomic, copy, readonly) NSDate * dateProp;
@property (nonatomic, assign, readonly) EverythingIntEnum intEnum;
@property (nonatomic, assign, readonly) NSInteger intProp;
Expand All @@ -118,16 +148,22 @@ NS_ASSUME_NONNULL_BEGIN
@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, NSString *> * mapWithObjectValues;
@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, User *> * mapWithOtherModelValues;
@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, NSNumber /* Integer */ *> * mapWithPrimitiveValues;
@property (nonatomic, assign, readonly) EverythingNsintegerEnum nsintegerEnum;
@property (nonatomic, assign, readonly) EverythingNsuintegerEnum nsuintegerEnum;
@property (nonatomic, assign, readonly) double numberProp;
@property (nullable, nonatomic, strong, readonly) User * otherModelProp;
@property (nullable, nonatomic, strong, readonly) EverythingPolymorphicProp * polymorphicProp;
@property (nullable, nonatomic, strong, readonly) NSSet * setProp;
@property (nullable, nonatomic, strong, readonly) NSSet<User *> * setPropWithOtherModelValues;
@property (nullable, nonatomic, strong, readonly) NSSet<NSNumber /*> Integer */ *> * setPropWithPrimitiveValues;
@property (nullable, nonatomic, strong, readonly) NSSet<NSString *> * setPropWithValues;
@property (nonatomic, assign, readonly) EverythingShortEnum shortEnum;
@property (nonatomic, assign, readonly) EverythingStringEnum stringEnum;
@property (nullable, nonatomic, copy, readonly) NSString * stringProp;
@property (nullable, nonatomic, copy, readonly) NSString * type;
@property (nonatomic, assign, readonly) EverythingUnsignedCharEnum unsignedCharEnum;
@property (nonatomic, assign, readonly) EverythingUnsignedIntEnum unsignedIntEnum;
@property (nonatomic, assign, readonly) EverythingUnsignedShortEnum unsignedShortEnum;
@property (nullable, nonatomic, copy, readonly) NSURL * uriProp;

+ (NSString *)className;
Expand All @@ -143,6 +179,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSDictionary *)dictionaryObjectRepresentation;
- (BOOL)isArrayPropSet;
- (BOOL)isBooleanPropSet;
- (BOOL)isCharEnumSet;
- (BOOL)isDatePropSet;
- (BOOL)isIntEnumSet;
- (BOOL)isIntPropSet;
Expand All @@ -159,22 +196,29 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)isMapWithObjectValuesSet;
- (BOOL)isMapWithOtherModelValuesSet;
- (BOOL)isMapWithPrimitiveValuesSet;
- (BOOL)isNsintegerEnumSet;
- (BOOL)isNsuintegerEnumSet;
- (BOOL)isNumberPropSet;
- (BOOL)isOtherModelPropSet;
- (BOOL)isPolymorphicPropSet;
- (BOOL)isSetPropSet;
- (BOOL)isSetPropWithOtherModelValuesSet;
- (BOOL)isSetPropWithPrimitiveValuesSet;
- (BOOL)isSetPropWithValuesSet;
- (BOOL)isShortEnumSet;
- (BOOL)isStringEnumSet;
- (BOOL)isStringPropSet;
- (BOOL)isTypeSet;
- (BOOL)isUnsignedCharEnumSet;
- (BOOL)isUnsignedIntEnumSet;
- (BOOL)isUnsignedShortEnumSet;
- (BOOL)isUriPropSet;
@end

@interface EverythingBuilder : NSObject
@property (nullable, nonatomic, strong, readwrite) NSArray * arrayProp;
@property (nonatomic, assign, readwrite) BOOL booleanProp;
@property (nonatomic, assign, readwrite) EverythingCharEnum charEnum;
@property (nullable, nonatomic, copy, readwrite) NSDate * dateProp;
@property (nonatomic, assign, readwrite) EverythingIntEnum intEnum;
@property (nonatomic, assign, readwrite) NSInteger intProp;
Expand All @@ -191,16 +235,22 @@ NS_ASSUME_NONNULL_BEGIN
@property (nullable, nonatomic, strong, readwrite) NSDictionary<NSString *, NSString *> * mapWithObjectValues;
@property (nullable, nonatomic, strong, readwrite) NSDictionary<NSString *, User *> * mapWithOtherModelValues;
@property (nullable, nonatomic, strong, readwrite) NSDictionary<NSString *, NSNumber /* Integer */ *> * mapWithPrimitiveValues;
@property (nonatomic, assign, readwrite) EverythingNsintegerEnum nsintegerEnum;
@property (nonatomic, assign, readwrite) EverythingNsuintegerEnum nsuintegerEnum;
@property (nonatomic, assign, readwrite) double numberProp;
@property (nullable, nonatomic, strong, readwrite) User * otherModelProp;
@property (nullable, nonatomic, strong, readwrite) EverythingPolymorphicProp * polymorphicProp;
@property (nullable, nonatomic, strong, readwrite) NSSet * setProp;
@property (nullable, nonatomic, strong, readwrite) NSSet<User *> * setPropWithOtherModelValues;
@property (nullable, nonatomic, strong, readwrite) NSSet<NSNumber /*> Integer */ *> * setPropWithPrimitiveValues;
@property (nullable, nonatomic, strong, readwrite) NSSet<NSString *> * setPropWithValues;
@property (nonatomic, assign, readwrite) EverythingShortEnum shortEnum;
@property (nonatomic, assign, readwrite) EverythingStringEnum stringEnum;
@property (nullable, nonatomic, copy, readwrite) NSString * stringProp;
@property (nullable, nonatomic, copy, readwrite) NSString * type;
@property (nonatomic, assign, readwrite) EverythingUnsignedCharEnum unsignedCharEnum;
@property (nonatomic, assign, readwrite) EverythingUnsignedIntEnum unsignedIntEnum;
@property (nonatomic, assign, readwrite) EverythingUnsignedShortEnum unsignedShortEnum;
@property (nullable, nonatomic, copy, readwrite) NSURL * uriProp;

- (instancetype)initWithModel:(Everything *)modelObject;
Expand Down
4 changes: 2 additions & 2 deletions Examples/Cocoa/Sources/Objective_C/include/Pin.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, PinAttributionObjectsInternalType) {
typedef NS_ENUM(unsigned char, PinAttributionObjectsInternalType) {
PinAttributionObjectsInternalTypeBoard = 1,
PinAttributionObjectsInternalTypeUser = 2
};
Expand All @@ -32,7 +32,7 @@ typedef NS_ENUM(NSInteger, PinAttributionObjectsInternalType) {

NS_ASSUME_NONNULL_END

typedef NS_ENUM(NSInteger, PinInStock) {
typedef NS_ENUM(char, PinInStock) {
PinInStockUnknown = -1,
PinInStockOutOfStock = 0,
PinInStockInStock = 1
Expand Down
2 changes: 1 addition & 1 deletion Examples/Cocoa/Sources/Objective_C/include/User.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@class Image;
@class UserBuilder;

typedef NS_ENUM(NSInteger, UserEmailFrequency) {
typedef NS_ENUM(unsigned char, UserEmailFrequency) {
UserEmailFrequencyUnset /* unset */,
UserEmailFrequencyImmediate /* immediate */,
UserEmailFrequencyDaily /* daily */
Expand Down
51 changes: 50 additions & 1 deletion Examples/Cocoa/Tests/Objective_CTests/ObjcTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,58 @@ class ObjcDictionaryRepresentationTestSuite: XCTestCase {
assertDictionaryRepresentation(dict)
}

func testCharEnum() {
let dict: JSONDict = [
"char_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testUnsignedCharEnum() {
let dict: JSONDict = [
"unsigned_char_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testShortEnum() {
let dict: JSONDict = [
"short_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testUnsignedShortEnum() {
let dict: JSONDict = [
"unsigned_short_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testIntEnum() {
let dict: JSONDict = [
"int_enum": 2,
"int_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testUnsignedIntEnum() {
let dict: JSONDict = [
"unsigned_int_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testNSIntegerEnum() {
let dict: JSONDict = [
"nsinteger_enum": 0,
]
assertDictionaryRepresentation(dict)
}

func testNSUIntegerEnum() {
let dict: JSONDict = [
"nsuinteger_enum": 0,
]
assertDictionaryRepresentation(dict)
}
Expand Down
42 changes: 39 additions & 3 deletions Examples/JS/flow/EverythingType.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,27 @@ export type EverythingMapPolymorphicValuesType = UserType | BoardType | ImageTyp

export type EverythingPolymorphicPropType = UserType | BoardType | ImageType | PinType | EverythingType | string | boolean | number | number | PlankDate | PlankURI;

export type EverythingCharEnum =
| -1 /* char_case_1 */
;

export type EverythingIntEnum =
| 1 /* int_case_1 */
| 2 /* int_case_2 */
| 3 /* int_case_3 */
| -1 /* int_case_1 */
| 65536 /* int_case_2 */
;

export type EverythingNsintegerEnum =
| -1 /* nsinteger_case_1 */
| 4294967295 /* nsinteger_case_2 */
;

export type EverythingNsuintegerEnum =
| 4294967296 /* nsuinteger_case_2 */
;

export type EverythingShortEnum =
| -1 /* short_case_1 */
| 256 /* short_case_2 */
;

export type EverythingStringEnum =
Expand All @@ -29,9 +46,22 @@ export type EverythingStringEnum =
| 'case3'
;

export type EverythingUnsignedCharEnum =
| 255 /* unsigned_char_case_2 */
;

export type EverythingUnsignedIntEnum =
| 65536 /* unsigned_int_case_2 */
;

export type EverythingUnsignedShortEnum =
| 256 /* char_case_2 */
;

export type EverythingType = $Shape<{|
+array_prop: ?Array<*>,
+boolean_prop: boolean,
+char_enum: EverythingCharEnum,
+date_prop: ?PlankDate,
+int_enum: EverythingIntEnum,
+int_prop: number,
Expand All @@ -48,16 +78,22 @@ export type EverythingType = $Shape<{|
+map_with_object_values: ?{ +[string]: string },
+map_with_other_model_values: ?{ +[string]: UserType },
+map_with_primitive_values: ?{ +[string]: number } /* Integer */,
+nsinteger_enum: EverythingNsintegerEnum,
+nsuinteger_enum: EverythingNsuintegerEnum,
+number_prop: number,
+other_model_prop: ?UserType,
+polymorphic_prop: ?EverythingPolymorphicPropType,
+set_prop: ?Array<*>,
+set_prop_with_other_model_values: ?Array<UserType>,
+set_prop_with_primitive_values: ?Array<number /* Integer> */>,
+set_prop_with_values: ?Array<string>,
+short_enum: EverythingShortEnum,
+string_enum: EverythingStringEnum,
+string_prop: ?string,
+type: ?string,
+unsigned_char_enum: EverythingUnsignedCharEnum,
+unsigned_int_enum: EverythingUnsignedIntEnum,
+unsigned_short_enum: EverythingUnsignedShortEnum,
+uri_prop: ?PlankURI,
|}> & {
id: string
Expand Down
Loading

0 comments on commit d3c6322

Please sign in to comment.