Conflicts:
	Tools/XcodeCapp/XcodeCapp/ProcessSourceOperation.m
This commit is contained in:
Antoine Mercadal
2014-11-05 19:06:06 -08:00
8 changed files with 977 additions and 147 deletions
+17 -15
View File
@@ -138,21 +138,23 @@ AppController *SharedAppControllerInstance = nil;
- (void)registerDefaultPreferences
{
NSDictionary *appDefaults = @{
kDefaultLastEventId: [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow],
kDefaultFirstLaunch: @YES,
kDefaultFirstLaunchVersion: @2.0,
kDefaultXCCAPIMode: [NSNumber numberWithInt:kXCCAPIModeAuto],
kDefaultXCCReactToInodeMod: @YES,
kDefaultXCCReopenLastProject: @YES,
kDefaultXCCAutoOpenErrorsPanelOnErrors: @YES,
kDefaultXCCAutoOpenErrorsPanelOnCappLint: @YES,
kDefaultXCCAutoShowNotificationOnErrors: @YES,
kDefaultXCCAutoShowNotificationOnCappLint: @YES,
kDefaultXCCProjectHistory: [NSArray new],
kDefaultMaxRecentProjects: @20,
kDefaultLogLevel: [NSNumber numberWithInt:LOG_LEVEL_WARN],
kDefaultAutoOpenXcodeProject: @YES,
kDefaultUseSymlinkWhenCreatingProject: @YES
kDefaultLastEventId: [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow],
kDefaultFirstLaunch: @YES,
kDefaultFirstLaunchVersion: @2.0,
kDefaultXCCAPIMode: [NSNumber numberWithInt:kXCCAPIModeAuto],
kDefaultXCCReactToInodeMod: @YES,
kDefaultXCCReopenLastProject: @YES,
kDefaultXCCAutoOpenErrorsPanelOnErrors: @YES,
kDefaultXCCAutoOpenErrorsPanelOnCappLint: @YES,
kDefaultXCCAutoShowNotificationOnErrors: @YES,
kDefaultXCCAutoShowNotificationOnCappLint: @YES,
kDefaultXCCProjectHistory: [NSArray new],
kDefaultMaxRecentProjects: @20,
kDefaultLogLevel: [NSNumber numberWithInt:LOG_LEVEL_WARN],
kDefaultAutoOpenXcodeProject: @YES,
kDefaultUseSymlinkWhenCreatingProject: @YES,
kDefaultXCCUseDebugFrameworkWithObjj: @YES,
kDefaultXCCShouldProcessObjj: @YES
};
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+2 -2
View File
@@ -21,11 +21,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.1</string>
<string>3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3.1</string>
<string>3.2</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSUIElement</key>
@@ -44,8 +44,8 @@
return;
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSDictionary *info = @{ @"projectId":self.projectId, @"path":self.sourcePath };
NSDictionary *info = @{ @"projectId":self.projectId, @"path":self.sourcePath};
[center postNotificationName:XCCConversionDidStartNotification object:self userInfo:info];
DDLogVerbose(@"Conversion started: %@", self.sourcePath);
@@ -74,7 +74,7 @@
self.xcc.parserPath,
self.projectPath,
self.sourcePath
];
];
notificationTitle = @"Objective-J source processed";
}
@@ -158,14 +158,23 @@
}
else if (!self.xcc.isLoadingProject)
{
BOOL showFinalNotification = YES;
BOOL showFinalNotification = NO;
// At this point, we should only detect warnings
if ([self.xcc shouldProcessWithObjjWarnings])
{
showFinalNotification = [self.xcc checkObjjWarningsForPath:[NSArray arrayWithObject:self.sourcePath]];
[self.xcc showObjjWarnings];
}
else
{
showFinalNotification = YES;
}
if ([self.xcc shouldProcessWithCappLint])
{
showFinalNotification = [self.xcc checkCappLintForPath:[NSArray arrayWithObject:self.sourcePath]];
if (!showFinalNotification)
[self.xcc showCappLintErrors];
showFinalNotification = [self.xcc checkCappLintForPath:[NSArray arrayWithObject:self.sourcePath]] && showFinalNotification;
[self.xcc showCappLintWarnings];
}
if (showFinalNotification)
+2
View File
@@ -21,6 +21,8 @@ extern NSString * const kDefaultXCCAutoOpenErrorsPanelOnErrors;
extern NSString * const kDefaultXCCAutoOpenErrorsPanelOnCappLint;
extern NSString * const kDefaultXCCAutoShowNotificationOnErrors;
extern NSString * const kDefaultXCCAutoShowNotificationOnCappLint;
extern NSString * const kDefaultXCCUseDebugFrameworkWithObjj;
extern NSString * const kDefaultXCCShouldProcessObjj;
extern NSString * const kDefaultXCCProjectHistory;
extern NSString * const kDefaultLastOpenedPath;
extern NSString * const kDefaultPathModificationDates;
+3 -1
View File
@@ -19,6 +19,8 @@ NSString * const kDefaultXCCAutoOpenErrorsPanelOnErrors = @"XCCAutoOpenErrorsPan
NSString * const kDefaultXCCAutoOpenErrorsPanelOnCappLint = @"XCCAutoOpenErrorsPanelOnCappLint";
NSString * const kDefaultXCCAutoShowNotificationOnErrors = @"XCCAutoOpenShowNotificationErrors";
NSString * const kDefaultXCCAutoShowNotificationOnCappLint = @"XCCAutoShowNotificationOnCappLint";
NSString * const kDefaultXCCUseDebugFrameworkWithObjj = @"XCCUseDebugFrameworkWithObjj";
NSString * const kDefaultXCCShouldProcessObjj = @"XCCShouldProcessObjj";
NSString * const kDefaultXCCProjectHistory = @"XCCProjectHistory";
NSString * const kDefaultLastOpenedPath = @"LastOpenedPath";
NSString * const kDefaultPathModificationDates = @"pathModificationDates";
@@ -26,4 +28,4 @@ NSString * const kDefaultMaxRecentProjects = @"maxRecentProjects";
NSString * const kDefaultLogLevel = @"logLevel";
NSString * const kDefaultAutoOpenXcodeProject = @"autoOpenXcodeProject";
NSString * const kDefaultUseSymlinkWhenCreatingProject = @"useSymlinkWhenCreatingProject";
NSString * const kDefaultUpdateCappuccinoWithLastVersionOfMasterBranch = @"updateCappuccinoWithLastVersionOfMasterBranch";
NSString * const kDefaultUpdateCappuccinoWithLastVersionOfMasterBranch = @"updateCappuccinoWithLastVersionOfMasterBranch";
+6 -1
View File
@@ -156,9 +156,14 @@ extern NSString * const XCCCappLintDidEndNotification;
- (NSDictionary*)createProject:(NSString*)aPath;
- (void)showCappLintWarnings;
- (void)showObjjWarnings;
- (BOOL)shouldProcessWithCappLint;
- (BOOL)checkCappLintForPath:(NSArray*)paths;
- (void)showCappLintErrors;
- (BOOL)shouldProcessWithObjjWarnings;
- (BOOL)checkObjjWarningsForPath:(NSArray*)paths;
- (void)updateCappuccino;
+249 -20
View File
@@ -76,6 +76,8 @@ static NSArray *XCCDefaultIgnoredPathPredicates = nil;
NSString * const XCCCappLintDidStartNotification = @"XCCCappLintDidStartNotification";
NSString * const XCCCappLintDidEndNotification = @"XCCCappLintDidEndNotification";
NSString * const XCCObjjDidStartNotification = @"XCCObjjDidStartNotification";
NSString * const XCCObjjDidEndNotification = @"XCCObjjDidEndNotification";
@interface XcodeCapp ()
@@ -1694,6 +1696,13 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
|| [defaults boolForKey:kDefaultXCCAutoShowNotificationOnCappLint];
}
- (BOOL)shouldProcessWithObjjWarnings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
return ([defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnErrors] || [defaults boolForKey:kDefaultXCCAutoShowNotificationOnErrors]) && [defaults boolForKey:kDefaultXCCShouldProcessObjj];
}
- (void)showErrors
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
@@ -1704,41 +1713,96 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
}
}
- (void)showCappLintErrors
- (void)showCappLintWarnings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnCappLint] && self.errorList.count)
NSUInteger numberError = [self.errorList count];
NSDictionary *firstError;
NSUInteger i = 0;
for (i = 0; i < numberError; i++)
{
NSDictionary *dict = [self.errorList objectAtIndex:i];
if ([[dict valueForKey:@"type"] isEqualToString: @"capp_lint"])
{
firstError = dict;
break;
}
}
if ([defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnCappLint] && firstError)
[self openErrorsPanel:self];
if ([defaults boolForKey:kDefaultXCCAutoShowNotificationOnCappLint])
if ([defaults boolForKey:kDefaultXCCAutoShowNotificationOnCappLint] && firstError)
{
NSUInteger numberError = [self.errorList count];
NSDictionary *error = [self.errorList objectAtIndex:0];
NSString *filename = [error objectForKey:@"path"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:self.projectId] , @"projectId",
@"Code Style Issues", @"title",
filename.lastPathComponent , @"message",
nil];
[self wantUserNotificationWithInfo:dict];
}
}
- (void)showObjjWarnings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSUInteger numberError = [self.errorList count];
NSDictionary *firstError;
NSUInteger i = 0;
for (i = 0; i < numberError; i++)
{
NSDictionary *dict = [self.errorList objectAtIndex:i];
if (numberError)
if ([[dict valueForKey:@"type"] isEqualToString: @"objj"])
{
NSDictionary *error = [self.errorList objectAtIndex:0];
NSString *filename = [error objectForKey:@"path"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:self.projectId] , @"projectId",
@"Code Style Issues", @"title",
filename.lastPathComponent , @"message",
nil];
[self wantUserNotificationWithInfo:dict];
firstError = dict;
break;
}
}
if ([defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnErrors] && firstError)
[self openErrorsPanel:self];
if ([defaults boolForKey:kDefaultXCCAutoShowNotificationOnErrors] && firstError)
{
NSDictionary *error = [self.errorList objectAtIndex:0];
NSString *filename = [error objectForKey:@"path"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:self.projectId] , @"projectId",
@"Compiling Issues", @"title",
filename.lastPathComponent , @"message",
nil];
[self wantUserNotificationWithInfo:dict];
}
}
- (void)pruneProcessingErrorsForProjectPath:(NSString *)path
{
[self pruneProcessingErrorsForProjectPath:path type:nil];
}
- (void)pruneProcessingErrorsForProjectPath:(NSString *)path type:(NSString*)type
{
// Remove all errors for the path being processed
NSIndexSet *matchingErrors = [self.errorList indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
{
return [[obj valueForKey:@"path"] isEqualToString:path];
if (type)
return ([[obj valueForKey:@"path"] isEqualToString:path] || [[obj valueForKey:@"realPath"] isEqualToString:path]) && [[obj valueForKey:@"type"] isEqualToString:type];
else
return [[obj valueForKey:@"path"] isEqualToString:path] || [[obj valueForKey:@"realPath"] isEqualToString:path];
}];
[self.errorListController removeObjectsAtArrangedObjectIndexes:matchingErrors];
}
@@ -1758,6 +1822,170 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
return index != NSNotFound;
}
#pragma mark - objjj check
- (NSString*)_getObjjIncludePaths
{
NSRegularExpression *regulareExpressionFramework = [NSRegularExpression regularExpressionWithPattern:@"OBJJ_INCLUDE_PATHS ?= ?\\[\"(.*)\"\\," options:0 error:nil];
NSString *indexPath;
if ([[NSUserDefaults standardUserDefaults] boolForKey:kDefaultXCCUseDebugFrameworkWithObjj])
indexPath = [NSString stringWithFormat:@"%@/index-debug.html", self.projectPath];
else
indexPath = [NSString stringWithFormat:@"%@/index.html", self.projectPath];
NSDictionary *taskResult = [self runTaskWithLaunchPath:@"/bin/cat" arguments:[NSMutableArray arrayWithObject:indexPath] returnType:kTaskReturnTypeAny];
NSString *response = taskResult[@"response"];
NSArray *matches = [regulareExpressionFramework matchesInString:response options:0 range:NSMakeRange(0, [response length])];
for (NSTextCheckingResult *match in matches)
return [response substringWithRange:[match rangeAtIndex:1]];
return @"Frameworks/";
}
- (BOOL)checkObjjWarningsForPath:(NSArray*)paths
{
DDLogVerbose(@"Checking path %@ with objj", paths);
NSUInteger numberOfFiles = [paths count];
if (!numberOfFiles)
return YES;
[[NSNotificationCenter defaultCenter] postNotificationName:XCCBatchDidStartNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:XCCObjjDidStartNotification object:self];
NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"-I", [self _getObjjIncludePaths], @"-m", nil];
[arguments addObjectsFromArray:paths];
NSDictionary *taskResult = [self runTaskWithLaunchPath:self.executablePaths[@"objj"]
arguments:arguments
returnType:kTaskReturnTypeStdOut];
NSInteger status = [taskResult[@"status"] intValue];
NSString *response = taskResult[@"response"];
if (status == 0 && [response length] == 0)
{
[[NSNotificationCenter defaultCenter] postNotificationName:XCCObjjDidEndNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:XCCBatchDidEndNotification object:self];
return YES;
}
NSMutableArray *errors = [NSMutableArray arrayWithArray:[response componentsSeparatedByString:@"\n\n"]];
NSInteger numberOfErrors = [errors count];
NSInteger i = 0;
NSMutableArray *dicts = [NSMutableArray array];
// When checking of the entire project, we have to be ready to find errors
NSRegularExpression *regulareExpressionFramework = [NSRegularExpression regularExpressionWithPattern:@"([\\S\\s]*)(WARNING|ERROR) line ([0-9]*) in file\\:(.*)\\: ([\\S\\s]*)" options:0 error:nil];
NSString *filePath;
if ([paths count] == 1)
filePath = [paths firstObject];
for (i = 0; i < numberOfErrors; i++)
{
NSMutableString *error = (NSMutableString*)[errors objectAtIndex:i];
NSString *line;
NSString *path;
NSString *messageError;
// We have an extra new line for the first error
if (i == 0)
error = (NSMutableString*)[error substringFromIndex:1];
NSArray *matches = [regulareExpressionFramework matchesInString:error options:0 range:NSMakeRange(0, [error length])];
NSInteger j = 0;
if (![matches count])
{
DDLogVerbose(@"Error %@ has been ignored by xCodeCapp, the error doesn't respect any pattern", error);
continue;
}
for (NSTextCheckingResult *match in matches)
{
for (j = 0; j < [match numberOfRanges]; j++)
{
switch (j) {
case 1:
messageError = [error substringWithRange:[match rangeAtIndex:j]];
break;
case 3:
line = [error substringWithRange:[match rangeAtIndex:j]];
break;
case 4:
path = [error substringWithRange:[match rangeAtIndex:j]];
break;
case 5:
messageError = [NSString stringWithFormat:@"Compiling issue at line %@ of file %@:\n%@ \n%@", line, path.lastPathComponent, [error substringWithRange:[match rangeAtIndex:j]], messageError];
break;
default:
break;
}
}
}
// Make sure to delete all the compilations issue form the tableView
[self pruneProcessingErrorsForProjectPath:path type:@"objj"];
// Path and realPath are needed, we can get error on ViewController2.j while checking ViewController.j.
// When recompiling ViewController.j, realPath is used to know which errors have to be erased form the table
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:[line intValue]], @"line",
messageError , @"message",
(filePath ? filePath:path), @"path",
@"objj", @"type",
path , @"realPath",
nil];
// Compiler can show several times the same errors
if (![dicts containsObject:dict] && ![self.errorList containsObject:dict])
[dicts addObject:dict];
}
[self performSelectorOnMainThread:@selector(objjCompilerDidGenerateError:) withObject:dicts waitUntilDone:YES];
self.isProcessing = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:XCCObjjDidEndNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:XCCBatchDidEndNotification object:self];
return NO;
}
- (IBAction)checkProjectWithObjj:(id)sender
{
[self clearErrors:self];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(objjDidEndNotification:) name:XCCObjjDidEndNotification object:nil];
[self performSelectorInBackground:@selector(checkObjjWarningsForPath:) withObject:self.xCodeCappTargetedFiles];
}
- (void)objjDidEndNotification:(NSNotification*)aNotification
{
[self showObjjWarnings];
[[NSNotificationCenter defaultCenter] removeObserver:self name:XCCObjjDidEndNotification object:nil];
}
- (void)objjCompilerDidGenerateError:(NSArray*)errors
{
[self.errorListController addObjects:errors];
}
#pragma mark - capp_lint
@@ -1773,7 +2001,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
- (void)cappLintDidEndNotification:(NSNotification*)aNotification
{
[self showCappLintErrors];
[self showCappLintWarnings];
[[NSNotificationCenter defaultCenter] removeObserver:self name:XCCCappLintDidEndNotification object:nil];
}
@@ -1840,18 +2068,19 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
NSInteger positionOfSecondColon = [errorWithoutPath rangeOfString:@":"].location;
line = [errorWithoutPath substringToIndex:positionOfSecondColon];
NSString *messageError = [NSString stringWithFormat:@"Code style issue: %@ \n%@", path.lastPathComponent, errorWithoutPath];
NSString *messageError = [NSString stringWithFormat:@"Code style issue at line %@ of file %@:\n%@", line, path.lastPathComponent, errorWithoutPath];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:[line intValue]], @"line",
messageError , @"message",
path, @"path",
@"capp_lint", @"type",
nil];
[dicts addObject:dict];
}
[self performSelectorOnMainThread:@selector(cappLintConversionDidGenerateError:) withObject:dicts waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(cappLintConversionDidGenerateError:) withObject:dicts waitUntilDone:YES];
self.isProcessing = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:XCCBatchDidEndNotification object:self];
File diff suppressed because it is too large Load Diff