From 3deecff55a3d83ad91c16d6ad9c0ac0084bb6671 Mon Sep 17 00:00:00 2001 From: Markus Emrich Date: Wed, 14 Aug 2019 12:20:36 -0700 Subject: [PATCH] Update remodel iglistdiffable plugin to the latest Summary: Remodel changed quite a bit, this updates the plugin to work correctly with the latest state. It also includes other recent Remodel changes like e.g. autoformatting of the codebase. Resolves #1353 Reviewed By: natestedman Differential Revision: D16794236 fbshipit-source-id: f543d0e3e5656f540accd5e359bbaf0acc8071fc --- .../features/iglistdiffable.feature | 226 +++-------------- .../__tests__/plugins/iglistdiffable-test.ts | 234 ++++++++++-------- .../src/plugins/iglistdiffable-utils.ts | 230 +++++++++-------- remodel-plugin/src/plugins/iglistdiffable.ts | 138 +++++++---- 4 files changed, 381 insertions(+), 447 deletions(-) diff --git a/remodel-plugin/features/iglistdiffable.feature b/remodel-plugin/features/iglistdiffable.feature index 5f1358c5..68812190 100644 --- a/remodel-plugin/features/iglistdiffable.feature +++ b/remodel-plugin/features/iglistdiffable.feature @@ -4,22 +4,22 @@ Feature: Outputting Value Objects implementing IGListDiffable @announce Scenario: Generating a value object, which correctly implements IGListDiffable using the specified diffIdentifier - Given a file named "project/values/Test.value" with: + Given a file named "project/values/IGListDiffableTest.value" with: """ - Test includes(IGListDiffable) { + IGListDiffableTest includes(IGListDiffable) { CGRect someRect - %diffIdentifier - NSString *stringOne + %diffIdentifier NSString *stringOne } """ When I run `../../bin/generate project` - Then the file "project/values/Test.h" should contain: + Then the file "project/values/IGListDiffableTest.h" should contain: """ + #import #import #import - @interface Test : NSObject + @interface IGListDiffableTest : NSObject @property (nonatomic, readonly) CGRect someRect; @property (nonatomic, readonly, copy) NSString *stringOne; @@ -33,89 +33,37 @@ Feature: Outputting Value Objects implementing IGListDiffable @end """ - And the file "project/values/Test.m" should contain: + And the file "project/values/IGListDiffableTest.m" should contain: """ - @implementation Test - - - (instancetype)initWithSomeRect:(CGRect)someRect stringOne:(NSString *)stringOne - { - if ((self = [super init])) { - _someRect = someRect; - _stringOne = [stringOne copy]; - } - - return self; - } - - - (id)copyWithZone:(nullable NSZone *)zone - { - return self; - } - - - (NSString *)description - { - return [NSString stringWithFormat:@"%@ - \n\t someRect: %@; \n\t stringOne: %@; \n", [super description], NSStringFromCGRect(_someRect), _stringOne]; - } - - (id)diffIdentifier { return _stringOne; } - - - (NSUInteger)hash - { - NSUInteger subhashes[] = {HashCGFloat(_someRect.origin.x), HashCGFloat(_someRect.origin.y), HashCGFloat(_someRect.size.width), HashCGFloat(_someRect.size.height), [_stringOne hash]}; - NSUInteger result = subhashes[0]; - for (int ii = 1; ii < 5; ++ii) { - unsigned long long base = (((unsigned long long)result) << 32 | subhashes[ii]); - base = (~base) + (base << 18); - base ^= (base >> 31); - base *= 21; - base ^= (base >> 11); - base += (base << 6); - base ^= (base >> 22); - result = base; - } - return result; - } - - - (BOOL)isEqual:(Test *)object - { - if (self == object) { - return YES; - } else if (object == nil || ![object isKindOfClass:[self class]]) { - return NO; - } - return - CGRectEqualToRect(_someRect, object->_someRect) && - (_stringOne == object->_stringOne ? YES : [_stringOne isEqual:object->_stringOne]); - } - + """ + And the file "project/values/IGListDiffableTest.m" should contain: + """ - (BOOL)isEqualToDiffableObject:(nullable id)object { return [self isEqual:object]; } - - @end - """ Scenario: Generating a value object, which correctly implements IGListDiffable using a CGRect property - Given a file named "project/values/Test.value" with: + Given a file named "project/values/IGListDiffableTest2.value" with: """ - Test includes(IGListDiffable) { - %diffIdentifier - CGRect someRect + IGListDiffableTest2 includes(IGListDiffable) { + %diffIdentifier CGRect someRect } """ When I run `../../bin/generate project` - Then the file "project/values/Test.h" should contain: + Then the file "project/values/IGListDiffableTest2.h" should contain: """ + #import #import #import - @interface Test : NSObject + @interface IGListDiffableTest2 : NSObject @property (nonatomic, readonly) CGRect someRect; @@ -126,106 +74,60 @@ Feature: Outputting Value Objects implementing IGListDiffable - (instancetype)initWithSomeRect:(CGRect)someRect NS_DESIGNATED_INITIALIZER; @end - """ - And the file "project/values/Test.m" should contain: + And the file "project/values/IGListDiffableTest2.m" should contain: """ - @implementation Test - - - (instancetype)initWithSomeRect:(CGRect)someRect - { - if ((self = [super init])) { - _someRect = someRect; - } - - return self; - } - - - (id)copyWithZone:(nullable NSZone *)zone - { - return self; - } - - - (NSString *)description - { - return [NSString stringWithFormat:@"%@ - \n\t someRect: %@; \n", [super description], NSStringFromCGRect(_someRect)]; - } - - (id)diffIdentifier { return [NSValue valueWithCGRect:_someRect]; } - - - (NSUInteger)hash - { - NSUInteger subhashes[] = {HashCGFloat(_someRect.origin.x), HashCGFloat(_someRect.origin.y), HashCGFloat(_someRect.size.width), HashCGFloat(_someRect.size.height)}; - NSUInteger result = subhashes[0]; - for (int ii = 1; ii < 4; ++ii) { - unsigned long long base = (((unsigned long long)result) << 32 | subhashes[ii]); - base = (~base) + (base << 18); - base ^= (base >> 31); - base *= 21; - base ^= (base >> 11); - base += (base << 6); - base ^= (base >> 22); - result = base; - } - return result; - } - - - (BOOL)isEqual:(Test *)object - { - if (self == object) { - return YES; - } else if (object == nil || ![object isKindOfClass:[self class]]) { - return NO; - } - return - CGRectEqualToRect(_someRect, object->_someRect); - } - + """ + And the file "project/values/IGListDiffableTest2.m" should contain: + """ - (BOOL)isEqualToDiffableObject:(nullable id)object { return [self isEqual:object]; } - - @end - """ Scenario: Generating a value object, which correctly implements IGListDiffable using an NSInteger property - Given a file named "project/values/Test.value" with: + Given a file named "project/values/IGListDiffableTest3.value" with: """ - Test includes(IGListDiffable) { - %diffIdentifier - NSInteger count + IGListDiffableTest3 includes(IGListDiffable) { + %diffIdentifier NSInteger count } """ When I run `../../bin/generate project` - Then the file "project/values/Test.m" should contain: + Then the file "project/values/IGListDiffableTest3.m" should contain: """ - (id)diffIdentifier { return @(_count); } - + """ + And the file "project/values/IGListDiffableTest3.m" should contain: + """ + - (BOOL)isEqualToDiffableObject:(nullable id)object + { + return [self isEqual:object]; + } """ Scenario: Generating a value object, which correctly implements IGListDiffable defaulting to self as diffIdentifier - Given a file named "project/values/Test.value" with: + Given a file named "project/values/IGListDiffableTest4.value" with: """ - Test includes(IGListDiffable) { + IGListDiffableTest4 includes(IGListDiffable) { CGRect someRect } """ When I run `../../bin/generate project` - Then the file "project/values/Test.h" should contain: + Then the file "project/values/IGListDiffableTest4.h" should contain: """ #import #import #import - @interface Test : NSObject + @interface IGListDiffableTest4 : NSObject @property (nonatomic, readonly) CGRect someRect; @@ -238,67 +140,17 @@ Feature: Outputting Value Objects implementing IGListDiffable @end """ - And the file "project/values/Test.m" should contain: + And the file "project/values/IGListDiffableTest4.m" should contain: """ - @implementation Test - - - (instancetype)initWithSomeRect:(CGRect)someRect - { - if ((self = [super init])) { - _someRect = someRect; - } - - return self; - } - - - (id)copyWithZone:(nullable NSZone *)zone - { - return self; - } - - - (NSString *)description - { - return [NSString stringWithFormat:@"%@ - \n\t someRect: %@; \n", [super description], NSStringFromCGRect(_someRect)]; - } - - (id)diffIdentifier { return self; } - - - (NSUInteger)hash - { - NSUInteger subhashes[] = {HashCGFloat(_someRect.origin.x), HashCGFloat(_someRect.origin.y), HashCGFloat(_someRect.size.width), HashCGFloat(_someRect.size.height)}; - NSUInteger result = subhashes[0]; - for (int ii = 1; ii < 4; ++ii) { - unsigned long long base = (((unsigned long long)result) << 32 | subhashes[ii]); - base = (~base) + (base << 18); - base ^= (base >> 31); - base *= 21; - base ^= (base >> 11); - base += (base << 6); - base ^= (base >> 22); - result = base; - } - return result; - } - - - (BOOL)isEqual:(Test *)object - { - if (self == object) { - return YES; - } else if (object == nil || ![object isKindOfClass:[self class]]) { - return NO; - } - return - CGRectEqualToRect(_someRect, object->_someRect); - } - + """ + And the file "project/values/IGListDiffableTest4.m" should contain: + """ - (BOOL)isEqualToDiffableObject:(nullable id)object { return [self isEqual:object]; } - - @end - """ diff --git a/remodel-plugin/src/__tests__/plugins/iglistdiffable-test.ts b/remodel-plugin/src/__tests__/plugins/iglistdiffable-test.ts index 20d4c930..e962a81e 100644 --- a/remodel-plugin/src/__tests__/plugins/iglistdiffable-test.ts +++ b/remodel-plugin/src/__tests__/plugins/iglistdiffable-test.ts @@ -8,22 +8,22 @@ /// /// -import IGListDiffable = require('../../plugins/iglistdiffable'); -import Error = require('../../error'); -import Maybe = require('../../maybe'); -import ObjC = require('../../objc'); -import ObjectSpec = require('../../object-spec'); -import ObjectGeneration = require('../../object-generation'); +import * as IGListDiffable from '../../plugins/iglistdiffable'; +import * as Error from '../../error'; +import * as Maybe from '../../maybe'; +import * as ObjC from '../../objc'; +import * as ObjectSpec from '../../object-spec'; +import * as ObjectGeneration from '../../object-generation'; const ObjectSpecPlugin = IGListDiffable.createPlugin(); -function igListDiffableIsEqualMethod():ObjC.Method { +function igListDiffableIsEqualMethod(): ObjC.Method { return { - preprocessors:[], - belongsToProtocol:Maybe.Just('IGListDiffable'), + preprocessors: [], + belongsToProtocol: Maybe.Just('IGListDiffable'), code: ['return [self isEqual:object];'], - comments:[], - compilerAttributes:[], + comments: [], + compilerAttributes: [], keywords: [ { name: 'isEqualToDiffableObject', @@ -32,234 +32,250 @@ function igListDiffableIsEqualMethod():ObjC.Method { modifiers: [ObjC.KeywordArgumentModifier.Nullable()], type: { name: 'id', - reference: 'id' - } - }) - } + reference: 'id', + }, + }), + }, ], - returnType: { type:Maybe.Just({ - name: 'BOOL', - reference: 'BOOL' - }), modifiers: [] } - } + returnType: { + type: Maybe.Just({ + name: 'BOOL', + reference: 'BOOL', + }), + modifiers: [], + }, + }; } -function igListDiffableDiffIdentifierMethodWithCode(code:string):ObjC.Method { +function igListDiffableDiffIdentifierMethodWithCode(code: string): ObjC.Method { return { - preprocessors:[], - belongsToProtocol:Maybe.Just('IGListDiffable'), + preprocessors: [], + belongsToProtocol: Maybe.Just('IGListDiffable'), code: [code], - comments:[], - compilerAttributes:[], + comments: [], + compilerAttributes: [], keywords: [ { name: 'diffIdentifier', - argument: Maybe.Nothing() - } + argument: Maybe.Nothing(), + }, ], - returnType: { type:Maybe.Just({ - name: 'NSObject', - reference: 'id' - }), modifiers: [] } - } + returnType: { + type: Maybe.Just({ + name: 'NSObject', + reference: 'id', + }), + modifiers: [], + }, + }; } describe('ObjectSpecPlugins.IGListDiffable', function() { describe('Value Object', function() { describe('#instanceMethods', function() { - it('returns two instance methods and uses self as diffIdentifier with no input attributes', function() { - const objectType:ObjectSpec.Type = { - annotations: {}, - attributes: [], - comments: [], - excludes: [], - includes: [], - libraryName: Maybe.Nothing(), - typeLookups:[], - typeName: 'Foo' - }; + const objectType: ObjectSpec.Type = { + annotations: {}, + attributes: [], + comments: [], + excludes: [], + includes: [], + libraryName: Maybe.Nothing(), + typeLookups: [], + typeName: 'Foo', + }; - const instanceMethods:ObjC.Method[] = ObjectSpecPlugin.instanceMethods(objectType); + const instanceMethods: ObjC.Method[] = ObjectSpecPlugin.instanceMethods( + objectType, + ); - const expectedInstanceMethods:ObjC.Method[] = [ + const expectedInstanceMethods: ObjC.Method[] = [ igListDiffableIsEqualMethod(), - igListDiffableDiffIdentifierMethodWithCode('return self;') + igListDiffableDiffIdentifierMethodWithCode('return self;'), ]; expect(instanceMethods).toEqualJSON(expectedInstanceMethods); }); it('returns NSObjects directly as diffIdentifier', function() { - const objectType:ObjectSpec.Type = { + const objectType: ObjectSpec.Type = { annotations: {}, attributes: [ { annotations: { - diffIdentifier: [] + diffIdentifier: [], }, comments: [], name: 'name', - nullability:ObjC.Nullability.Inherited(), + nullability: ObjC.Nullability.Inherited(), type: { - fileTypeIsDefinedIn:Maybe.Nothing(), - libraryTypeIsDefinedIn:Maybe.Nothing(), + fileTypeIsDefinedIn: Maybe.Nothing(), + libraryTypeIsDefinedIn: Maybe.Nothing(), name: 'NSString', reference: 'NSString *', - underlyingType:Maybe.Just('NSObject'), - conformingProtocol: Maybe.Nothing() - } - } + underlyingType: Maybe.Just('NSObject'), + conformingProtocol: Maybe.Nothing(), + }, + }, ], comments: [], excludes: [], includes: [], libraryName: Maybe.Nothing(), - typeLookups:[], - typeName: 'Foo' + typeLookups: [], + typeName: 'Foo', }; - const instanceMethods:ObjC.Method[] = ObjectSpecPlugin.instanceMethods(objectType); + const instanceMethods: ObjC.Method[] = ObjectSpecPlugin.instanceMethods( + objectType, + ); - const expectedInstanceMethods:ObjC.Method[] = [ + const expectedInstanceMethods: ObjC.Method[] = [ igListDiffableIsEqualMethod(), - igListDiffableDiffIdentifierMethodWithCode('return _name;') + igListDiffableDiffIdentifierMethodWithCode('return _name;'), ]; expect(instanceMethods).toEqualJSON(expectedInstanceMethods); }); it('returns NSInteger as formatString as diffIdentifier', function() { - const objectType:ObjectSpec.Type = { + const objectType: ObjectSpec.Type = { annotations: {}, attributes: [ { annotations: { - diffIdentifier: [] + diffIdentifier: [], }, comments: [], name: 'age', - nullability:ObjC.Nullability.Inherited(), + nullability: ObjC.Nullability.Inherited(), type: { - fileTypeIsDefinedIn:Maybe.Nothing(), - libraryTypeIsDefinedIn:Maybe.Nothing(), + fileTypeIsDefinedIn: Maybe.Nothing(), + libraryTypeIsDefinedIn: Maybe.Nothing(), name: 'NSInteger', reference: 'NSInteger', - underlyingType:Maybe.Nothing(), - conformingProtocol: Maybe.Nothing() - } - } + underlyingType: Maybe.Nothing(), + conformingProtocol: Maybe.Nothing(), + }, + }, ], comments: [], excludes: [], includes: [], libraryName: Maybe.Nothing(), - typeLookups:[], - typeName: 'Foo' + typeLookups: [], + typeName: 'Foo', }; - const instanceMethods:ObjC.Method[] = ObjectSpecPlugin.instanceMethods(objectType); + const instanceMethods: ObjC.Method[] = ObjectSpecPlugin.instanceMethods( + objectType, + ); - const expectedInstanceMethods:ObjC.Method[] = [ + const expectedInstanceMethods: ObjC.Method[] = [ igListDiffableIsEqualMethod(), - igListDiffableDiffIdentifierMethodWithCode('return @(_age);') + igListDiffableDiffIdentifierMethodWithCode('return @(_age);'), ]; expect(instanceMethods).toEqualJSON(expectedInstanceMethods); }); it('returns CGRect as string as diffIdentifier', function() { - const objectType:ObjectSpec.Type = { + const objectType: ObjectSpec.Type = { annotations: {}, attributes: [ { annotations: { - diffIdentifier: [] + diffIdentifier: [], }, comments: [], name: 'rect', - nullability:ObjC.Nullability.Inherited(), + nullability: ObjC.Nullability.Inherited(), type: { - fileTypeIsDefinedIn:Maybe.Nothing(), - libraryTypeIsDefinedIn:Maybe.Nothing(), + fileTypeIsDefinedIn: Maybe.Nothing(), + libraryTypeIsDefinedIn: Maybe.Nothing(), name: 'CGRect', reference: 'CGRect', - underlyingType:Maybe.Nothing(), - conformingProtocol: Maybe.Nothing() - } - } + underlyingType: Maybe.Nothing(), + conformingProtocol: Maybe.Nothing(), + }, + }, ], comments: [], excludes: [], includes: [], libraryName: Maybe.Nothing(), - typeLookups:[], - typeName: 'Foo' + typeLookups: [], + typeName: 'Foo', }; - const instanceMethods:ObjC.Method[] = ObjectSpecPlugin.instanceMethods(objectType); + const instanceMethods: ObjC.Method[] = ObjectSpecPlugin.instanceMethods( + objectType, + ); - const expectedInstanceMethods:ObjC.Method[] = [ + const expectedInstanceMethods: ObjC.Method[] = [ igListDiffableIsEqualMethod(), - igListDiffableDiffIdentifierMethodWithCode('return [NSValue valueWithCGRect:_rect];') + igListDiffableDiffIdentifierMethodWithCode( + 'return [NSValue valueWithCGRect:_rect];', + ), ]; expect(instanceMethods).toEqualJSON(expectedInstanceMethods); }); it('returns property marked with %diffIdentifier as diffIdentifier', function() { - const objectType:ObjectSpec.Type = { + const objectType: ObjectSpec.Type = { annotations: {}, attributes: [ { annotations: {}, comments: [], name: 'name', - nullability:ObjC.Nullability.Inherited(), + nullability: ObjC.Nullability.Inherited(), type: { - fileTypeIsDefinedIn:Maybe.Nothing(), - libraryTypeIsDefinedIn:Maybe.Nothing(), + fileTypeIsDefinedIn: Maybe.Nothing(), + libraryTypeIsDefinedIn: Maybe.Nothing(), name: 'NSString', reference: 'NSString *', - underlyingType:Maybe.Just('NSObject'), - conformingProtocol: Maybe.Nothing() - } + underlyingType: Maybe.Just('NSObject'), + conformingProtocol: Maybe.Nothing(), + }, }, { annotations: { - diffIdentifier: [] + diffIdentifier: [], }, comments: [], name: 'age', - nullability:ObjC.Nullability.Inherited(), + nullability: ObjC.Nullability.Inherited(), type: { - fileTypeIsDefinedIn:Maybe.Nothing(), - libraryTypeIsDefinedIn:Maybe.Nothing(), + fileTypeIsDefinedIn: Maybe.Nothing(), + libraryTypeIsDefinedIn: Maybe.Nothing(), name: 'NSInteger', reference: 'NSInteger', - underlyingType:Maybe.Nothing(), - conformingProtocol: Maybe.Nothing() - } - } + underlyingType: Maybe.Nothing(), + conformingProtocol: Maybe.Nothing(), + }, + }, ], comments: [], excludes: [], includes: [], libraryName: Maybe.Nothing(), - typeLookups:[], - typeName: 'Foo' + typeLookups: [], + typeName: 'Foo', }; - const instanceMethods:ObjC.Method[] = ObjectSpecPlugin.instanceMethods(objectType); + const instanceMethods: ObjC.Method[] = ObjectSpecPlugin.instanceMethods( + objectType, + ); - const expectedInstanceMethods:ObjC.Method[] = [ + const expectedInstanceMethods: ObjC.Method[] = [ igListDiffableIsEqualMethod(), - igListDiffableDiffIdentifierMethodWithCode('return @(_age);') + igListDiffableDiffIdentifierMethodWithCode('return @(_age);'), ]; expect(instanceMethods).toEqualJSON(expectedInstanceMethods); }); - }); }); }); diff --git a/remodel-plugin/src/plugins/iglistdiffable-utils.ts b/remodel-plugin/src/plugins/iglistdiffable-utils.ts index 545fd21f..626be235 100644 --- a/remodel-plugin/src/plugins/iglistdiffable-utils.ts +++ b/remodel-plugin/src/plugins/iglistdiffable-utils.ts @@ -5,19 +5,19 @@ * LICENSE file in the root directory of this source tree. */ -import Maybe = require('../maybe'); -import ObjC = require('../objc'); -import ObjCTypeUtils = require('../objc-type-utils'); -import ObjectSpec = require('../object-spec'); -import ObjectSpecCodeUtils = require('../object-spec-code-utils'); +import * as Maybe from '../maybe'; +import * as ObjC from '../objc'; +import * as ObjCTypeUtils from '../objc-type-utils'; +import * as ObjectSpec from '../object-spec'; +import * as ObjectSpecCodeUtils from '../object-spec-code-utils'; -function isEqualToDiffableObjectMethod():ObjC.Method { +function isEqualToDiffableObjectMethod(): ObjC.Method { return { - preprocessors:[], - belongsToProtocol:Maybe.Just('IGListDiffable'), + preprocessors: [], + belongsToProtocol: Maybe.Just('IGListDiffable'), code: ['return [self isEqual:object];'], - comments:[], - compilerAttributes:[], + comments: [], + compilerAttributes: [], keywords: [ { name: 'isEqualToDiffableObject', @@ -26,110 +26,142 @@ function isEqualToDiffableObjectMethod():ObjC.Method { modifiers: [ObjC.KeywordArgumentModifier.Nullable()], type: { name: 'id', - reference: 'id' - } - }) - } + reference: 'id', + }, + }), + }, ], - returnType: { type: Maybe.Just({ - name: 'BOOL', - reference: 'BOOL' - }), modifiers: [] } - } + returnType: { + type: Maybe.Just({ + name: 'BOOL', + reference: 'BOOL', + }), + modifiers: [], + }, + }; } -function functionReturnValueForIvarWithFunctionName(iVarString:string, functionToCall:string):string { +function functionReturnValueForIvarWithFunctionName( + iVarString: string, + functionToCall: string, +): string { return functionToCall + '(' + iVarString + ')'; } -function formattedStringValueForIvarWithFormatSpecifier(iVarString:string, stringFormatSpecifier:string, optionalCast:string=null):string { - var castString:string = (optionalCast === null ? "" : "(" + optionalCast + ")"); - return "[NSString stringWithFormat:@\"" + stringFormatSpecifier + "\", " + castString + iVarString + "]"; +function formattedStringValueForIvarWithFormatSpecifier( + iVarString: string, + stringFormatSpecifier: string, + optionalCast: string = null, +): string { + var castString: string = + optionalCast === null ? '' : '(' + optionalCast + ')'; + return ( + '[NSString stringWithFormat:@"' + + stringFormatSpecifier + + '", ' + + castString + + iVarString + + ']' + ); } -function nullableObjectValueWithFallback(objectValue:string, optionalFallback:string=null) { - return (optionalFallback === null) ? objectValue : `${objectValue} ?: ${optionalFallback}`; +function nullableObjectValueWithFallback( + objectValue: string, + optionalFallback: string = null, +) { + return optionalFallback === null + ? objectValue + : `${objectValue} ?: ${optionalFallback}`; } -function wrappedInNSValueForTypeName(iVarString:string, typeName:string) { +function wrappedInNSValueForTypeName(iVarString: string, typeName: string) { return `[NSValue valueWith${typeName}:${iVarString}]`; } -function objectValueForAttribute(attribute:ObjectSpec.Attribute, optionalFallback:string=null):string { - const iVarString:string = ObjectSpecCodeUtils.ivarForAttribute(attribute); - const type:ObjC.Type = ObjectSpecCodeUtils.computeTypeOfAttribute(attribute); +function objectValueForAttribute( + attribute: ObjectSpec.Attribute, + optionalFallback: string = null, +): string { + const iVarString: string = ObjectSpecCodeUtils.ivarForAttribute(attribute); + const type: ObjC.Type = ObjectSpecCodeUtils.computeTypeOfAttribute(attribute); - return ObjCTypeUtils.matchType({ - id: function() { - return formattedStringValueForIvarWithFormatSpecifier(iVarString, "%@"); + return ObjCTypeUtils.matchType( + { + id: function() { + return formattedStringValueForIvarWithFormatSpecifier(iVarString, '%@'); + }, + NSObject: function() { + return nullableObjectValueWithFallback(iVarString, optionalFallback); + }, + BOOL: function() { + return `@(${iVarString})`; + }, + NSInteger: function() { + return `@(${iVarString})`; + }, + NSUInteger: function() { + return `@(${iVarString})`; + }, + double: function() { + return `@(${iVarString})`; + }, + float: function() { + return `@(${iVarString})`; + }, + CGFloat: function() { + return `@(${iVarString})`; + }, + NSTimeInterval: function() { + return `@(${iVarString})`; + }, + uintptr_t: function() { + return `@(${iVarString})`; + }, + uint32_t: function() { + return `@(${iVarString})`; + }, + uint64_t: function() { + return `@(${iVarString})`; + }, + int32_t: function() { + return `@(${iVarString})`; + }, + int64_t: function() { + return `@(${iVarString})`; + }, + SEL: function() { + return functionReturnValueForIvarWithFunctionName( + iVarString, + 'NSStringFromSelector', + ); + }, + NSRange: function() { + return wrappedInNSValueForTypeName(iVarString, 'Range'); + }, + CGRect: function() { + return wrappedInNSValueForTypeName(iVarString, type.name); + }, + CGPoint: function() { + return wrappedInNSValueForTypeName(iVarString, type.name); + }, + CGSize: function() { + return wrappedInNSValueForTypeName(iVarString, type.name); + }, + UIEdgeInsets: function() { + return wrappedInNSValueForTypeName(iVarString, type.name); + }, + Class: function() { + return formattedStringValueForIvarWithFormatSpecifier(iVarString, '%@'); + }, + dispatch_block_t: function() { + return formattedStringValueForIvarWithFormatSpecifier(iVarString, '%@'); + }, + unmatchedType: function() { + return nullableObjectValueWithFallback('self', optionalFallback); + }, }, - NSObject: function() { - return nullableObjectValueWithFallback(iVarString, optionalFallback); - }, - BOOL: function() { - return `@(${iVarString})`; - }, - NSInteger: function() { - return `@(${iVarString})`; - }, - NSUInteger: function() { - return `@(${iVarString})`; - }, - double: function() { - return `@(${iVarString})`; - }, - float: function() { - return `@(${iVarString})`; - }, - CGFloat: function() { - return `@(${iVarString})`; - }, - NSTimeInterval: function() { - return `@(${iVarString})`; - }, - uintptr_t: function() { - return `@(${iVarString})`; - }, - uint32_t: function() { - return `@(${iVarString})`; - }, - uint64_t: function() { - return `@(${iVarString})`; - }, - int32_t: function() { - return `@(${iVarString})`; - }, - int64_t: function() { - return `@(${iVarString})`; - }, - SEL: function() { - return functionReturnValueForIvarWithFunctionName(iVarString, "NSStringFromSelector"); - }, - NSRange: function() { - return wrappedInNSValueForTypeName(iVarString, 'Range'); - }, - CGRect: function() { - return wrappedInNSValueForTypeName(iVarString, type.name); - }, - CGPoint: function() { - return wrappedInNSValueForTypeName(iVarString, type.name); - }, - CGSize: function() { - return wrappedInNSValueForTypeName(iVarString, type.name); - }, - UIEdgeInsets: function() { - return wrappedInNSValueForTypeName(iVarString, type.name); - }, - Class: function() { - return formattedStringValueForIvarWithFormatSpecifier(iVarString, "%@"); - }, - dispatch_block_t: function() { - return formattedStringValueForIvarWithFormatSpecifier(iVarString, "%@"); - }, - unmatchedType: function() { - return nullableObjectValueWithFallback('self', optionalFallback); - } - }, type); + type, + ); } export {isEqualToDiffableObjectMethod, objectValueForAttribute}; diff --git a/remodel-plugin/src/plugins/iglistdiffable.ts b/remodel-plugin/src/plugins/iglistdiffable.ts index 461c3746..040b0079 100644 --- a/remodel-plugin/src/plugins/iglistdiffable.ts +++ b/remodel-plugin/src/plugins/iglistdiffable.ts @@ -5,113 +5,147 @@ * LICENSE file in the root directory of this source tree. */ -import Code = require('../code'); -import Error = require('../error'); -import FileWriter = require('../file-writer'); -import FunctionUtils = require('../function-utils'); -import IGListDiffableUtils = require ('./iglistdiffable-utils'); -import Maybe = require('../maybe'); -import ObjC = require('../objc'); -import ObjectSpec = require('../object-spec'); -import ObjectSpecUtils = require('../object-spec-utils'); +import * as Code from '../code'; +import * as Error from '../error'; +import * as FileWriter from '../file-writer'; +import * as IGListDiffableUtils from './iglistdiffable-utils'; +import * as Maybe from '../maybe'; +import * as ObjC from '../objc'; +import * as ObjectSpec from '../object-spec'; -function diffIdentiferAttributeFilter(attribute:ObjectSpec.Attribute, index, array):boolean { - return (attribute.annotations["diffIdentifier"] != null); +function diffIdentiferAttributeFilter( + attribute: ObjectSpec.Attribute, + index, + array, +): boolean { + return attribute.annotations['diffIdentifier'] != null; } -function diffIdentifierMethodImplementation(objectType:ObjectSpec.Type):string[] { - const diffIdentifierAttributes:ObjectSpec.Attribute[] = objectType.attributes.filter(diffIdentiferAttributeFilter); +function diffIdentifierMethodImplementation( + objectType: ObjectSpec.Type, +): string[] { + const diffIdentifierAttributes: ObjectSpec.Attribute[] = objectType.attributes.filter( + diffIdentiferAttributeFilter, + ); if (diffIdentifierAttributes.length > 0) { // use first marked attribute as identifier, if available - return ['return ' + IGListDiffableUtils.objectValueForAttribute(diffIdentifierAttributes[0]) + ';'] + return [ + 'return ' + + IGListDiffableUtils.objectValueForAttribute( + diffIdentifierAttributes[0], + ) + + ';', + ]; } else { // fallback/default to self return ['return self;']; } } -function diffIdentifierMethod(objectType:ObjectSpec.Type):ObjC.Method { +function diffIdentifierMethod(objectType: ObjectSpec.Type): ObjC.Method { return { - preprocessors:[], - belongsToProtocol:Maybe.Just('IGListDiffable'), + preprocessors: [], + belongsToProtocol: Maybe.Just('IGListDiffable'), code: diffIdentifierMethodImplementation(objectType), - comments:[], - compilerAttributes:[], + comments: [], + compilerAttributes: [], keywords: [ { name: 'diffIdentifier', - argument: Maybe.Nothing() - } + argument: Maybe.Nothing(), + }, ], - returnType: { type: Maybe.Just({ - name: 'NSObject', - reference: 'id' - }), modifiers: [] } - } + returnType: { + type: Maybe.Just({ + name: 'NSObject', + reference: 'id', + }), + modifiers: [], + }, + }; } -export function createPlugin():ObjectSpec.Plugin { +export function createPlugin(): ObjectSpec.Plugin { return { - additionalFiles: function(objectType:ObjectSpec.Type):Code.File[] { + additionalFiles: function(objectType: ObjectSpec.Type): Code.File[] { return []; }, - additionalTypes: function(objectType:ObjectSpec.Type):ObjectSpec.Type[] { + transformBaseFile: function( + objectType: ObjectSpec.Type, + baseFile: Code.File, + ): Code.File { + return baseFile; + }, + additionalTypes: function(objectType: ObjectSpec.Type): ObjectSpec.Type[] { return []; }, - attributes: function(objectType:ObjectSpec.Type):ObjectSpec.Attribute[] { + attributes: function(objectType: ObjectSpec.Type): ObjectSpec.Attribute[] { return []; }, - classMethods: function(objectType:ObjectSpec.Type):ObjC.Method[] { + classMethods: function(objectType: ObjectSpec.Type): ObjC.Method[] { return []; }, - fileTransformation: function(request:FileWriter.Request):FileWriter.Request { + transformFileRequest: function( + request: FileWriter.Request, + ): FileWriter.Request { return request; }, - fileType: function(objectType:ObjectSpec.Type):Maybe.Maybe { + fileType: function( + objectType: ObjectSpec.Type, + ): Maybe.Maybe { return Maybe.Nothing(); }, - forwardDeclarations: function(objectType:ObjectSpec.Type):ObjC.ForwardDeclaration[] { + forwardDeclarations: function( + objectType: ObjectSpec.Type, + ): ObjC.ForwardDeclaration[] { return []; }, - functions: function(objectType:ObjectSpec.Type):ObjC.Function[] { + functions: function(objectType: ObjectSpec.Type): ObjC.Function[] { return []; }, - headerComments: function(objectType:ObjectSpec.Type):ObjC.Comment[] { + headerComments: function(objectType: ObjectSpec.Type): ObjC.Comment[] { return []; }, - implementedProtocols: function(objectType:ObjectSpec.Type):ObjC.Protocol[] { + implementedProtocols: function( + objectType: ObjectSpec.Type, + ): ObjC.Protocol[] { + return [{name: 'IGListDiffable'}]; + }, + imports: function(objectType: ObjectSpec.Type): ObjC.Import[] { return [ - { name: 'IGListDiffable' }, + { + file: 'IGListDiffable.h', + isPublic: true, + requiresCPlusPlus: false, + library: Maybe.Just('IGListKit'), + }, ]; }, - imports: function(objectType:ObjectSpec.Type):ObjC.Import[] { - return [ - {file:'IGListDiffable.h', isPublic:true, library:Maybe.Just('IGListKit')}, - ]; - }, - instanceMethods: function(objectType:ObjectSpec.Type):ObjC.Method[] { + instanceMethods: function(objectType: ObjectSpec.Type): ObjC.Method[] { return [ IGListDiffableUtils.isEqualToDiffableObjectMethod(), - diffIdentifierMethod(objectType) + diffIdentifierMethod(objectType), ]; }, - macros: function(valueType:ObjectSpec.Type):ObjC.Macro[] { + macros: function(valueType: ObjectSpec.Type): ObjC.Macro[] { return []; }, - properties: function(objectType:ObjectSpec.Type):ObjC.Property[] { + properties: function(objectType: ObjectSpec.Type): ObjC.Property[] { return []; }, - requiredIncludesToRun:['IGListDiffable'], - staticConstants: function(objectType:ObjectSpec.Type):ObjC.Constant[] { + requiredIncludesToRun: ['IGListDiffable'], + staticConstants: function(objectType: ObjectSpec.Type): ObjC.Constant[] { return []; }, - validationErrors: function(objectType:ObjectSpec.Type):Error.Error[] { + validationErrors: function(objectType: ObjectSpec.Type): Error.Error[] { return []; }, - nullability: function(objectType:ObjectSpec.Type):Maybe.Maybe { + nullability: function( + objectType: ObjectSpec.Type, + ): Maybe.Maybe { return Maybe.Nothing(); }, - subclassingRestricted: function(objectType:ObjectSpec.Type):boolean { + subclassingRestricted: function(objectType: ObjectSpec.Type): boolean { return false; }, };