Skip to content

Commit

Permalink
Merge pull request #203 from a2/master
Browse files Browse the repository at this point in the history
[NEW] Preliminary Swift support. (Alexsander Akers)
  • Loading branch information
rentzsch committed Jun 6, 2014
2 parents d62842d + 4c2d823 commit 1140ad3
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 55 deletions.
1 change: 1 addition & 0 deletions mogenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
BOOL _version;
BOOL _listSourceFiles;
BOOL _orphaned;
BOOL _swift;
NSMutableDictionary *templateVar;
}
@end
137 changes: 82 additions & 55 deletions mogenerator.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
NSString *gCustomBaseClass;
NSString *gCustomBaseClassImport;
NSString *gCustomBaseClassForced;
BOOL gSwift;

@interface NSEntityDescription (fetchedPropertiesAdditions)
- (NSDictionary*)fetchedPropertiesByName;
Expand Down Expand Up @@ -245,7 +246,7 @@ - (NSString*)_resolveKeyPathType:(NSString*)keyPath {
id property = [[entity propertiesByName] objectForKey:key];
if ([property isKindOfClass:[NSAttributeDescription class]]) {
NSString *result = [property objectAttributeType];
return [result substringToIndex:[result length] -1];
return gSwift ? result : [result substringToIndex:[result length] -1];
} else if ([property isKindOfClass:[NSRelationshipDescription class]]) {
entity = [property destinationEntity];
}
Expand Down Expand Up @@ -294,7 +295,9 @@ - (void)_processPredicate:(NSPredicate*)predicate_ bindings:(NSMutableArray*)bin
} else {
type = [self _resolveKeyPathType:[lhs keyPath]];
}
type = [type stringByAppendingString:@"*"];
if (!gSwift) {
type = [type stringByAppendingString:@"*"];
}
// make sure that no repeated variables are entered here.
if (![self bindingsArray:bindings_ containsVariableNamed:[rhs variable]]) {
[bindings_ addObject:[NSDictionary dictionaryWithObjectsAndKeys:
Expand Down Expand Up @@ -344,22 +347,22 @@ - (BOOL)hasScalarAttributeType {
- (NSString*)scalarAttributeType {
switch ([self attributeType]) {
case NSInteger16AttributeType:
return @"int16_t";
return gSwift ? @"Int16" : @"int16_t";
break;
case NSInteger32AttributeType:
return @"int32_t";
return gSwift ? @"Int32" : @"int32_t";
break;
case NSInteger64AttributeType:
return @"int64_t";
return gSwift ? @"Int64" : @"int64_t";
break;
case NSDoubleAttributeType:
return @"double";
return gSwift ? @"Double" : @"double";
break;
case NSFloatAttributeType:
return @"float";
return gSwift ? @"Float" : @"float";
break;
case NSBooleanAttributeType:
return @"BOOL";
return gSwift ? @"Bool" : @"BOOL";
break;
default:
return nil;
Expand Down Expand Up @@ -421,11 +424,14 @@ - (NSString*)objectAttributeClassName {
if ([self hasTransformableAttributeType]) {
result = [[self userInfo] objectForKey:@"attributeValueClassName"];
if (!result) {
result = @"NSObject";
result = gSwift ? @"AnyObject" : @"NSObject";
}
} else {
result = [self attributeValueClassName];
}
if ([result isEqualToString:@"NSString"]) {
result = @"String";
}
return result;
}
- (NSArray*)objectAttributeTransformableProtocols {
Expand All @@ -448,8 +454,8 @@ - (NSString*)objectAttributeType {
} else if ([result rangeOfString:@"<"].location != NSNotFound) {
// `id<Protocol1,Protocol2>` (don't append asterisk).
} else if ([result isEqualToString:@"NSObject"]) {
result = @"id";
} else {
result = gSwift ? @"AnyObject" : @"id";
} else if (!gSwift) {
result = [result stringByAppendingString:@"*"]; // Make it a pointer.
}
return result;
Expand Down Expand Up @@ -605,6 +611,7 @@ - (void)application:(DDCliApplication*)app
{@"list-source-files", 0, DDGetoptNoArgument},
{@"orphaned", 0, DDGetoptNoArgument},

{@"swift", 'S', DDGetoptNoArgument},
{@"help", 'h', DDGetoptNoArgument},
{@"version", 0, DDGetoptNoArgument},
{@"template-var", 0, DDGetoptKeyValueArgument},
Expand All @@ -617,6 +624,7 @@ - (void)application:(DDCliApplication*)app
- (void)printUsage {
ddprintf(@"%@: Usage [OPTIONS] <argument> [...]\n", DDCliApp);
printf("\n"
" -S, --swift Generate Swift templates instead of Objective-C\n"
" -m, --model MODEL Path to model\n"
" -C, --configuration CONFIG Only consider entities included in the named configuration\n"
" --base-class CLASS Custom base class\n"
Expand Down Expand Up @@ -818,6 +826,8 @@ - (int)application:(DDCliApplication*)app runWithArguments:(NSArray*)arguments {
return EXIT_SUCCESS;
}

gSwift = _swift;

if (baseClassForce) {
gCustomBaseClassForced = [baseClassForce retain];
gCustomBaseClass = gCustomBaseClassForced;
Expand Down Expand Up @@ -903,15 +913,27 @@ - (int)application:(DDCliApplication*)app runWithArguments:(NSArray*)arguments {
int humanFilesGenerated = 0;

if (model) {
MiscMergeEngine *machineH = engineWithTemplateDesc([self templateDescNamed:@"machine.h.motemplate"]);
assert(machineH);
MiscMergeEngine *machineM = engineWithTemplateDesc([self templateDescNamed:@"machine.m.motemplate"]);
assert(machineM);
MiscMergeEngine *humanH = engineWithTemplateDesc([self templateDescNamed:@"human.h.motemplate"]);
assert(humanH);
MiscMergeEngine *humanM = engineWithTemplateDesc([self templateDescNamed:@"human.m.motemplate"]);
assert(humanM);

MiscMergeEngine *machineH = nil;
MiscMergeEngine *machineM = nil;
MiscMergeEngine *humanH = nil;
MiscMergeEngine *humanM = nil;

if (_swift) {
machineH = engineWithTemplateDesc([self templateDescNamed:@"machine.swift.motemplate"]);
assert(machineH);
humanH = engineWithTemplateDesc([self templateDescNamed:@"human.swift.motemplate"]);
assert(humanH);
} else {
machineH = engineWithTemplateDesc([self templateDescNamed:@"machine.h.motemplate"]);
assert(machineH);
machineM = engineWithTemplateDesc([self templateDescNamed:@"machine.m.motemplate"]);
assert(machineM);
humanH = engineWithTemplateDesc([self templateDescNamed:@"human.h.motemplate"]);
assert(humanH);
humanM = engineWithTemplateDesc([self templateDescNamed:@"human.m.motemplate"]);
assert(humanM);
}

// Add the template var dictionary to each of the merge engines
[machineH setEngineValue:templateVar forKey:kTemplateVar];
[machineM setEngineValue:templateVar forKey:kTemplateVar];
Expand Down Expand Up @@ -939,8 +961,9 @@ - (int)application:(DDCliApplication*)app runWithArguments:(NSArray*)arguments {
BOOL machineDirtied = NO;

// Machine header files.
NSString *extension = (_swift ? @"swift" : @"h");
NSString *machineHFileName = [machineDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"_%@.h", entityClassName]];
[NSString stringWithFormat:@"_%@.%@", entityClassName, extension]];
if (_listSourceFiles) {
[machineHFiles addObject:machineHFileName];
} else {
Expand All @@ -953,22 +976,25 @@ - (int)application:(DDCliApplication*)app runWithArguments:(NSArray*)arguments {
}

// Machine source files.
NSString *machineMFileName = [machineDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"_%@.m", entityClassName]];
if (_listSourceFiles) {
[machineMFiles addObject:machineMFileName];
} else {
if (![fm regularFileExistsAtPath:machineMFileName] || ![generatedMachineM isEqualToString:[NSString stringWithContentsOfFile:machineMFileName encoding:NSUTF8StringEncoding error:nil]]) {
// If the file doesn't exist or is different than what we just generated, write it out.
[generatedMachineM writeToFile:machineMFileName atomically:NO encoding:NSUTF8StringEncoding error:nil];
machineDirtied = YES;
machineFilesGenerated++;
NSString *machineMFileName = nil;
if (!_swift) {
machineMFileName = [machineDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"_%@.m", entityClassName]];
if (_listSourceFiles) {
[machineMFiles addObject:machineMFileName];
} else {
if (![fm regularFileExistsAtPath:machineMFileName] || ![generatedMachineM isEqualToString:[NSString stringWithContentsOfFile:machineMFileName encoding:NSUTF8StringEncoding error:nil]]) {
// If the file doesn't exist or is different than what we just generated, write it out.
[generatedMachineM writeToFile:machineMFileName atomically:NO encoding:NSUTF8StringEncoding error:nil];
machineDirtied = YES;
machineFilesGenerated++;
}
}
}

// Human header files.
NSString *humanHFileName = [humanDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.h", entityClassName]];
[NSString stringWithFormat:@"%@.%@", entityClassName, extension]];
if (_listSourceFiles) {
[humanHFiles addObject:humanHFileName];
} else {
Expand All @@ -980,32 +1006,33 @@ - (int)application:(DDCliApplication*)app runWithArguments:(NSArray*)arguments {
humanFilesGenerated++;
}
}

// Human source files.
NSString *humanMFileName = [humanDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.m", entityClassName]];
NSString *humanMMFileName = [humanDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.mm", entityClassName]];
if (![fm regularFileExistsAtPath:humanMFileName] && [fm regularFileExistsAtPath:humanMMFileName]) {
// Allow .mm human files as well as .m files.
humanMFileName = humanMMFileName;
}
if (_listSourceFiles) {
[humanMFiles addObject:humanMFileName];
} else {
if ([fm regularFileExistsAtPath:humanMFileName]) {
if (machineDirtied)
[fm touchPath:humanMFileName];

if (!_swift) {
// Human source files.
NSString *humanMFileName = [humanDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.m", entityClassName]];
NSString *humanMMFileName = [humanDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.mm", entityClassName]];
if (![fm regularFileExistsAtPath:humanMFileName] && [fm regularFileExistsAtPath:humanMMFileName]) {
// Allow .mm human files as well as .m files.
humanMFileName = humanMMFileName;
}
if (_listSourceFiles) {
[humanMFiles addObject:humanMFileName];
} else {
[generatedHumanM writeToFile:humanMFileName atomically:NO encoding:NSUTF8StringEncoding error:nil];
humanFilesGenerated++;
if ([fm regularFileExistsAtPath:humanMFileName]) {
if (machineDirtied)
[fm touchPath:humanMFileName];
} else {
[generatedHumanM writeToFile:humanMFileName atomically:NO encoding:NSUTF8StringEncoding error:nil];
humanFilesGenerated++;
}
}

[mfileContent appendFormat:@"#import \"%@\"\n#import \"%@\"\n",
[humanMFileName lastPathComponent], [machineMFileName lastPathComponent]];
[hfileContent appendFormat:@"#import \"%@\"\n", [humanHFileName lastPathComponent]];
}

[mfileContent appendFormat:@"#import \"%@\"\n#import \"%@\"\n",
[humanMFileName lastPathComponent], [machineMFileName lastPathComponent]];

[hfileContent appendFormat:@"#import \"%@\"\n", [humanHFileName lastPathComponent]];
}

if (_listSourceFiles) {
Expand Down
6 changes: 6 additions & 0 deletions templates/human.swift.motemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@objc
class <$managedObjectClassName$>: _<$managedObjectClassName$> {

// Custom logic goes here.

}
Loading

0 comments on commit 1140ad3

Please sign in to comment.