mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-11-09 16:38:45 +00:00
Merge remote-tracking branch 'cappuccino/master'
This commit is contained in:
commit
d9819d8b3d
87 files changed
+1258
-3951
No files matched your search
+1
-1
@@ -280,7 +280,7 @@ CPButtonImageOffset = 3.0;
|
||||
break;
|
||||
|
||||
case CPOffState:
|
||||
[self unsetThemeState:[CPThemeStateSelected, CPButtonStateMixed, CPThemeStateHighlighted]];
|
||||
[self unsetThemeStates:[CPThemeStateSelected, CPButtonStateMixed, CPThemeStateHighlighted]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -272,15 +272,15 @@
|
||||
currentButtonOffset += width - 1;
|
||||
}
|
||||
|
||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered]];
|
||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
|
||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered]];
|
||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered]];
|
||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
|
||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered]];
|
||||
[button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
|
||||
|
||||
// FIXME shouldn't need this
|
||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
|
||||
|
||||
[self addSubview:button];
|
||||
}
|
||||
|
||||
@@ -1114,30 +1114,30 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled];
|
||||
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]]forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]]forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateSelected]];
|
||||
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:CPThemeStateHighlighted] forThemeAttribute:@"font" inState:CPThemeStateHighlighted];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateHighlighted];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateHighlighted];
|
||||
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"font" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-color" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-offset" inStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
|
||||
[self addSubview:_textField];
|
||||
|
||||
|
||||
+6
-6
@@ -188,12 +188,12 @@
|
||||
[_buttonUp setFrame:upFrame];
|
||||
[_buttonDown setFrame:downFrame];
|
||||
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
}
|
||||
|
||||
- (void)_sizeToFit
|
||||
|
||||
@@ -789,7 +789,13 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
||||
var idx = [self indexOfTabViewItem:_selectedTabViewItem];
|
||||
|
||||
if (idx !== CPNotFound)
|
||||
{
|
||||
// Temporarily set the selected item to not selected.
|
||||
// It allows the initial selection to be made correctly.
|
||||
_selectedTabViewItem = nil;
|
||||
|
||||
[self selectTabViewItemAtIndex:idx];
|
||||
}
|
||||
}
|
||||
|
||||
var type = _type;
|
||||
|
||||
@@ -622,7 +622,7 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
[[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:YES];
|
||||
|
||||
// The underlying column header shows normal state
|
||||
[headerView unsetThemeState:CPThemeStateHighlighted | CPThemeStateSelected];
|
||||
[headerView unsetThemeStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
|
||||
// Keep track of the location within the column header where the original mousedown occurred
|
||||
_columnDragHeaderView = [_columnDragView viewWithTag:CPTableHeaderViewDragColumnHeaderTag];
|
||||
|
||||
@@ -6400,18 +6400,12 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
|
||||
- (BOOL)setThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
[super setThemeState:aState];
|
||||
[self recursivelyPerformSelector:@selector(setThemeState:) withObject:aState startingFrom:self];
|
||||
}
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
[super unsetThemeState:aState];
|
||||
[self recursivelyPerformSelector:@selector(unsetThemeState:) withObject:aState startingFrom:self];
|
||||
}
|
||||
|
||||
@@ -684,7 +684,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
// Select the text if the textfield became first responder through keyboard interaction
|
||||
if (!_willBecomeFirstResponderByClick)
|
||||
{
|
||||
[self _selectText:self immediately:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
var point = CGPointMake([self convertPointFromBase:[[CPApp currentEvent] locationInWindow]].x - [self currentValueForThemeAttribute:@"content-inset"].left, 0),
|
||||
position = [CPPlatformString charPositionOfString:[self stringValue] withFont:[self font] forPoint:point];
|
||||
|
||||
[self setSelectedRange:CPMakeRange(position, 0)];
|
||||
}
|
||||
|
||||
_willBecomeFirstResponderByClick = NO;
|
||||
|
||||
|
||||
+125
-44
@@ -36,7 +36,6 @@ var CPThemesByName = { },
|
||||
/*!
|
||||
@ingroup appkit
|
||||
*/
|
||||
|
||||
@implementation CPTheme : CPObject
|
||||
{
|
||||
CPString _name;
|
||||
@@ -327,6 +326,7 @@ function ThemeState(stateNames)
|
||||
{
|
||||
if (!stateNames.hasOwnProperty(key))
|
||||
continue;
|
||||
|
||||
if (key !== 'normal')
|
||||
{
|
||||
this._stateNames[key] = true;
|
||||
@@ -344,8 +344,10 @@ function ThemeState(stateNames)
|
||||
this._stateNameString = stateNameKeys[0];
|
||||
|
||||
var stateNameLength = stateNameKeys.length;
|
||||
|
||||
for (var stateIndex = 1; stateIndex < stateNameLength; stateIndex++)
|
||||
this._stateNameString = this._stateNameString + "+" + stateNameKeys[stateIndex];
|
||||
|
||||
this._stateNameCount = stateNameLength;
|
||||
}
|
||||
|
||||
@@ -392,7 +394,19 @@ ThemeState.prototype.without = function(aState)
|
||||
if (!aState || aState === [CPNull null])
|
||||
return this;
|
||||
|
||||
var firstTransform = CPThemeWithoutTransform[this._stateNameString],
|
||||
result;
|
||||
|
||||
if (firstTransform)
|
||||
{
|
||||
result = firstTransform[aState._stateNameString];
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
var newStates = {};
|
||||
|
||||
for (var stateName in this._stateNames)
|
||||
{
|
||||
if (!this._stateNames.hasOwnProperty(stateName))
|
||||
@@ -402,25 +416,54 @@ ThemeState.prototype.without = function(aState)
|
||||
newStates[stateName] = true;
|
||||
}
|
||||
|
||||
return ThemeState._cacheThemeState(new ThemeState(newStates));
|
||||
result = ThemeState._cacheThemeState(new ThemeState(newStates));
|
||||
|
||||
if (!firstTransform)
|
||||
firstTransform = CPThemeWithoutTransform[this._stateNameString] = {};
|
||||
|
||||
firstTransform[aState._stateNameString] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ThemeState.prototype.and = function(aState)
|
||||
{
|
||||
return CPThemeState(this, aState);
|
||||
var firstTransform = CPThemeAndTransform[this._stateNameString],
|
||||
result;
|
||||
|
||||
if (firstTransform)
|
||||
{
|
||||
result = firstTransform[aState._stateNameString];
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = CPThemeState(this, aState);
|
||||
|
||||
if (!firstTransform)
|
||||
firstTransform = CPThemeAndTransform[this._stateNameString] = {};
|
||||
|
||||
firstTransform[aState._stateNameString] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var CPThemeStates = {};
|
||||
var CPThemeStates = {},
|
||||
CPThemeWithoutTransform = {},
|
||||
CPThemeAndTransform = {};
|
||||
|
||||
ThemeState._cacheThemeState = function(aState)
|
||||
{
|
||||
// We do this caching so themeState equality works. Basically, doing CPThemeState('foo+bar') === CPThemeState('bar', 'foo') will return true.
|
||||
var themeState = CPThemeStates[String(aState)];
|
||||
|
||||
if (themeState === undefined)
|
||||
{
|
||||
themeState = aState;
|
||||
CPThemeStates[String(themeState)] = themeState;
|
||||
}
|
||||
|
||||
return themeState;
|
||||
}
|
||||
|
||||
@@ -438,14 +481,17 @@ function CPThemeState()
|
||||
throw "CPThemeState() must be called with at least one string argument";
|
||||
|
||||
var themeState;
|
||||
|
||||
if (arguments.length === 1 && typeof arguments[0] === 'string')
|
||||
{
|
||||
themeState = CPThemeStates[arguments[0]];
|
||||
|
||||
if (themeState !== undefined)
|
||||
return themeState;
|
||||
}
|
||||
|
||||
var stateNames = {};
|
||||
|
||||
for (var argIndex = 0; argIndex < arguments.length; argIndex++)
|
||||
{
|
||||
if (arguments[argIndex] === [CPNull null] || !arguments[argIndex])
|
||||
@@ -457,12 +503,14 @@ function CPThemeState()
|
||||
{
|
||||
if (!arguments[argIndex]._stateNames.hasOwnProperty(stateName))
|
||||
continue;
|
||||
|
||||
stateNames[stateName] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var allNames = arguments[argIndex].split('+');
|
||||
|
||||
for (var nameIndex = 0; nameIndex < allNames.length; nameIndex++)
|
||||
stateNames[allNames[nameIndex]] = true;
|
||||
}
|
||||
@@ -522,6 +570,9 @@ CPThemeStateControlSizeRegular = CPThemeState("controlSizeRegular");
|
||||
CPThemeStateControlSizeSmall = CPThemeState("controlSizeSmall");
|
||||
CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
|
||||
CPThemeStateNormalString = String(CPThemeStateNormal);
|
||||
|
||||
|
||||
@implementation _CPThemeAttribute : CPObject
|
||||
{
|
||||
CPString _name;
|
||||
@@ -532,7 +583,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
_CPThemeAttribute _themeDefaultAttribute;
|
||||
}
|
||||
|
||||
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue
|
||||
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue defaultAttribute:(_CPThemeAttribute)aDefaultAttribute
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@@ -541,7 +592,9 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
_cache = { };
|
||||
_name = aName;
|
||||
_defaultValue = aDefaultValue;
|
||||
_values = @{};
|
||||
|
||||
if (aDefaultAttribute)
|
||||
_themeDefaultAttribute = aDefaultAttribute;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -562,24 +615,41 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
return [_values count] > 0;
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue
|
||||
- (_CPThemeAttribute)attributeBySettingValue:(id)aValue
|
||||
{
|
||||
_cache = {};
|
||||
var attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
|
||||
|
||||
if (aValue === undefined || aValue === nil)
|
||||
_values = @{};
|
||||
else
|
||||
_values = @{ String(CPThemeStateNormal): aValue };
|
||||
if (aValue !== undefined && aValue !== nil)
|
||||
attribute._values = @{ CPThemeStateNormalString: aValue };
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forState:(ThemeState)aState
|
||||
- (_CPThemeAttribute)attributeBySettingValue:(id)aValue forState:(ThemeState)aState
|
||||
{
|
||||
_cache = { };
|
||||
var shouldRemoveValue = aValue === undefined || aValue === nil,
|
||||
attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute],
|
||||
values = _values;
|
||||
|
||||
if ((aValue === undefined) || (aValue === nil))
|
||||
[_values removeObjectForKey:String(aState)];
|
||||
else
|
||||
[_values setObject:aValue forKey:String(aState)];
|
||||
if (values != null)
|
||||
{
|
||||
values = [values copy];
|
||||
|
||||
if (shouldRemoveValue)
|
||||
[values removeObjectForKey:String(aState)];
|
||||
else
|
||||
[values setObject:aValue forKey:String(aState)];
|
||||
|
||||
attribute._values = values;
|
||||
}
|
||||
else if (!shouldRemoveValue)
|
||||
{
|
||||
values = [[CPDictionary alloc] init];
|
||||
[values setObject:aValue forKey:String(aState)];
|
||||
attribute._values = values;
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
- (id)value
|
||||
@@ -604,7 +674,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
if (aState._stateNameCount > 1)
|
||||
{
|
||||
var states = [_values allKeys],
|
||||
count = states.length,
|
||||
count = states ? states.length : 0,
|
||||
largestThemeState = 0;
|
||||
|
||||
while (count--)
|
||||
@@ -642,27 +712,41 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
return value;
|
||||
}
|
||||
|
||||
- (void)setParentAttribute:(_CPThemeAttribute)anAttribute
|
||||
- (_CPThemeAttribute)attributeBySettingParentAttribute:(_CPThemeAttribute)anAttribute
|
||||
{
|
||||
if (_themeDefaultAttribute === anAttribute)
|
||||
return;
|
||||
return self;
|
||||
|
||||
_cache = { };
|
||||
_themeDefaultAttribute = anAttribute;
|
||||
var attribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:anAttribute];
|
||||
|
||||
attribute._values = [_values copy];
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
- (_CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
|
||||
{
|
||||
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue];
|
||||
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue defaultAttribute:_themeDefaultAttribute];
|
||||
|
||||
mergedAttribute._values = [_values copy];
|
||||
[mergedAttribute._values addEntriesFromDictionary:anAttribute._values];
|
||||
|
||||
if (anAttribute._values)
|
||||
mergedAttribute._values ? [mergedAttribute._values addEntriesFromDictionary:anAttribute._values] : [anAttribute._values copy];
|
||||
|
||||
return mergedAttribute;
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return [super description] + @" Name: " + _name + @", defaultAttribute: " + _themeDefaultAttribute + @", defaultValue: " + _defaultValue + @", values: " + _values;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// This is used to pass 'parrentAttribute' to the coder
|
||||
var ParentAttributeForCoder = nil;
|
||||
|
||||
@implementation _CPThemeAttribute (CPCoding)
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
@@ -676,13 +760,16 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
_name = [aCoder decodeObjectForKey:@"name"];
|
||||
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
|
||||
_values = @{};
|
||||
_themeDefaultAttribute = ParentAttributeForCoder;
|
||||
|
||||
if ([aCoder containsValueForKey:@"value"])
|
||||
{
|
||||
var state = String(CPThemeStateNormal);
|
||||
var state;
|
||||
|
||||
if ([aCoder containsValueForKey:@"state"])
|
||||
state = [aCoder decodeObjectForKey:@"state"];
|
||||
else
|
||||
state = CPThemeStateNormalString
|
||||
|
||||
[_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
|
||||
}
|
||||
@@ -710,7 +797,7 @@ CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
[aCoder encodeObject:_defaultValue forKey:@"defaultValue"];
|
||||
|
||||
var keys = [_values allKeys],
|
||||
count = keys.length;
|
||||
count = keys ? keys.length : 0;
|
||||
|
||||
if (count === 1)
|
||||
{
|
||||
@@ -748,7 +835,7 @@ function CPThemeAttributeEncode(aCoder, aThemeAttribute)
|
||||
{
|
||||
var state = [values allKeys][0];
|
||||
|
||||
if (state === String(CPThemeStateNormal))
|
||||
if (state === CPThemeStateNormalString)
|
||||
{
|
||||
[aCoder encodeObject:[values objectForKey:state] forKey:key];
|
||||
|
||||
@@ -766,30 +853,24 @@ function CPThemeAttributeEncode(aCoder, aThemeAttribute)
|
||||
return NO;
|
||||
}
|
||||
|
||||
function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme, aClass)
|
||||
function CPThemeAttributeDecode(aCoder, attribute)
|
||||
{
|
||||
var key = "$a" + anAttributeName;
|
||||
var key = "$a" + attribute._name;
|
||||
|
||||
if (![aCoder containsValueForKey:key])
|
||||
var attribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
|
||||
|
||||
else
|
||||
if ([aCoder containsValueForKey:key])
|
||||
{
|
||||
var attribute = [aCoder decodeObjectForKey:key];
|
||||
ParentAttributeForCoder = attribute._themeDefaultAttribute;
|
||||
|
||||
if (!attribute || !attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]])
|
||||
{
|
||||
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
|
||||
var decodedAttribute = [aCoder decodeObjectForKey:key];
|
||||
|
||||
[themeAttribute setValue:attribute];
|
||||
ParentAttributeForCoder = nil;
|
||||
|
||||
attribute = themeAttribute;
|
||||
}
|
||||
if (!decodedAttribute || !decodedAttribute.isa || ![decodedAttribute isKindOfClass:[_CPThemeAttribute class]])
|
||||
attribute = [attribute attributeBySettingValue:decodedAttribute];
|
||||
else
|
||||
attribute = decodedAttribute;
|
||||
}
|
||||
|
||||
if (aTheme && aClass)
|
||||
[attribute setParentAttribute:[aTheme attributeWithName:anAttributeName forClass:aClass]];
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
|
||||
@@ -1475,9 +1475,6 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
|
||||
- (BOOL)setThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var r = [super setThemeState:aState];
|
||||
|
||||
// Share hover state with the disclosure and delete buttons.
|
||||
@@ -1492,9 +1489,6 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var r = [super unsetThemeState:aState];
|
||||
|
||||
// Share hover state with the disclosure and delete button.
|
||||
|
||||
+13
-2
@@ -3386,8 +3386,19 @@ setBoundsOrigin:
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
|
||||
[_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
|
||||
}
|
||||
// var start = [CPDate new];
|
||||
|
||||
for (var i = 0, size = [_subviews count]; i < size; i++)
|
||||
{
|
||||
[[_subviews objectAtIndex:i] _recomputeAppearance];
|
||||
}
|
||||
// [_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
|
||||
|
||||
/* var now = [CPDate new];
|
||||
var elapsedSeconds = [now timeIntervalSinceReferenceDate] - [start timeIntervalSinceReferenceDate];
|
||||
|
||||
CPLog.trace(@"_recomputeAppearance " + [_subviews count] + " subviews in " + elapsedSeconds + @" seconds");
|
||||
*/}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -49,7 +49,7 @@ var CPCibOwner = @"CPCibOwner",
|
||||
|
||||
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner
|
||||
{
|
||||
return [self loadCibNamed:aName owner:anOwner loadDelegate:nil];
|
||||
return [self loadCibFile:[self _cibPathForName:aName withOwner:anOwner] externalNameTable:@{ CPCibOwner: anOwner }];
|
||||
}
|
||||
|
||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
|
||||
@@ -68,14 +68,7 @@ var CPCibOwner = @"CPCibOwner",
|
||||
|
||||
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
|
||||
{
|
||||
if (![aName hasSuffix:@".cib"])
|
||||
aName = [aName stringByAppendingString:@".cib"];
|
||||
|
||||
// Path is based solely on anOwner:
|
||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
||||
path = [bundle _cibPathForResource:aName];
|
||||
|
||||
return [self loadCibFile:path externalNameTable:@{ CPCibOwner: anOwner } loadDelegate:aDelegate];
|
||||
return [self loadCibFile:[self _cibPathForName:aName withOwner:anOwner] externalNameTable:@{ CPCibOwner: anOwner } loadDelegate:aDelegate];
|
||||
}
|
||||
|
||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
|
||||
@@ -101,6 +94,17 @@ var CPCibOwner = @"CPCibOwner",
|
||||
return [self pathForResource:aName];
|
||||
}
|
||||
|
||||
+ (CPString)_cibPathForName:(CPString)aName withOwner:(id)anOwner
|
||||
{
|
||||
if (![aName hasSuffix:@".cib"])
|
||||
aName = [aName stringByAppendingString:@".cib"];
|
||||
|
||||
// Path is based solely on anOwner:
|
||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle];
|
||||
|
||||
return [bundle _cibPathForResource:aName];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPCibLoadDelegate : CPObject
|
||||
|
||||
+3
-2
@@ -33,8 +33,9 @@ appKitTask = framework ("AppKit", function(appKitTask)
|
||||
return "--include \"" + aFilename + "\"";
|
||||
}).join(" ");
|
||||
|
||||
if ($CONFIGURATION === "Release")
|
||||
appKitTask.setCompilerFlags("-O " + INCLUDES);
|
||||
if ($CONFIGURATION === "Release") {
|
||||
appKitTask.setCompilerFlags("-O2 " + INCLUDES);
|
||||
}
|
||||
else
|
||||
appKitTask.setCompilerFlags("-DDEBUG -g " + INCLUDES);
|
||||
});
|
||||
|
||||
@@ -129,6 +129,33 @@ var DOMFixedWidthSpanElement = nil,
|
||||
DOMMetricsDivElement.appendChild(DOMMetricsImgElement);
|
||||
}
|
||||
|
||||
+ (int)charPositionOfString:(CPString)aString withFont:(CPFont)aFont forPoint:(CGPoint)aPoint
|
||||
{
|
||||
if (!aString)
|
||||
return 0;
|
||||
|
||||
var position = 0,
|
||||
stringLength = aString.length,
|
||||
currentString = "";
|
||||
|
||||
for (var i = 0; i < stringLength; i++)
|
||||
{
|
||||
var lastChar = aString[i];
|
||||
|
||||
currentString += lastChar;
|
||||
|
||||
var sizeOfString = [self sizeOfString:currentString withFont:aFont forWidth:nil].width,
|
||||
sizeLastChar = [self sizeOfString:lastChar withFont:aFont forWidth:nil].width;
|
||||
|
||||
if (sizeOfString - sizeLastChar / 2 < aPoint.x)
|
||||
position++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
|
||||
{
|
||||
if (!DOMFixedWidthSpanElement)
|
||||
|
||||
@@ -326,7 +326,7 @@ var themedButtonValues = nil,
|
||||
var button = [self button];
|
||||
|
||||
[button setTitle:@"OK"];
|
||||
[button setThemeState:[CPButtonStateBezelStyleRounded, CPThemeStateDefault]];
|
||||
[button setThemeStates:[CPButtonStateBezelStyleRounded, CPThemeStateDefault]];
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -232,7 +232,12 @@ var ItemSizes = { },
|
||||
state = attributeValueState[2];
|
||||
|
||||
if (state)
|
||||
[aView setValue:value forThemeAttribute:attribute inState:state];
|
||||
{
|
||||
if (state.isa && [state isKindOfClass:CPArray])
|
||||
[aView setValue:value forThemeAttribute:attribute inStates:state];
|
||||
else
|
||||
[aView setValue:value forThemeAttribute:attribute inState:state];
|
||||
}
|
||||
else
|
||||
[aView setValue:value forThemeAttribute:attribute];
|
||||
}
|
||||
@@ -304,7 +309,12 @@ var ItemSizes = { },
|
||||
}
|
||||
|
||||
if (state)
|
||||
[aView setValue:value forThemeAttribute:attribute inState:state];
|
||||
{
|
||||
if (state.isa && [state isKindOfClass:CPArray])
|
||||
[aView setValue:value forThemeAttribute:attribute inStates:state];
|
||||
else
|
||||
[aView setValue:value forThemeAttribute:attribute inState:state];
|
||||
}
|
||||
else
|
||||
[aView setValue:value forThemeAttribute:attribute];
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ blendKitTask = framework ("BlendKit", function(blendKitTask)
|
||||
blendKitTask.setFlattensSources(true); // FIXME: how do we non flatten?
|
||||
|
||||
if ($CONFIGURATION === "Release")
|
||||
blendKitTask.setCompilerFlags("-O");
|
||||
blendKitTask.setCompilerFlags("-O2");
|
||||
else
|
||||
blendKitTask.setCompilerFlags("-DDEBUG -g");
|
||||
});
|
||||
|
||||
@@ -171,9 +171,9 @@ var _CPAutocompleteMenuMaximumHeight = 307;
|
||||
|
||||
var dataView = [tableColumn dataView],
|
||||
fontNormal = [dataView valueForThemeAttribute:@"font" inState:CPThemeStateTableDataView],
|
||||
fontSelected = [dataView valueForThemeAttribute:@"font" inState:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]],
|
||||
fontSelected = [dataView valueForThemeAttribute:@"font" inStates:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]],
|
||||
contentInsetNormal = [dataView valueForThemeAttribute:@"content-inset" inState:CPThemeStateTableDataView],
|
||||
contentInsetSelected = [dataView valueForThemeAttribute:@"content-inset" inState:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]];
|
||||
contentInsetSelected = [dataView valueForThemeAttribute:@"content-inset" inStates:[CPThemeStateTableDataView, CPThemeStateSelectedDataView]];
|
||||
|
||||
var mergedString = contentArray.join("\n");
|
||||
|
||||
|
||||
+146
-47
@@ -23,8 +23,6 @@
|
||||
|
||||
@import "CPTheme.j"
|
||||
|
||||
var CachedThemeAttributes = nil;
|
||||
|
||||
var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
CPViewThemeStateKey = @"CPViewThemeStateKey";
|
||||
|
||||
@@ -38,8 +36,11 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
|
||||
- (unsigned)themeState;
|
||||
- (BOOL)hasThemeState:(ThemeState)aState;
|
||||
- (BOOL)hasThemeStates:(CPArray)states;
|
||||
- (BOOL)setThemeState:(ThemeState)aState;
|
||||
- (BOOL)setThemeStates:(CPArray)aState;
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState;
|
||||
- (BOOL)unsetThemeStates:(CPArray)aState;
|
||||
- (BOOL)hasThemeAttribute:(CPString)aName;
|
||||
|
||||
- (void)objectDidChangeTheme;
|
||||
@@ -74,31 +75,55 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
|
||||
- (BOOL)hasThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
return _themeState.hasThemeState.apply(_themeState, aState);
|
||||
#if DEBUG
|
||||
// TODO: To allow aState to be an array is now deprecated. An exception is thrown only in Debug version as
|
||||
// the preformance cost for this check is to high. We should remove this check in a future release.
|
||||
if (aState && aState.isa && [aState isKindOfClass:CPArray])
|
||||
[CPException raise:CPInvalidArgumentException reason:@"aState can't be an array. Please use 'hasThemeStates: instead: " + aState];
|
||||
#endif
|
||||
|
||||
return _themeState.hasThemeState(aState);
|
||||
}
|
||||
|
||||
- (BOOL)hasThemeStates:(CPArray)states
|
||||
{
|
||||
var i = [states count],
|
||||
aState = [states objectAtIndex:--i];
|
||||
|
||||
while (i > 0)
|
||||
aState = aState.and([states objectAtIndex:--i]);
|
||||
|
||||
return _themeState.hasThemeState(aState);
|
||||
}
|
||||
|
||||
- (BOOL)setThemeState:(ThemeState)aState
|
||||
{
|
||||
#if DEBUG
|
||||
// TODO: To allow aState to be an array is now deprecated. An exception is thrown only in Debug version as
|
||||
// the preformance cost for this check is to high. We should remove this check in a future release.
|
||||
if (aState && aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
[CPException raise:CPInvalidArgumentException reason:@"aState can't be an array. Please use 'setThemeStates: instead: " + aState];
|
||||
#endif
|
||||
|
||||
if (_themeState.hasThemeState(aState))
|
||||
return NO;
|
||||
|
||||
_themeState = CPThemeState(_themeState, aState);
|
||||
_themeState = _themeState.and(aState);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
#if DEBUG
|
||||
// TODO: To allow aState to be an array is now deprecated. An exception is thrown only in Debug version as
|
||||
// the preformance cost for this check is to high. We should remove this check in a future release.
|
||||
if (aState && aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
[CPException raise:CPInvalidArgumentException reason:@"aState can't be an array. Please use 'unsetThemeStates: instead: " + aState];
|
||||
#endif
|
||||
|
||||
var oldThemeState = _themeState;
|
||||
|
||||
_themeState = _themeState.without(aState);
|
||||
|
||||
if (oldThemeState === _themeState)
|
||||
@@ -107,6 +132,28 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)setThemeStates:(CPArray)states
|
||||
{
|
||||
var i = [states count],
|
||||
aState = [states objectAtIndex:--i];
|
||||
|
||||
while (i > 0)
|
||||
aState = aState.and([states objectAtIndex:--i]);
|
||||
|
||||
return [self setThemeState:aState];
|
||||
}
|
||||
|
||||
- (BOOL)unsetThemeStates:(CPArray)states
|
||||
{
|
||||
var i = [states count],
|
||||
aState = [states objectAtIndex:--i];
|
||||
|
||||
while (i > 0)
|
||||
aState = aState.and([states objectAtIndex:--i]);
|
||||
|
||||
return [self unsetThemeState:aState];
|
||||
}
|
||||
|
||||
#pragma mark Theme Attributes
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -134,25 +181,30 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
[self _loadThemeAttributes];
|
||||
}
|
||||
|
||||
+ (CPArray)_themeAttributes
|
||||
{
|
||||
if (!CachedThemeAttributes)
|
||||
CachedThemeAttributes = {};
|
||||
var NULL_THEME = {};
|
||||
|
||||
+ (CPArray)_themeAttributesForTheme:(CPTheme)theme andThemeClass:(CPString)themeClassName
|
||||
{
|
||||
var theClass = [self class],
|
||||
CPObjectClass = [CPObject class],
|
||||
attributes = [],
|
||||
nullValue = [CPNull null];
|
||||
theClassName = class_getName(theClass),
|
||||
themeClassNameCache = theme != nil ? theme._cachedThemeAttributes || (theme._cachedThemeAttributes = {}) : NULL_THEME,
|
||||
themedCacheAttributes = themeClassNameCache[themeClassName] || (themeClassNameCache[themeClassName] = {}),
|
||||
attributes = themedCacheAttributes[theClassName];
|
||||
|
||||
if (attributes)
|
||||
return attributes;
|
||||
else
|
||||
attributes = [];
|
||||
|
||||
var CPObjectClass = [CPObject class];
|
||||
|
||||
for (; theClass && theClass !== CPObjectClass; theClass = [theClass superclass])
|
||||
{
|
||||
var cachedAttributes = CachedThemeAttributes[class_getName(theClass)];
|
||||
var cachedAttributes = themedCacheAttributes[class_getName(theClass)];
|
||||
|
||||
if (cachedAttributes)
|
||||
{
|
||||
attributes = attributes.length ? attributes.concat(cachedAttributes) : attributes;
|
||||
CachedThemeAttributes[[self className]] = attributes;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -167,38 +219,34 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
while (attributeCount--)
|
||||
{
|
||||
var attributeName = attributeKeys[attributeCount],
|
||||
attributeValue = [attributeDictionary objectForKey:attributeName];
|
||||
attributeValue = [attributeDictionary objectForKey:attributeName],
|
||||
themeAttribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributeValue defaultAttribute:[theme attributeWithName:attributeName forClass:themeClassName]];
|
||||
|
||||
attributes.push(attributeValue === nullValue ? nil : attributeValue);
|
||||
attributes.push(attributeName);
|
||||
attributes.push(themeAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
themedCacheAttributes[theClassName] = attributes;
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (void)_loadThemeAttributes
|
||||
{
|
||||
var theClass = [self class],
|
||||
attributes = [theClass _themeAttributes],
|
||||
attributes = [theClass _themeAttributesForTheme:[self theme] andThemeClass:[self themeClass]],
|
||||
count = attributes.length;
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
var theme = [self theme],
|
||||
themeClass = [self themeClass];
|
||||
|
||||
_themeAttributes = {};
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var attributeName = attributes[count--],
|
||||
attribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributes[count]];
|
||||
var attribute = attributes[count];
|
||||
|
||||
[attribute setParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
|
||||
|
||||
_themeAttributes[attributeName] = attribute;
|
||||
_themeAttributes[attribute._name] = attribute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +276,7 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
for (var attributeName in _themeAttributes)
|
||||
{
|
||||
if (_themeAttributes.hasOwnProperty(attributeName))
|
||||
[_themeAttributes[attributeName] setParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
|
||||
_themeAttributes[attributeName] = [_themeAttributes[attributeName] attributeBySettingParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -253,48 +301,96 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
|
||||
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
#if DEBUG
|
||||
// TODO: To allow aState to be an array is now deprecated. An exception is thrown only in Debug version as
|
||||
// the preformance cost for this check is to high. We should remove this check in a future release.
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
[CPException raise:CPInvalidArgumentException reason:self + @": aState can't be an array. Please use 'setValue:forThemeAttribute:inStates:' instead: " + aState];
|
||||
#endif
|
||||
|
||||
if (!_themeAttributes || !_themeAttributes[aName])
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
[_themeAttributes[aName] setValue:aValue forState:aState];
|
||||
_themeAttributes[aName] = [themeAttr attributeBySettingValue:aValue forState:aState];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inStates:(CPArray)states
|
||||
{
|
||||
var i = [states count],
|
||||
aState = [states objectAtIndex:--i];
|
||||
|
||||
while (i > 0)
|
||||
aState = aState.and([states objectAtIndex:--i]);
|
||||
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
_themeAttributes[aName] = [themeAttr attributeBySettingValue:aValue forState:aState];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
|
||||
{
|
||||
if (!_themeAttributes || !_themeAttributes[aName])
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
[_themeAttributes[aName] setValue:aValue];
|
||||
_themeAttributes[aName] = [themeAttr attributeBySettingValue:aValue];
|
||||
}
|
||||
|
||||
- (id)valueForThemeAttribute:(CPString)aName inState:(ThemeState)aState
|
||||
{
|
||||
#if DEBUG
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
[CPException raise:CPInvalidArgumentException reason:@"aState can't be an array. Please use 'valueForThemeAttribute:inStates:' instead: " + aState];
|
||||
#endif
|
||||
|
||||
if (!_themeAttributes || !_themeAttributes[aName])
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
return [_themeAttributes[aName] valueForState:aState];
|
||||
return [themeAttr valueForState:aState];
|
||||
}
|
||||
|
||||
- (id)valueForThemeAttribute:(CPString)aName inStates:(CPArray)states
|
||||
{
|
||||
var i = [states count],
|
||||
aState = [states objectAtIndex:--i];
|
||||
|
||||
while (i > 0)
|
||||
aState = aState.and([states objectAtIndex:--i]);
|
||||
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
return [themeAttr valueForState:aState];
|
||||
}
|
||||
|
||||
- (id)valueForThemeAttribute:(CPString)aName
|
||||
{
|
||||
if (!_themeAttributes || !_themeAttributes[aName])
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
return [_themeAttributes[aName] value];
|
||||
return [themeAttr value];
|
||||
}
|
||||
|
||||
- (id)currentValueForThemeAttribute:(CPString)aName
|
||||
{
|
||||
if (!_themeAttributes || !_themeAttributes[aName])
|
||||
var themeAttr = _themeAttributes && _themeAttributes[aName];
|
||||
|
||||
if (!themeAttr)
|
||||
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
|
||||
|
||||
return [_themeAttributes[aName] valueForState:_themeState];
|
||||
return [themeAttr valueForState:_themeState];
|
||||
}
|
||||
|
||||
- (BOOL)hasThemeAttribute:(CPString)aName
|
||||
@@ -320,7 +416,10 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
state = attributeValueState[2];
|
||||
|
||||
if (state)
|
||||
[self setValue:value forThemeAttribute:attribute inState:state];
|
||||
if (state.isa && [state isKindOfClass:CPArray])
|
||||
[self setValue:value forThemeAttribute:attribute inStates:state];
|
||||
else
|
||||
[self setValue:value forThemeAttribute:attribute inState:state];
|
||||
else
|
||||
[self setValue:value forThemeAttribute:attribute];
|
||||
}
|
||||
@@ -367,14 +466,14 @@ var CPViewThemeClassKey = @"CPViewThemeClassKey",
|
||||
|
||||
var theClass = [self class],
|
||||
themeClass = [self themeClass],
|
||||
attributes = [theClass _themeAttributes],
|
||||
attributes = [theClass _themeAttributesForTheme:_theme andThemeClass:themeClass],
|
||||
count = attributes.length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var attributeName = attributes[count--];
|
||||
var attribute = attributes[count];
|
||||
|
||||
_themeAttributes[attributeName] = CPThemeAttributeDecode(aCoder, attributeName, attributes[count], _theme, themeClass);
|
||||
_themeAttributes[attribute._name] = CPThemeAttributeDecode(aCoder, attribute);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1552,7 +1552,7 @@ var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4,
|
||||
month = [[self monthSymbols] indexOfObject:dateComponent] + 1;
|
||||
}
|
||||
|
||||
if (month > 11 || length >= 5)
|
||||
if (month > 12 || length >= 5)
|
||||
return nil;
|
||||
|
||||
dateArray[1] = month;
|
||||
@@ -1580,7 +1580,7 @@ var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4,
|
||||
month = [[self standaloneMonthSymbols] indexOfObject:dateComponent] + 1;
|
||||
}
|
||||
|
||||
if (month > 11 || length >= 5)
|
||||
if (month > 12 || length >= 5)
|
||||
return nil;
|
||||
|
||||
dateArray[1] = month;
|
||||
|
||||
@@ -423,7 +423,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
setKey_method_imp(self, _cmd, anObject);
|
||||
|
||||
[self didChangeValueForKey:aKey];
|
||||
}, "");
|
||||
}, setKey_method.method_types);
|
||||
}
|
||||
|
||||
// FIXME: Deprecated.
|
||||
@@ -441,7 +441,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
_setKey_method_imp(self, _cmd, anObject);
|
||||
|
||||
[self didChangeValueForKey:aKey];
|
||||
}, "");
|
||||
}, _setKey_method.method_types);
|
||||
}
|
||||
|
||||
// Ordered To-Many Relationships
|
||||
@@ -478,7 +478,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeInsertion
|
||||
valuesAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, insertObject_inKeyAtIndex_method.method_types);
|
||||
}
|
||||
|
||||
if (insertKey_atIndexes_method)
|
||||
@@ -496,7 +496,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeInsertion
|
||||
valuesAtIndexes:[indexes copy]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, insertKey_atIndexes_method.method_types);
|
||||
}
|
||||
|
||||
if (removeObjectFromKeyAtIndex_method)
|
||||
@@ -514,7 +514,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeRemoval
|
||||
valuesAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, removeObjectFromKeyAtIndex_method.method_types);
|
||||
}
|
||||
|
||||
if (removeKeyAtIndexes_method)
|
||||
@@ -532,7 +532,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeRemoval
|
||||
valuesAtIndexes:[indexes copy]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, removeKeyAtIndexes_method.method_types);
|
||||
}
|
||||
|
||||
// These are optional.
|
||||
@@ -558,7 +558,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeReplacement
|
||||
valuesAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, replaceObjectInKeyAtIndex_withObject_method.method_types);
|
||||
}
|
||||
|
||||
var replaceKeyAtIndexes_withKey_selector =
|
||||
@@ -581,7 +581,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChange:CPKeyValueChangeReplacement
|
||||
valuesAtIndexes:[indexes copy]
|
||||
forKey:aKey];
|
||||
}, "");
|
||||
}, replaceKeyAtIndexes_withKey_method.method_types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +615,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChangeValueForKey:aKey
|
||||
withSetMutation:CPKeyValueUnionSetMutation
|
||||
usingObjects:[CPSet setWithObject:anObject]];
|
||||
}, "");
|
||||
}, addKeyObject_method.method_types);
|
||||
}
|
||||
|
||||
if (addKey_method)
|
||||
@@ -633,7 +633,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChangeValueForKey:aKey
|
||||
withSetMutation:CPKeyValueUnionSetMutation
|
||||
usingObjects:[objects copy]];
|
||||
}, "");
|
||||
}, addKey_method.method_types);
|
||||
}
|
||||
|
||||
if (removeKeyObject_method)
|
||||
@@ -651,7 +651,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChangeValueForKey:aKey
|
||||
withSetMutation:CPKeyValueMinusSetMutation
|
||||
usingObjects:[CPSet setWithObject:anObject]];
|
||||
}, "");
|
||||
}, removeKeyObject_method.method_types);
|
||||
}
|
||||
|
||||
if (removeKey_method)
|
||||
@@ -669,7 +669,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChangeValueForKey:aKey
|
||||
withSetMutation:CPKeyValueMinusSetMutation
|
||||
usingObjects:[objects copy]];
|
||||
}, "");
|
||||
}, removeKey_method.method_types);
|
||||
}
|
||||
|
||||
// intersect<Key>: is optional.
|
||||
@@ -691,7 +691,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
[self didChangeValueForKey:aKey
|
||||
withSetMutation:CPKeyValueIntersectSetMutation
|
||||
usingObjects:[aSet copy]];
|
||||
}, "");
|
||||
}, intersectKey_method.method_types);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ foundationTask = framework ("Foundation", function(foundationTask)
|
||||
INCLUDES = "--include \"../AppKit/Platform/Platform.h\" " + INCLUDES;
|
||||
|
||||
if ($CONFIGURATION === "Release")
|
||||
foundationTask.setCompilerFlags("-O " + INCLUDES);
|
||||
foundationTask.setCompilerFlags("-O2 " + INCLUDES);
|
||||
else
|
||||
foundationTask.setCompilerFlags("-DDEBUG -g " + INCLUDES);
|
||||
});
|
||||
|
||||
@@ -45,6 +45,23 @@ if (DOMBaseElementsCount > 0)
|
||||
pageURL = new CFURL(DOMBaseElementHref, pageURL);
|
||||
}
|
||||
|
||||
// Set compiler flags
|
||||
|
||||
if (typeof OBJJ_COMPILER_FLAGS !== 'undefined')
|
||||
{
|
||||
var flags = 0;
|
||||
for (var i = 0; i < OBJJ_COMPILER_FLAGS.length; i++)
|
||||
{
|
||||
var flag = ObjJAcornCompiler.Flags[OBJJ_COMPILER_FLAGS[i]];
|
||||
|
||||
if (flag != null)
|
||||
{
|
||||
flags |= flag;
|
||||
}
|
||||
}
|
||||
exports.setCurrentCompilerFlags(flags);
|
||||
}
|
||||
|
||||
// Turn the main file into a URL.
|
||||
var mainFileURL = new CFURL(window.OBJJ_MAIN_FILE || "main.j"),
|
||||
|
||||
|
||||
Regular → Executable
+29
-8
@@ -104,7 +104,8 @@ GLOBAL(CFHTTPRequest) = function()
|
||||
this._nativeRequest = new NativeRequest();
|
||||
|
||||
// by default, all requests will assume that credentials should not be sent.
|
||||
this._nativeRequest.withCredentials = false;
|
||||
this._withCredentials = false;
|
||||
this._timeout = 60000;
|
||||
|
||||
var self = this;
|
||||
this._stateChangeHandler = function()
|
||||
@@ -217,12 +218,15 @@ CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
|
||||
|
||||
CFHTTPRequest.prototype.setTimeout = function(/*int*/ aTimeout)
|
||||
{
|
||||
this._nativeRequest.timeout = aTimeout;
|
||||
this._timeout = aTimeout;
|
||||
|
||||
if (this._isOpen)
|
||||
this._nativeRequest.timeout = aTimeout;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.getTimeout = function(/*int*/ aTimeout)
|
||||
{
|
||||
return this._nativeRequest.timeout;
|
||||
return this._timeout;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.getAllResponseHeaders = function()
|
||||
@@ -237,13 +241,24 @@ CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType)
|
||||
|
||||
CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword)
|
||||
{
|
||||
var retval;
|
||||
|
||||
this._isOpen = true;
|
||||
this._URL = aURL;
|
||||
this._async = isAsynchronous;
|
||||
this._method = aMethod;
|
||||
this._user = aUser;
|
||||
this._password = aPassword;
|
||||
return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword);
|
||||
|
||||
requestReturnValue = this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword);
|
||||
|
||||
if (this._async)
|
||||
{
|
||||
this._nativeRequest.withCredentials = this._withCredentials;
|
||||
this._nativeRequest.timeout = this._timeout;
|
||||
}
|
||||
|
||||
return requestReturnValue;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
|
||||
@@ -283,6 +298,7 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
|
||||
CFHTTPRequest.prototype.abort = function()
|
||||
{
|
||||
this._isOpen = false;
|
||||
|
||||
return this._nativeRequest.abort();
|
||||
};
|
||||
|
||||
@@ -298,12 +314,15 @@ CFHTTPRequest.prototype.removeEventListener = function(/*String*/ anEventName, /
|
||||
|
||||
CFHTTPRequest.prototype.setWithCredentials = function(/*Boolean*/ willSendWithCredentials)
|
||||
{
|
||||
this._nativeRequest.withCredentials = willSendWithCredentials;
|
||||
this._withCredentials = willSendWithCredentials;
|
||||
|
||||
if (this._isOpen && this._async)
|
||||
this._nativeRequest.withCredentials = willSendWithCredentials;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.withCredentials = function()
|
||||
{
|
||||
return this._nativeRequest.withCredentials;
|
||||
return this._withCredentials;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.isTimeoutRequest = function()
|
||||
@@ -320,7 +339,6 @@ function dispatchTimeoutHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
|
||||
function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
|
||||
{
|
||||
var eventDispatcher = aRequest._eventDispatcher,
|
||||
nativeRequest = aRequest._nativeRequest,
|
||||
readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
|
||||
|
||||
eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest});
|
||||
@@ -336,7 +354,9 @@ function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
|
||||
eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
|
||||
}
|
||||
else
|
||||
{
|
||||
eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
|
||||
}
|
||||
}
|
||||
|
||||
function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
|
||||
@@ -351,7 +371,7 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
|
||||
{
|
||||
var aFilePath = aURL.toString().substring(5),
|
||||
OS = require("os"),
|
||||
gccFlags = require("objective-j").currentCompilerFlags(),
|
||||
gccFlags = require("objective-j").currentGccCompilerFlags(),
|
||||
chunk,
|
||||
fileContents = "";
|
||||
|
||||
@@ -377,6 +397,7 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
|
||||
{
|
||||
onfailure({request: request});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -90,11 +90,14 @@ exports.run = function(args)
|
||||
if (argv[0] === "--help" || argv[0] === "-h")
|
||||
{
|
||||
print("Usage (objj): " + args[0] + " [options] [--] files...");
|
||||
print(" -v, --version print the current version of objj");
|
||||
print(" -I, --objj-include-paths include a specific framework paths")
|
||||
print(" -h, --help print this help");
|
||||
print(" -m, --multifiles launch objj on several files")
|
||||
print(" -x, --xml specify the output format in xml.")
|
||||
print(" -v, --version print the current version of objj");
|
||||
print(" -I, --objj-include-paths include a specific framework paths")
|
||||
print(" -h, --help print this help");
|
||||
print(" -m, --multifiles launch objj on several files")
|
||||
print(" -x, --xml specify the output format in xml.")
|
||||
print(" -g, --include-debug-symbols Include debug symbols when compiling.")
|
||||
print(" -T, --dont-include-type-signatures Do not include type signatures when compiling.")
|
||||
print(" -O2, --inline-msg-send Inline objj_msgSend function when compiling.")
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,6 +122,24 @@ exports.run = function(args)
|
||||
argv.shift();
|
||||
exports.outputFormatInXML = true;
|
||||
break;
|
||||
|
||||
case "-g":
|
||||
case "--include-debug-symbols":
|
||||
argv.shift();
|
||||
(OBJJ_COMPILER_FLAGS || (OBJJ_COMPILER_FLAGS = [])).push("IncludeDebugSymbols");
|
||||
break;
|
||||
|
||||
case "-T":
|
||||
case "--dont-include-type-signatures":
|
||||
argv.shift();
|
||||
(OBJJ_COMPILER_FLAGS || (OBJJ_COMPILER_FLAGS = [])).push("IncludeTypeSignatures");
|
||||
break;
|
||||
|
||||
case "-O2":
|
||||
case "--inline-msg-send":
|
||||
argv.shift();
|
||||
(OBJJ_COMPILER_FLAGS || (OBJJ_COMPILER_FLAGS = [])).push("InlineMsgSend");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,13 +187,17 @@ function resolveFlags(args)
|
||||
objjcFlags &= ~ObjectiveJ.ObjJAcornCompiler.Flags.CheckSyntax;
|
||||
|
||||
else if (argument.indexOf("-T") === 0)
|
||||
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures;
|
||||
objjcFlags &= ~ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures;
|
||||
|
||||
else if (argument.indexOf("-g") === 0)
|
||||
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.IncludeDebugSymbols;
|
||||
|
||||
else if (argument.indexOf("-O") === 0)
|
||||
else if (argument.indexOf("-O") === 0) {
|
||||
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.Compress;
|
||||
// FIXME: currently we are sending in '-O2' when we want InlineMsgSend. Here we only check if we it is '-O...'
|
||||
if (argument.length > 2)
|
||||
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.InlineMsgSend;
|
||||
}
|
||||
|
||||
else if (argument.indexOf("-G") === 0)
|
||||
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.Generate;
|
||||
@@ -255,12 +259,16 @@ exports.main = function(args)
|
||||
if (argv[0] === "--help" || argv[0].substr(0, 1) == '-')
|
||||
{
|
||||
print("Usage (objjc 2.0): " + args[0] + " [options] [--] file...");
|
||||
print(" -p, --print print the output directly to stdout");
|
||||
print(" --unmarked don't tag the output with @STATIC header");
|
||||
print(" -p, --print print the output directly to stdout");
|
||||
print(" --unmarked don't tag the output with @STATIC header");
|
||||
print("");
|
||||
print(" -T, --includeTypeSignatures include type signatures in the compiled output");
|
||||
print(" -T, --dont-include-type-signatures include type signatures in the compiled output");
|
||||
print(" -g, --include-debug-symbols include debug symbols in the compiled output");
|
||||
print(" -T, --include-type-signatures include type signatures in the compiled output");
|
||||
print(" -O, --compress compress the compiled output");
|
||||
print(" -O2, --inline-msg-send inline objj_msgSend function in the compiled output");
|
||||
print("");
|
||||
print(" --help print this help");
|
||||
print(" --help print this help");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -907,7 +907,7 @@ BundleTask.prototype.defineSourceTasks = function()
|
||||
basePath = absolutePath.substring(0, absolutePath.length - theTranslatedFilename.length);
|
||||
|
||||
// Here we set the current compiler flags so the load system will know what compiler flags to use
|
||||
ObjectiveJ.setCurrentCompilerFlags(environmentCompilerFlags);
|
||||
ObjectiveJ.setCurrentGccCompilerFlags(environmentCompilerFlags);
|
||||
// Here we tell the CFBundle to load frameworks for the current build enviroment and not the enviroment that is running
|
||||
CFBundle.environments = function() {return [anEnvironment.name(), "ObjJ"]};
|
||||
ObjectiveJ.make_narwhal_factory(absolutePath, basePath, translateFilenameToPath)(require, e, module, system, print);
|
||||
|
||||
@@ -185,7 +185,7 @@ GLOBAL(objj_typecheck_decorator) = function(msgSend)
|
||||
if (!aReceiver)
|
||||
return msgSend.apply(this, arguments);
|
||||
|
||||
var types = aReceiver.isa.method_dtable[aSelector].types;
|
||||
var types = aReceiver.isa.method_dtable[aSelector].method_types;
|
||||
for (var i = 2; i < arguments.length; i++)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -41,7 +41,7 @@ function FileExecutable(/*CFURL|String*/ aURL, /*Dictionary*/ aFilenameTranslate
|
||||
if (fileContents.match(/^@STATIC;/))
|
||||
executable = decompile(fileContents, aURL);
|
||||
else if ((extension === "j" || !extension) && !fileContents.match(/^{/))
|
||||
executable = exports.ObjJAcornCompiler.compileFileDependencies(fileContents, aURL, ObjJAcornCompiler.Flags.IncludeDebugSymbols);
|
||||
executable = exports.ObjJAcornCompiler.compileFileDependencies(fileContents, aURL, exports.currentCompilerFlags());
|
||||
else
|
||||
executable = new Executable(fileContents, [], aURL);
|
||||
|
||||
|
||||
@@ -365,8 +365,6 @@ var MethodDef = function(name, types)
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
var currentCompilerFlags = "";
|
||||
|
||||
var reservedIdentifiers = exports.acorn.makePredicate("self _cmd undefined localStorage arguments");
|
||||
|
||||
var wordPrefixOperators = exports.acorn.makePredicate("delete in instanceof new typeof void");
|
||||
@@ -414,18 +412,26 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*
|
||||
}
|
||||
|
||||
this.dependencies = [];
|
||||
this.flags = flags | ObjJAcornCompiler.Flags.IncludeDebugSymbols;
|
||||
this.flags = flags & (ObjJAcornCompiler.Flags.IncludeDebugSymbols | ObjJAcornCompiler.Flags.InlineMsgSend | ObjJAcornCompiler.Flags.IncludeTypeSignatures);
|
||||
this.classDefs = classDefs ? classDefs : Object.create(null);
|
||||
this.protocolDefs = protocolDefs ? protocolDefs : Object.create(null);
|
||||
this.typeDefs = typeDefs ? typeDefs : Object.create(null);
|
||||
this.lastPos = 0;
|
||||
if (currentCompilerFlags & ObjJAcornCompiler.Flags.Generate)
|
||||
this.generate = true;
|
||||
this.generate = true;
|
||||
this.generate = true; // Before there was an option to generate the code or copy & paste it from the source. Today we always generate the code.
|
||||
|
||||
compile(this.tokens, new Scope(null ,{ compiler: this }), pass === 2 ? pass2 : pass1);
|
||||
}
|
||||
|
||||
ObjJAcornCompiler.Flags = { };
|
||||
|
||||
ObjJAcornCompiler.Flags.IncludeDebugSymbols = 1 << 0;
|
||||
ObjJAcornCompiler.Flags.IncludeTypeSignatures = 1 << 1;
|
||||
ObjJAcornCompiler.Flags.Generate = 1 << 2;
|
||||
ObjJAcornCompiler.Flags.InlineMsgSend = 1 << 3;
|
||||
|
||||
var currentCompilerFlags = ObjJAcornCompiler.Flags.IncludeTypeSignatures;
|
||||
var currentGccCompilerFlags = "";
|
||||
|
||||
exports.ObjJAcornCompiler = ObjJAcornCompiler;
|
||||
|
||||
exports.ObjJAcornCompiler.compileToExecutable = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*/ flags)
|
||||
@@ -487,7 +493,42 @@ ObjJAcornCompiler.prototype.compilePass2 = function()
|
||||
return this.jsBuffer.toString();
|
||||
}
|
||||
|
||||
var currentCompilerFlags = "";
|
||||
exports.setCurrentGccCompilerFlags = function(/*String*/ compilerFlags)
|
||||
{
|
||||
if (currentGccCompilerFlags === compilerFlags) return;
|
||||
|
||||
currentGccCompilerFlags = compilerFlags;
|
||||
|
||||
var args = compilerFlags.split(" "),
|
||||
count = args.length,
|
||||
objjcFlags = ObjJAcornCompiler.Flags.IncludeTypeSignatures;
|
||||
|
||||
for (var index = 0; index < count; ++index)
|
||||
{
|
||||
var argument = args[index];
|
||||
|
||||
if (argument.indexOf("-g") === 0)
|
||||
objjcFlags |= ObjJAcornCompiler.Flags.IncludeDebugSymbols;
|
||||
else if (argument.indexOf("-O") === 0) {
|
||||
objjcFlags |= ObjJAcornCompiler.Flags.Compress;
|
||||
// FIXME: currently we are sending in '-O2' when we want InlineMsgSend. Here we only check if it is '-O...'.
|
||||
// Maybe we should have some other option for this
|
||||
if (argument.length > 2)
|
||||
objjcFlags |= ObjJAcornCompiler.Flags.InlineMsgSend;
|
||||
}
|
||||
else if (argument.indexOf("-G") === 0)
|
||||
objjcFlags |= ObjJAcornCompiler.Flags.Generate;
|
||||
else if (argument.indexOf("-T") === 0)
|
||||
objjcFlags &= ~ObjJAcornCompiler.Flags.IncludeTypeSignatures;
|
||||
}
|
||||
|
||||
currentCompilerFlags = objjcFlags;
|
||||
}
|
||||
|
||||
exports.currentGccCompilerFlags = function(/*String*/ compilerFlags)
|
||||
{
|
||||
return currentGccCompilerFlags;
|
||||
}
|
||||
|
||||
exports.setCurrentCompilerFlags = function(/*String*/ compilerFlags)
|
||||
{
|
||||
@@ -499,12 +540,6 @@ exports.currentCompilerFlags = function(/*String*/ compilerFlags)
|
||||
return currentCompilerFlags;
|
||||
}
|
||||
|
||||
ObjJAcornCompiler.Flags = { };
|
||||
|
||||
ObjJAcornCompiler.Flags.IncludeDebugSymbols = 1 << 0;
|
||||
ObjJAcornCompiler.Flags.IncludeTypeSignatures = 1 << 1;
|
||||
ObjJAcornCompiler.Flags.Generate = 1 << 2;
|
||||
|
||||
ObjJAcornCompiler.prototype.addWarning = function(/* Warning */ aWarning)
|
||||
{
|
||||
this.warnings.push(aWarning);
|
||||
@@ -1626,64 +1661,170 @@ Literal: function(node, st, c) {
|
||||
},
|
||||
ArrayLiteral: function(node, st, c) {
|
||||
var compiler = st.compiler,
|
||||
generate = compiler.generate;
|
||||
generate = compiler.generate,
|
||||
buffer = compiler.jsBuffer;
|
||||
|
||||
if (!generate) {
|
||||
compiler.jsBuffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
compiler.lastPos = node.start;
|
||||
}
|
||||
|
||||
if (!generate) buffer.concat(" "); // Add an extra space if it looks something like this: "return(<expression>)". No space between return and expression.
|
||||
if (!st.receiverLevel) st.receiverLevel = 0;
|
||||
if (!node.elements.length) {
|
||||
compiler.jsBuffer.concat("objj_msgSend(objj_msgSend(CPArray, \"alloc\"), \"init\")");
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.InlineMsgSend) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPArray.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : (___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.method_msgSend[\"init\"] || _objj_forward)(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"init\"))");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPArray.isa.objj_msgSend0(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.objj_msgSend0(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"init\"))");
|
||||
}
|
||||
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
} else {
|
||||
compiler.jsBuffer.concat("objj_msgSend(objj_msgSend(CPArray, \"alloc\"), \"initWithObjects:count:\", [");
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.InlineMsgSend) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPArray.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : (___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.method_msgSend[\"initWithObjects:count:\"] || _objj_forward)(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:count:\", [");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPArray.isa.objj_msgSend0(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.objj_msgSend2(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:count:\", [");
|
||||
}
|
||||
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
|
||||
for (var i = 0; i < node.elements.length; i++) {
|
||||
var elt = node.elements[i];
|
||||
|
||||
if (i)
|
||||
compiler.jsBuffer.concat(", ");
|
||||
buffer.concat(", ");
|
||||
|
||||
if (!generate) compiler.lastPos = elt.start;
|
||||
c(elt, st, "Expression");
|
||||
if (!generate) compiler.jsBuffer.concat(compiler.source.substring(compiler.lastPos, elt.end));
|
||||
if (!generate) buffer.concat(compiler.source.substring(compiler.lastPos, elt.end));
|
||||
}
|
||||
compiler.jsBuffer.concat("], " + node.elements.length + ")");
|
||||
buffer.concat("], " + node.elements.length + "))");
|
||||
}
|
||||
|
||||
st.receiverLevel--;
|
||||
if (!generate) compiler.lastPos = node.end;
|
||||
},
|
||||
DictionaryLiteral: function(node, st, c) {
|
||||
var compiler = st.compiler,
|
||||
generate = compiler.generate;
|
||||
generate = compiler.generate,
|
||||
buffer = compiler.jsBuffer,
|
||||
noOfKeys = node.keys.length;
|
||||
|
||||
if (!generate) {
|
||||
compiler.jsBuffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
compiler.lastPos = node.start;
|
||||
}
|
||||
|
||||
if (!generate) buffer.concat(" "); // Add an extra space if it looks something like this: "return(<expression>)". No space between return and expression.
|
||||
if (!node.keys.length) {
|
||||
compiler.jsBuffer.concat("objj_msgSend(objj_msgSend(CPDictionary, \"alloc\"), \"init\")");
|
||||
if (!st.receiverLevel) st.receiverLevel = 0;
|
||||
if (!noOfKeys) {
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.InlineMsgSend) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPDictionary.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : (___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.method_msgSend[\"init\"] || _objj_forward)(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"init\"))");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPDictionary.isa.objj_msgSend0(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.objj_msgSend0(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"init\"))");
|
||||
}
|
||||
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
} else {
|
||||
compiler.jsBuffer.concat("objj_msgSend(objj_msgSend(CPDictionary, \"alloc\"), \"initWithObjectsAndKeys:\"");
|
||||
for (var i = 0; i < node.keys.length; i++) {
|
||||
var key = node.keys[i],
|
||||
value = node.values[i];
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.InlineMsgSend) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPDictionary.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : (___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.method_msgSend[\"initWithObjects:forKeys:\"] || _objj_forward)(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:forKeys:\", [");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPDictionary.isa.objj_msgSend0(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(".isa.objj_msgSend2(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:forKeys:\", [");
|
||||
}
|
||||
|
||||
compiler.jsBuffer.concat(", ");
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
|
||||
for (var i = 0; i < noOfKeys; i++) {
|
||||
var value = node.values[i];
|
||||
|
||||
if (i) buffer.concat(", ");
|
||||
if (!generate) compiler.lastPos = value.start;
|
||||
c(value, st, "Expression");
|
||||
if (!generate) compiler.jsBuffer.concat(compiler.source.substring(compiler.lastPos, value.end));
|
||||
if (!generate) buffer.concat(compiler.source.substring(compiler.lastPos, value.end));
|
||||
}
|
||||
|
||||
compiler.jsBuffer.concat(", ");
|
||||
buffer.concat("], [");
|
||||
|
||||
for (var i = 0; i < noOfKeys; i++) {
|
||||
var key = node.keys[i];
|
||||
|
||||
if (i) buffer.concat(", ");
|
||||
if (!generate) compiler.lastPos = key.start;
|
||||
c(key, st, "Expression");
|
||||
if (!generate) compiler.jsBuffer.concat(compiler.source.substring(compiler.lastPos, key.end));
|
||||
if (!generate) buffer.concat(compiler.source.substring(compiler.lastPos, key.end));
|
||||
}
|
||||
compiler.jsBuffer.concat(")");
|
||||
buffer.concat("]))");
|
||||
}
|
||||
|
||||
st.receiverLevel--;
|
||||
if (!generate) compiler.lastPos = node.end;
|
||||
},
|
||||
ImportStatement: function(node, st, c) {
|
||||
@@ -2184,7 +2325,7 @@ MethodDeclarationStatement: function(node, st, c) {
|
||||
compiler.jsBuffer.concat("Nil\n");
|
||||
}
|
||||
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.IncludeDebugSymbols)
|
||||
if (compiler.flags & ObjJAcornCompiler.Flags.IncludeTypeSignatures)
|
||||
compiler.jsBuffer.concat(","+JSON.stringify(types));
|
||||
|
||||
compiler.jsBuffer.concat(")");
|
||||
@@ -2257,17 +2398,48 @@ MethodDeclarationStatement: function(node, st, c) {
|
||||
MessageSendExpression: function(node, st, c) {
|
||||
var compiler = st.compiler,
|
||||
generate = compiler.generate,
|
||||
inlineMsgSend = compiler.flags & ObjJAcornCompiler.Flags.InlineMsgSend,
|
||||
buffer = compiler.jsBuffer,
|
||||
nodeObject = node.object;
|
||||
nodeObject = node.object,
|
||||
selectors = node.selectors,
|
||||
arguments = node.arguments,
|
||||
argumentsLength = arguments.length,
|
||||
firstSelector = selectors[0],
|
||||
selector = firstSelector ? firstSelector.name : ""; // There is always at least one selector
|
||||
|
||||
// Put together the selector. Maybe this should be done in the parser...
|
||||
for (var i = 0; i < argumentsLength; i++)
|
||||
if (i === 0)
|
||||
selector += ":";
|
||||
else
|
||||
selector += (selectors[i] ? selectors[i].name : "") + ":";
|
||||
|
||||
if (!generate) {
|
||||
buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
compiler.lastPos = nodeObject ? nodeObject.start : node.arguments.length ? node.arguments[0].start : node.end;
|
||||
} else if (!inlineMsgSend) {
|
||||
// Find out the total number of arguments so we can choose appropriate msgSend function. Only needed if call the function and not inline it
|
||||
var totalNoOfParameters = argumentsLength;
|
||||
|
||||
if (node.parameters)
|
||||
totalNoOfParameters += node.parameters.length;
|
||||
}
|
||||
if (node.superObject)
|
||||
{
|
||||
if (!generate) buffer.concat(" "); // Add an extra space if it looks something like this: "return(<expression>)". No space between return and expression.
|
||||
buffer.concat("objj_msgSendSuper(");
|
||||
buffer.concat("{ receiver:self, super_class:" + (st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass ) + " }");
|
||||
if (inlineMsgSend) {
|
||||
buffer.concat("(");
|
||||
buffer.concat(st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass);
|
||||
buffer.concat(".method_dtable[\"");
|
||||
buffer.concat(selector);
|
||||
buffer.concat("\"] || _objj_forward)(self");
|
||||
} else {
|
||||
buffer.concat("objj_msgSendSuper");
|
||||
if (totalNoOfParameters < 4) {
|
||||
buffer.concat("" + totalNoOfParameters);
|
||||
}
|
||||
buffer.concat("({ receiver:self, super_class:" + (st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass ) + " }");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2293,6 +2465,8 @@ MessageSendExpression: function(node, st, c) {
|
||||
c(nodeObject, st, "Expression");
|
||||
buffer.concat(" == null ? null : ");
|
||||
}
|
||||
if (inlineMsgSend)
|
||||
buffer.concat("(");
|
||||
c(nodeObject, st, "Expression");
|
||||
} else {
|
||||
receiverIsNotSelf = true;
|
||||
@@ -2303,12 +2477,20 @@ MessageSendExpression: function(node, st, c) {
|
||||
c(nodeObject, st, "Expression");
|
||||
buffer.concat("), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ___r");
|
||||
buffer.concat(" == null ? null : ");
|
||||
if (inlineMsgSend)
|
||||
buffer.concat("(");
|
||||
buffer.concat("___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
}
|
||||
buffer.concat(".isa.objj_msgSend");
|
||||
if (inlineMsgSend) {
|
||||
buffer.concat(".isa.method_msgSend[\"");
|
||||
buffer.concat(selector);
|
||||
buffer.concat("\"] || _objj_forward)");
|
||||
} else
|
||||
buffer.concat(".isa.objj_msgSend");
|
||||
} else {
|
||||
buffer.concat(" "); // Add an extra space if it looks something like this: "return(<expression>)". No space between return and expression.
|
||||
buffer.concat("objj_msgSend(");
|
||||
@@ -2316,19 +2498,11 @@ MessageSendExpression: function(node, st, c) {
|
||||
}
|
||||
}
|
||||
|
||||
var selectors = node.selectors,
|
||||
arguments = node.arguments,
|
||||
argumentsLength = arguments.length,
|
||||
firstSelector = selectors[0],
|
||||
selector = firstSelector ? firstSelector.name : ""; // There is always at least one selector
|
||||
|
||||
if (generate && !node.superObject) {
|
||||
var totalNoOfParameters = argumentsLength;
|
||||
|
||||
if (node.parameters)
|
||||
totalNoOfParameters += node.parameters.length;
|
||||
if (totalNoOfParameters < 4) {
|
||||
buffer.concat("" + totalNoOfParameters);
|
||||
if (!inlineMsgSend) {
|
||||
if (totalNoOfParameters < 4) {
|
||||
buffer.concat("" + totalNoOfParameters);
|
||||
}
|
||||
}
|
||||
|
||||
if (receiverIsIdentifier) {
|
||||
@@ -2340,13 +2514,6 @@ MessageSendExpression: function(node, st, c) {
|
||||
}
|
||||
}
|
||||
|
||||
// Put together the selector. Maybe this should be done in the parser...
|
||||
for (var i = 0; i < argumentsLength; i++)
|
||||
if (i === 0)
|
||||
selector += ":";
|
||||
else
|
||||
selector += (selectors[i] ? selectors[i].name : "") + ":";
|
||||
|
||||
buffer.concat(", \"");
|
||||
buffer.concat(selector); // FIXME: sel_getUid(selector + "") ? This FIXME is from the old preprocessor compiler
|
||||
buffer.concat("\"");
|
||||
|
||||
+124
-42
@@ -49,9 +49,12 @@ GLOBAL(objj_ivar) = function(/*String*/ aName, /*String*/ aType)
|
||||
|
||||
GLOBAL(objj_method) = function(/*String*/ aName, /*IMP*/ anImplementation, /*Array<String>*/ types)
|
||||
{
|
||||
this.name = aName;
|
||||
this.method_imp = anImplementation;
|
||||
this.types = types;
|
||||
var method = anImplementation || function(/*id*/ aReceiver, /*SEL*/ aSelector) {CPException.isa.objj_msgSend2(CPException, "raise:reason:", CPInternalInconsistencyException, aReceiver.isa.method_msgSend0(self, "className") + " does not have an implementation for selector '" + aSelector + "'")};
|
||||
method.method_name = aName;
|
||||
method.method_imp = anImplementation;
|
||||
method.method_types = types;
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
GLOBAL(objj_class) = function(displayName)
|
||||
@@ -197,7 +200,7 @@ GLOBAL(class_addMethod) = function(/*Class*/ aClass, /*SEL*/ aName, /*IMP*/ anIm
|
||||
|
||||
#if DEBUG
|
||||
// Give this function a "pretty" name for the console.
|
||||
method.method_imp.displayName = METHOD_DISPLAY_NAME(aClass, method);
|
||||
method.displayName = METHOD_DISPLAY_NAME(aClass, method);
|
||||
#endif
|
||||
|
||||
// FIXME: Should this be done here?
|
||||
@@ -222,11 +225,11 @@ GLOBAL(class_addMethods) = function(/*Class*/ aClass, /*Array*/ methods)
|
||||
|
||||
// FIXME: Don't do it if it exists?
|
||||
method_list.push(method);
|
||||
method_dtable[method.name] = method;
|
||||
method_dtable[method.method_name] = method;
|
||||
|
||||
#if DEBUG
|
||||
// Give this function a "pretty" name for the console.
|
||||
method.method_imp.displayName = METHOD_DISPLAY_NAME(aClass, method);
|
||||
method.displayName = METHOD_DISPLAY_NAME(aClass, method);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -292,12 +295,22 @@ GLOBAL(class_replaceMethod) = function(/*Class*/ aClass, /*SEL*/ aSelector, /*IM
|
||||
return NULL;
|
||||
|
||||
var method = aClass.method_dtable[aSelector],
|
||||
method_imp = NULL;
|
||||
method_imp = method.method_imp,
|
||||
new_method = new objj_method(method.method_name, aMethodImplementation, method.method_types);
|
||||
|
||||
if (method)
|
||||
method_imp = method.method_imp;
|
||||
new_method.displayName = method.displayName;
|
||||
aClass.method_dtable[aSelector] = new_method;
|
||||
|
||||
method.method_imp = aMethodImplementation;
|
||||
var index = aClass.method_list.indexOf(method);
|
||||
|
||||
if (index !== -1)
|
||||
{
|
||||
aClass.method_list[index] = new_method;
|
||||
}
|
||||
else
|
||||
{
|
||||
aClass.method_list.push(new_method);
|
||||
}
|
||||
|
||||
return method_imp;
|
||||
}
|
||||
@@ -419,7 +432,7 @@ GLOBAL(protocol_addMethodDescriptions) = function(/*Protocol*/ proto, /*Array*/
|
||||
{
|
||||
var method = methods[index];
|
||||
|
||||
method_dtable[method.name] = method;
|
||||
method_dtable[method.method_name] = method;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,26 +504,43 @@ var _class_initialize = function(/*Class*/ aClass)
|
||||
meta.objj_msgSend2 = objj_msgSendFast2;
|
||||
meta.objj_msgSend3 = objj_msgSendFast3;
|
||||
|
||||
aClass.method_msgSend = aClass.method_dtable;
|
||||
meta.method_msgSend = meta.method_dtable;
|
||||
|
||||
meta.objj_msgSend0(aClass, "initialize");
|
||||
|
||||
CHANGEINFO(meta, CLS_INITIALIZED, CLS_INITIALIZING);
|
||||
}
|
||||
}
|
||||
|
||||
var _objj_forward = function(self, _cmd)
|
||||
GLOBAL(_objj_forward) = function(self, _cmd)
|
||||
{
|
||||
var isa = self.isa,
|
||||
implementation = isa.method_dtable[SEL_forwardingTargetForSelector_];
|
||||
meta = GETMETA(isa);
|
||||
|
||||
if (!GETINFO(meta, CLS_INITIALIZED) && !GETINFO(meta, CLS_INITIALIZING))
|
||||
{
|
||||
_class_initialize(isa);
|
||||
}
|
||||
|
||||
var implementation = isa.method_msgSend[_cmd];
|
||||
|
||||
if (implementation)
|
||||
{
|
||||
var target = implementation.method_imp.call(this, self, SEL_forwardingTargetForSelector_, _cmd);
|
||||
return implementation.apply(isa, arguments);
|
||||
}
|
||||
|
||||
implementation = isa.method_dtable[SEL_forwardingTargetForSelector_];
|
||||
|
||||
if (implementation)
|
||||
{
|
||||
var target = implementation(self, SEL_forwardingTargetForSelector_, _cmd);
|
||||
|
||||
if (target && target !== self)
|
||||
{
|
||||
arguments[0] = target;
|
||||
|
||||
return objj_msgSend.apply(this, arguments);
|
||||
return target.isa.objj_msgSend.apply(target.isa, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +552,7 @@ var _objj_forward = function(self, _cmd)
|
||||
|
||||
if (forwardInvocationImplementation)
|
||||
{
|
||||
var signature = implementation.method_imp.call(this, self, SEL_methodSignatureForSelector_, _cmd);
|
||||
var signature = implementation(self, SEL_methodSignatureForSelector_, _cmd);
|
||||
|
||||
if (signature)
|
||||
{
|
||||
@@ -541,7 +571,7 @@ var _objj_forward = function(self, _cmd)
|
||||
invocationIsa.objj_msgSend2(invocation, SEL_setArgument_atIndex_, arguments[index], index);
|
||||
}
|
||||
|
||||
forwardInvocationImplementation.method_imp.call(this, self, SEL_forwardInvocation_, invocation);
|
||||
forwardInvocationImplementation(self, SEL_forwardInvocation_, invocation);
|
||||
|
||||
return invocation == null ? null : invocationIsa.objj_msgSend0(invocation, SEL_returnValue);
|
||||
}
|
||||
@@ -552,7 +582,7 @@ var _objj_forward = function(self, _cmd)
|
||||
implementation = isa.method_dtable[SEL_doesNotRecognizeSelector_];
|
||||
|
||||
if (implementation)
|
||||
return implementation.method_imp.call(this, self, SEL_doesNotRecognizeSelector_, _cmd);
|
||||
return implementation(self, SEL_doesNotRecognizeSelector_, _cmd);
|
||||
|
||||
throw class_getName(isa) + " does not implement doesNotRecognizeSelector:. Did you forget a superclass for " + class_getName(isa) + "?";
|
||||
};
|
||||
@@ -562,9 +592,7 @@ var _objj_forward = function(self, _cmd)
|
||||
if (!ISINITIALIZED(aClass))\
|
||||
_class_initialize(aClass);\
|
||||
\
|
||||
var method = aClass.method_dtable[aSelector];\
|
||||
\
|
||||
aMethodImplementation = method ? method.method_imp : _objj_forward;
|
||||
aMethodImplementation = aClass.method_dtable[aSelector] || _objj_forward;
|
||||
|
||||
GLOBAL(class_getMethodImplementation) = function(/*Class*/ aClass, /*SEL*/ aSelector)
|
||||
{
|
||||
@@ -845,11 +873,28 @@ GLOBAL(objj_msgSendSuper) = function(/*id*/ aSuper, /*SEL*/ aSelector)
|
||||
return implementation.apply(aSuper.receiver, arguments);
|
||||
}
|
||||
|
||||
GLOBAL(objj_msgSendSuper0) = function(/*id*/ aSuper, /*SEL*/ aSelector)
|
||||
{
|
||||
return (aSuper.super_class.method_dtable[aSelector] || _objj_forward)(aSuper.receiver, aSelector);
|
||||
}
|
||||
|
||||
GLOBAL(objj_msgSendSuper1) = function(/*id*/ aSuper, /*SEL*/ aSelector, arg0)
|
||||
{
|
||||
return (aSuper.super_class.method_dtable[aSelector] || _objj_forward)(aSuper.receiver, aSelector, arg0);
|
||||
}
|
||||
|
||||
GLOBAL(objj_msgSendSuper2) = function(/*id*/ aSuper, /*SEL*/ aSelector, arg0, arg1)
|
||||
{
|
||||
return (aSuper.super_class.method_dtable[aSelector] || _objj_forward)(aSuper.receiver, aSelector, arg0, arg1);
|
||||
}
|
||||
|
||||
GLOBAL(objj_msgSendSuper3) = function(/*id*/ aSuper, /*SEL*/ aSelector, arg0, arg1, arg2)
|
||||
{
|
||||
return (aSuper.super_class.method_dtable[aSelector] || _objj_forward)(aSuper.receiver, aSelector, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
GLOBAL(objj_msgSendFast) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
{
|
||||
var method = this.method_dtable[aSelector],
|
||||
implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
throw new Error("Maximum call stack depth exceeded.");
|
||||
@@ -857,7 +902,7 @@ GLOBAL(objj_msgSendFast) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
try {
|
||||
#endif
|
||||
|
||||
return implementation.apply(aReceiver, arguments);
|
||||
return (this.method_dtable[aSelector] || _objj_forward).apply(aReceiver, arguments);
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
} finally {
|
||||
@@ -874,9 +919,6 @@ var objj_msgSendFastInitialize = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
|
||||
GLOBAL(objj_msgSendFast0) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
{
|
||||
var method = this.method_dtable[aSelector],
|
||||
implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
throw new Error("Maximum call stack depth exceeded.");
|
||||
@@ -884,7 +926,7 @@ GLOBAL(objj_msgSendFast0) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
try {
|
||||
#endif
|
||||
|
||||
return implementation(aReceiver, aSelector);
|
||||
return (this.method_dtable[aSelector] || _objj_forward)(aReceiver, aSelector);
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
} finally {
|
||||
@@ -901,9 +943,6 @@ var objj_msgSendFast0Initialize = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
|
||||
GLOBAL(objj_msgSendFast1) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0)
|
||||
{
|
||||
var method = this.method_dtable[aSelector],
|
||||
implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
throw new Error("Maximum call stack depth exceeded.");
|
||||
@@ -911,7 +950,7 @@ GLOBAL(objj_msgSendFast1) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0)
|
||||
try {
|
||||
#endif
|
||||
|
||||
return implementation(aReceiver, aSelector, arg0);
|
||||
return (this.method_dtable[aSelector] || _objj_forward)(aReceiver, aSelector, arg0);
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
} finally {
|
||||
@@ -928,9 +967,6 @@ var objj_msgSendFast1Initialize = function(/*id*/ aReceiver, /*SEL*/ aSelector,
|
||||
|
||||
GLOBAL(objj_msgSendFast2) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0, arg1)
|
||||
{
|
||||
var method = this.method_dtable[aSelector],
|
||||
implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
throw new Error("Maximum call stack depth exceeded.");
|
||||
@@ -938,7 +974,7 @@ GLOBAL(objj_msgSendFast2) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0,
|
||||
try {
|
||||
#endif
|
||||
|
||||
return implementation(aReceiver, aSelector, arg0, arg1);
|
||||
return (this.method_dtable[aSelector] || _objj_forward)(aReceiver, aSelector, arg0, arg1);
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
} finally {
|
||||
@@ -955,9 +991,6 @@ var objj_msgSendFast2Initialize = function(/*id*/ aReceiver, /*SEL*/ aSelector,
|
||||
|
||||
GLOBAL(objj_msgSendFast3) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0, arg1, arg2)
|
||||
{
|
||||
var method = this.method_dtable[aSelector],
|
||||
implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
throw new Error("Maximum call stack depth exceeded.");
|
||||
@@ -965,7 +998,7 @@ GLOBAL(objj_msgSendFast3) = function(/*id*/ aReceiver, /*SEL*/ aSelector, arg0,
|
||||
try {
|
||||
#endif
|
||||
|
||||
return implementation(aReceiver, aSelector, arg0, arg1, arg2);
|
||||
return (this.method_dtable[aSelector] || _objj_forward)(aReceiver, aSelector, arg0, arg1, arg2);
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
} finally {
|
||||
@@ -984,7 +1017,55 @@ var objj_msgSendFast3Initialize = function(/*id*/ aReceiver, /*SEL*/ aSelector,
|
||||
|
||||
GLOBAL(method_getName) = function(/*Method*/ aMethod)
|
||||
{
|
||||
return aMethod.name;
|
||||
return aMethod.method_name;
|
||||
}
|
||||
|
||||
// This will not return correct values if the compiler does not have the option 'IncludeTypeSignatures'
|
||||
GLOBAL(method_copyReturnType) = function(/*Method*/ aMethod)
|
||||
{
|
||||
var types = aMethod.method_types;
|
||||
|
||||
if (types)
|
||||
{
|
||||
var argType = types[0];
|
||||
|
||||
return argType != NULL ? argType : NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This will not return correct values for index > 1 if the compiler does not have the option 'IncludeTypeSignatures'
|
||||
GLOBAL(method_copyArgumentType) = function(/*Method*/ aMethod, /*unsigned int*/ index)
|
||||
{
|
||||
switch (index) {
|
||||
case 0:
|
||||
return "id";
|
||||
|
||||
case 1:
|
||||
return "SEL";
|
||||
|
||||
default:
|
||||
var types = aMethod.method_types;
|
||||
|
||||
if (types)
|
||||
{
|
||||
var argType = types[index - 1];
|
||||
|
||||
return argType != NULL ? argType : NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns number of arguments for a method. The first argument is 'self' and the second is the selector.
|
||||
// Those are followed by the method arguments. So for example it will return 2 for a method with no arguments.
|
||||
GLOBAL(method_getNumberOfArguments) = function(/*Method*/ aMethod)
|
||||
{
|
||||
var types = aMethod.method_types;
|
||||
|
||||
return types ? types.length + 1 : ((aMethod.method_name.match(/:/g) || []).length + 2);
|
||||
}
|
||||
|
||||
GLOBAL(method_getImplementation) = function(/*Method*/ aMethod)
|
||||
@@ -1050,6 +1131,7 @@ objj_class.prototype.objj_msgSend0 = objj_msgSendFast0Initialize;
|
||||
objj_class.prototype.objj_msgSend1 = objj_msgSendFast1Initialize;
|
||||
objj_class.prototype.objj_msgSend2 = objj_msgSendFast2Initialize;
|
||||
objj_class.prototype.objj_msgSend3 = objj_msgSendFast3Initialize;
|
||||
objj_class.prototype.method_msgSend = Object.create(null);
|
||||
|
||||
var SEL_description = sel_getUid("description"),
|
||||
SEL_forwardingTargetForSelector_ = sel_getUid("forwardingTargetForSelector:"),
|
||||
|
||||
@@ -56,20 +56,20 @@
|
||||
|
||||
- (void)testThemeAttributeValueForState
|
||||
{
|
||||
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:@"test" defaultValue:5];
|
||||
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:@"test" defaultValue:5 defaultAttribute:nil];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState")] == 5) message:"Return the default value for the theme attribute if the theme attribute has no value defined for the given state"];
|
||||
|
||||
[themeAttribute setValue:7 forState:CPThemeState("aState")];
|
||||
themeAttribute = [themeAttribute attributeBySettingValue:7 forState:CPThemeState("aState")];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState")] == 7) message:"Return the correct value for the state if the state is defined"];
|
||||
|
||||
[themeAttribute setValue:8 forState:CPThemeState('normal')];
|
||||
themeAttribute = [themeAttribute attributeBySettingValue:8 forState:CPThemeState('normal')];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState1")] == 8) message:"Return the normal value for the state if the theme attribute has no value defined for the given state but has a value for the normal state defined"];
|
||||
|
||||
[themeAttribute setValue:10 forState:CPThemeState('aState3+aState4')];
|
||||
themeAttribute = [themeAttribute attributeBySettingValue:10 forState:CPThemeState('aState3+aState4')];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState3")] == 8) message:"Return the normal value for the state if the state is only a partial match on the theme attributes defined states"];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState4+aState3")] == 10) message:"Correctly match combined states on the theme attribute"];
|
||||
|
||||
[themeAttribute setValue:9 forState:CPThemeState('aState3')];
|
||||
themeAttribute = [themeAttribute attributeBySettingValue:9 forState:CPThemeState('aState3')];
|
||||
[self assertTrue:([themeAttribute valueForState:CPThemeState("aState8+aState3+aState4")] == 10) message:"Return the largest partial subset match for a combined state that isn't a perfect match"];
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ var methodCalled;
|
||||
[self assertTrue:[view hasThemeState:CPThemeStateDisabled] message:@"CPView should be in state CPThemeStateDisabled"];
|
||||
[self assertTrue:[view hasThemeState:CPThemeStateBordered] message:@"CPView should be in state CPThemeStateBordered"];
|
||||
[self assertTrue:[view hasThemeState:CPThemeState(CPThemeStateBordered, CPThemeStateDisabled)] message:@"CPView should be in the combined state of CPThemeStateDisabled and CPThemeStateBordered"];
|
||||
[self assertTrue:[view hasThemeState:[CPThemeStateBordered, CPThemeStateDisabled]] message:@"hasThemeState works with an array argument"];
|
||||
[self assertTrue:[view hasThemeStates:[CPThemeStateBordered, CPThemeStateDisabled]] message:@"hasThemeState works with an array argument"];
|
||||
[self assertFalse:[view hasThemeState:CPThemeState(CPThemeStateNormal)] message:@"CPView should not be in CPThemeStateNormal"];
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ var methodCalled;
|
||||
[self assert:String(CPThemeState(CPThemeStateDisabled, CPThemeStateHighlighted)) equals:String([view themeState]) message:@"The view should be in the combined state of CPThemeStateDisabled and CPThemeStateHighlighted"];
|
||||
|
||||
[view unsetThemeState:[view themeState]];
|
||||
[view setThemeState:[CPThemeStateSelected, CPThemeStateDisabled]];
|
||||
[view setThemeStates:[CPThemeStateSelected, CPThemeStateDisabled]];
|
||||
[self assert:String(CPThemeState(CPThemeStateDisabled, CPThemeStateSelected)) equals:String([view themeState]) message:@"setThemeState works with array argument"];
|
||||
}
|
||||
|
||||
@@ -117,20 +117,20 @@ var methodCalled;
|
||||
[self assert:String(CPThemeStateNormal) equals:String([view themeState]) message:@"CPView should be able to unset a combined theme state"];
|
||||
|
||||
[view setThemeState:CPThemeState(CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateBordered)];
|
||||
[view unsetThemeState:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
[view unsetThemeStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
|
||||
[self assert:String(CPThemeStateDisabled) equals:String([view themeState]) message:@"unsetThemeState works with array argument"];
|
||||
|
||||
[view setThemeState:CPThemeStateDisabled];
|
||||
[view unsetThemeState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[view unsetThemeStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[self assert:String(CPThemeStateNormal) equals:String([view themeState]) message:@"CPView should be able to unset a combined theme state that has more theme states than the view currently has"];
|
||||
|
||||
[view setThemeState:CPThemeState(CPThemeStateDisabled, CPThemeStateBordered)];
|
||||
var returnValue = [view unsetThemeState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
var returnValue = [view unsetThemeStates:[CPThemeStateDisabled, CPThemeStateHighlighted]];
|
||||
[self assert:String(CPThemeStateBordered) equals:String([view themeState]) message:@"CPView should be able to unset a combined theme state that has not entirely overlapping themestates"];
|
||||
[self assertTrue:returnValue message:@"When unsetThemeState successfully unsets anything, it return YES"];
|
||||
|
||||
[view setThemeState:CPThemeState(CPThemeStateDisabled, CPThemeStateBordered)];
|
||||
var returnValue = [view unsetThemeState:[CPThemeStateSelected, CPThemeStateHighlighted]];
|
||||
var returnValue = [view unsetThemeStates:[CPThemeStateSelected, CPThemeStateHighlighted]];
|
||||
[self assert:String(CPThemeState(CPThemeStateDisabled, CPThemeStateBordered)) equals:String([view themeState]) message:@"CPView not unset any theme states it does not have"];
|
||||
[self assertFalse:returnValue message:@"When unsetThemeState doesn't unset anything, it returns NO"];
|
||||
|
||||
|
||||
@@ -635,18 +635,50 @@
|
||||
var result = [_dateFormatter dateFromString:@"10"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-10-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"M"];
|
||||
var result = [_dateFormatter dateFromString:@"1"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"M"];
|
||||
var result = [_dateFormatter dateFromString:@"12"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MM"];
|
||||
var result = [_dateFormatter dateFromString:@"7"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-07-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MM"];
|
||||
var result = [_dateFormatter dateFromString:@"1"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MM"];
|
||||
var result = [_dateFormatter dateFromString:@"12"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMM"];
|
||||
var result = [_dateFormatter dateFromString:@"Sep"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-09-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMM"];
|
||||
var result = [_dateFormatter dateFromString:@"Jan"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMM"];
|
||||
var result = [_dateFormatter dateFromString:@"Dec"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMMM"];
|
||||
var result = [_dateFormatter dateFromString:@"September"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-09-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMMM"];
|
||||
var result = [_dateFormatter dateFromString:@"December"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMMM"];
|
||||
var result = [_dateFormatter dateFromString:@"January"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"MMMMM"];
|
||||
var result = [_dateFormatter dateFromString:@"S"];
|
||||
[self assert:result equals:nil];
|
||||
@@ -682,18 +714,50 @@
|
||||
var result = [_dateFormatter dateFromString:@"10"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-10-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"L"];
|
||||
var result = [_dateFormatter dateFromString:@"1"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"L"];
|
||||
var result = [_dateFormatter dateFromString:@"12"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LL"];
|
||||
var result = [_dateFormatter dateFromString:@"7"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-07-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LL"];
|
||||
var result = [_dateFormatter dateFromString:@"1"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LL"];
|
||||
var result = [_dateFormatter dateFromString:@"12"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLL"];
|
||||
var result = [_dateFormatter dateFromString:@"Sep"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-09-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLL"];
|
||||
var result = [_dateFormatter dateFromString:@"Dec"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLL"];
|
||||
var result = [_dateFormatter dateFromString:@"Jan"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLLL"];
|
||||
var result = [_dateFormatter dateFromString:@"September"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-09-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLLL"];
|
||||
var result = [_dateFormatter dateFromString:@"December"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-12-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLLL"];
|
||||
var result = [_dateFormatter dateFromString:@"January"];
|
||||
[self assert:result equals:[[CPDate alloc] initWithString:@"2000-01-01 08:00:00 +0000"]];
|
||||
|
||||
[_dateFormatter setDateFormat:@"LLLLL"];
|
||||
var result = [_dateFormatter dateFromString:@"S"];
|
||||
[self assert:result equals:nil];
|
||||
|
||||
@@ -28,7 +28,7 @@ var _getCheeseCounter;
|
||||
count = arguments.length;
|
||||
|
||||
for (; index < count; ++index)
|
||||
class_addMethod(theClass, arguments[index], function() { });
|
||||
class_addMethod(theClass, arguments[index], function() { }, ["void"]);
|
||||
|
||||
return [theClass new];
|
||||
}
|
||||
@@ -268,7 +268,8 @@ var _getCheeseCounter;
|
||||
- (void)testOnlyInsertObject_AtKeyIndex_Implemented
|
||||
{
|
||||
var insertSelector = @selector(insertObject:inObjectsAtIndex:),
|
||||
object = [self objectWithMethods:insertSelector];
|
||||
object = [self objectWithMethods:insertSelector],
|
||||
methodTypes = class_getInstanceMethod(object.isa, insertSelector).method_types;
|
||||
|
||||
// Sanity check
|
||||
[self assert:class_getInstanceMethod(object.isa, insertSelector)
|
||||
@@ -417,6 +418,64 @@ var _getCheeseCounter;
|
||||
[self assert:test equals:_lastObject];
|
||||
}
|
||||
|
||||
- (void)testMethodTypesOnKVOForSet_Key_Implemented
|
||||
{
|
||||
var setSelector = @selector(setObjects:),
|
||||
object = [self objectWithMethods:setSelector],
|
||||
methodTypes = class_getInstanceMethod(object.isa, setSelector).method_types;
|
||||
|
||||
// Sanity check
|
||||
[self assert:class_getInstanceMethod(object.isa, setSelector)
|
||||
same:class_getInstanceMethod([object class], setSelector)];
|
||||
|
||||
[object
|
||||
addObserver:self
|
||||
forKeyPath:@"objects"
|
||||
options:CPKeyValueObservingOptionOld | CPKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
|
||||
// Sanity check
|
||||
[self assert:class_getInstanceMethod(object.isa, setSelector)
|
||||
notSame:class_getInstanceMethod([object class], setSelector)];
|
||||
|
||||
// Check that the return and parameter types are the same on the new method as the old
|
||||
[self assertTrue:methodTypes != nil message:@"methodTypes can not be nil or undefined"];
|
||||
[self assert:methodTypes equals:class_getInstanceMethod(object.isa, setSelector).method_types];
|
||||
}
|
||||
|
||||
- (void)testMethodTypesOnKVOForInsertObject_AtKeyIndex_Implemented_and_removeFromKeyAtIndex
|
||||
{
|
||||
var insertSelector = @selector(insertObject:inObjectsAtIndex:),
|
||||
removeSelector = @selector(removeObjectFromObjectsAtIndex:),
|
||||
object = [self objectWithMethods:insertSelector, removeSelector],
|
||||
methodTypesInsert = class_getInstanceMethod(object.isa, insertSelector).method_types,
|
||||
methodTypesRemove = class_getInstanceMethod(object.isa, removeSelector).method_types;
|
||||
|
||||
// Sanity check
|
||||
[self assert:class_getInstanceMethod(object.isa, insertSelector)
|
||||
same:class_getInstanceMethod([object class], insertSelector)];
|
||||
[self assert:class_getInstanceMethod(object.isa, removeSelector)
|
||||
same:class_getInstanceMethod([object class], removeSelector)];
|
||||
|
||||
[object
|
||||
addObserver:self
|
||||
forKeyPath:@"objects"
|
||||
options:CPKeyValueObservingOptionOld | CPKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
|
||||
// Sanity check
|
||||
[self assert:class_getInstanceMethod(object.isa, insertSelector)
|
||||
notSame:class_getInstanceMethod([object class], insertSelector)];
|
||||
[self assert:class_getInstanceMethod(object.isa, removeSelector)
|
||||
notSame:class_getInstanceMethod([object class], removeSelector)];
|
||||
|
||||
// Check that the return and parameter types are the same on the new method as the old
|
||||
[self assertTrue:methodTypesInsert != nil message:@"methodTypes can not be nil or undefined on insert selector"];
|
||||
[self assertTrue:methodTypesRemove != nil message:@"methodTypes can not be nil or undefined in remove selector"];
|
||||
[self assert:methodTypesInsert equals:class_getInstanceMethod(object.isa, insertSelector).method_types];
|
||||
[self assert:methodTypesRemove equals:class_getInstanceMethod(object.isa, removeSelector).method_types];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ObservingTester : CPObject
|
||||
|
||||
@@ -36,21 +36,21 @@ var CPSourceListDataSource_sourceList_itemHasBadge_ = 1 << 1,
|
||||
- (void)setSourceListDataSource:(id)aDataSource
|
||||
{
|
||||
_sourceListDataSource = aDataSource;
|
||||
implementedSourceListDataSourceMethods = 0;
|
||||
_implementedSourceListDataSourceMethods = 0;
|
||||
|
||||
if ([_sourceListDataSource respondsToSelector:@selector(sourceList:itemHasBadge:)])
|
||||
implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_itemHasBadge_;
|
||||
_implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_itemHasBadge_;
|
||||
if ([_sourceListDataSource respondsToSelector:@selector(sourceList:badgeValueForItem:)])
|
||||
implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeValueForItem_;
|
||||
_implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeValueForItem_;
|
||||
if ([_sourceListDataSource respondsToSelector:@selector(sourceList:badgeBackgroundColorForItem:)])
|
||||
implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeBackgroundColorForItem_;
|
||||
_implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeBackgroundColorForItem_;
|
||||
if ([_sourceListDataSource respondsToSelector:@selector(sourceList:badgeTextColorForItem:)])
|
||||
implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeTextColorForItem_;
|
||||
_implementedSourceListDataSourceMethods |= CPSourceListDataSource_sourceList_badgeTextColorForItem_;
|
||||
}
|
||||
|
||||
- (BOOL)itemHasBadge:(id)item
|
||||
{
|
||||
if (implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_itemHasBadge_)
|
||||
if (_implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_itemHasBadge_)
|
||||
return [_sourceListDataSource sourceList:self itemHasBadge:item];
|
||||
|
||||
return NO;
|
||||
@@ -58,7 +58,7 @@ var CPSourceListDataSource_sourceList_itemHasBadge_ = 1 << 1,
|
||||
|
||||
- (CPInteger)badgeValueForItem:(id)item
|
||||
{
|
||||
if ([self itemHasBadge:item] && implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeValueForItem_)
|
||||
if ([self itemHasBadge:item] && _implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeValueForItem_)
|
||||
return [_sourceListDataSource sourceList:self badgeValueForItem:item];
|
||||
|
||||
return CPNotFound;
|
||||
@@ -137,7 +137,7 @@ var CPSourceListDataSource_sourceList_itemHasBadge_ = 1 << 1,
|
||||
textColor = [CPColor whiteColor];
|
||||
|
||||
//If the data source returns a custom colour..
|
||||
if (implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeBackgroundColorForItem_)
|
||||
if (_implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeBackgroundColorForItem_)
|
||||
{
|
||||
backgroundColor = [_sourceListDataSource sourceList:self badgeBackgroundColorForItem:rowItem];
|
||||
|
||||
@@ -148,7 +148,7 @@ var CPSourceListDataSource_sourceList_itemHasBadge_ = 1 << 1,
|
||||
backgroundColor = BADGE_BACKGROUND_COLOR;
|
||||
|
||||
//If the delegate wants a custom badge text colour..
|
||||
if (implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeTextColorForItem_)
|
||||
if (_implementedSourceListDataSourceMethods & CPSourceListDataSource_sourceList_badgeTextColorForItem_)
|
||||
{
|
||||
textColor = [_sourceListDataSource sourceList:self badgeTextColorForItem:rowItem];
|
||||
|
||||
|
||||
@@ -80,4 +80,59 @@
|
||||
[self assert:-6 equals:[testClass void:10 in:4]];
|
||||
}
|
||||
|
||||
- (void)testMethodName
|
||||
{
|
||||
var method = class_getInstanceMethod(MathClass, @selector(sqrt:));
|
||||
|
||||
[self assert:method_getName(method) equals:@"sqrt:"];
|
||||
}
|
||||
|
||||
- (void)testMethodNoOfArguments
|
||||
{
|
||||
var method = class_getInstanceMethod(MathClass, @selector(five));
|
||||
|
||||
[self assert:method_getNumberOfArguments(method) equals:2];
|
||||
|
||||
method = class_getInstanceMethod(MathClass, @selector(multiply:));
|
||||
[self assert:method_getNumberOfArguments(method) equals:3];
|
||||
|
||||
method = class_getInstanceMethod(MathClass, @selector(multiply:with:));
|
||||
[self assert:method_getNumberOfArguments(method) equals:4];
|
||||
}
|
||||
|
||||
- (void)testMethodTypes
|
||||
{
|
||||
var theClass = objj_allocateClassPair(CPObject, RAND() + "");
|
||||
|
||||
objj_registerClassPair(theClass);
|
||||
class_addMethod(theClass, @"myMethod:", function() { }, ["void", "CPNumber"]);
|
||||
class_addMethod(theClass, @"myMethod2:", function() { }, ["int", "float"]);
|
||||
class_addMethod(theClass, @"myMethod3:", function() { });
|
||||
[theClass new];
|
||||
|
||||
var method = class_getInstanceMethod(theClass, @selector(myMethod:));
|
||||
|
||||
[self assert:method_copyReturnType(method) equals:@"void" message:@"Return type of method 'myMethod:'"];
|
||||
[self assert:method_copyArgumentType(method, 0) equals:@"id"];
|
||||
[self assert:method_copyArgumentType(method, 1) equals:@"SEL"];
|
||||
[self assert:method_copyArgumentType(method, 2) equals:@"CPNumber"];
|
||||
[self assertTrue:method_copyArgumentType(method, 3) === nil];
|
||||
[self assert:method_getNumberOfArguments(method) equals:3];
|
||||
|
||||
method = class_getInstanceMethod(theClass, @selector(myMethod2:));
|
||||
[self assert:method_copyReturnType(method) equals:@"int" message:@"Return type of method 'myMethod2:'"];
|
||||
[self assert:method_copyArgumentType(method, 0) equals:@"id"];
|
||||
[self assert:method_copyArgumentType(method, 1) equals:@"SEL"];
|
||||
[self assert:method_copyArgumentType(method, 2) equals:@"float"];
|
||||
[self assertTrue:method_copyArgumentType(method, 3) === nil];
|
||||
[self assert:method_getNumberOfArguments(method) equals:3];
|
||||
|
||||
method = class_getInstanceMethod(theClass, @selector(myMethod3:));
|
||||
[self assertTrue:method_copyReturnType(method) == nil];
|
||||
[self assert:method_copyArgumentType(method, 0) equals:@"id"];
|
||||
[self assert:method_copyArgumentType(method, 1) equals:@"SEL"];
|
||||
[self assertTrue:method_copyArgumentType(method, 2) === nil];
|
||||
[self assert:method_getNumberOfArguments(method) equals:3];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -5,7 +5,7 @@ if(!the_class){
|
||||
throw new SyntaxError("*** Could not find definition for class \"TestClass\"");
|
||||
}
|
||||
var meta_class=the_class.isa;
|
||||
class_addIvars(the_class,[new objj_ivar("ivar")]);
|
||||
class_addIvars(the_class,[new objj_ivar("ivar","Type")]);
|
||||
class_addMethods(the_class,[new objj_method(sel_getUid("ivar"),function $TestClass__ivar(_1,_2){
|
||||
return _1.ivar;
|
||||
},["Type"]),new objj_method(sel_getUid("setIvar:"),function $TestClass__setIvar_(_3,_4,_5){
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var the_class = objj_allocateClassPair(Nil, "TestClass"),
|
||||
meta_class = the_class.isa;
|
||||
|
||||
class_addIvars(the_class,[new objj_ivar("ivar"), new objj_ivar("array"), new objj_ivar("string"), new objj_ivar("integer")]);
|
||||
class_addIvars(the_class,[new objj_ivar("ivar","Type"), new objj_ivar("array","CPArray"), new objj_ivar("string","CPString"), new objj_ivar("integer","int")]);
|
||||
|
||||
objj_registerClassPair(the_class);
|
||||
@@ -2,6 +2,6 @@
|
||||
var the_class = objj_allocateClassPair(Nil, "TestClass"),
|
||||
meta_class = the_class.isa;
|
||||
|
||||
class_addIvars(the_class,[new objj_ivar("ivar")]);
|
||||
class_addIvars(the_class,[new objj_ivar("ivar","Type")]);
|
||||
|
||||
objj_registerClassPair(the_class);
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
(object==null?null:(object.isa.method_msgSend[":"]||_objj_forward)(object,":",argument));
|
||||
@@ -0,0 +1,2 @@
|
||||
var a=0;
|
||||
((___r1=a++<2?small_target:big_target),___r1==null?null:(___r1.isa.method_msgSend["doStuff"]||_objj_forward)(___r1,"doStuff"));
|
||||
@@ -0,0 +1 @@
|
||||
(object==null?null:(object.isa.method_msgSend["for:in:nil:"]||_objj_forward)(object,"for:in:nil:",a,b,nil));
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
(object==null?null:(object.isa.method_msgSend["label:label2:label3:label4:"]||_objj_forward)(object,"label:label2:label3:label4:",argument,argument2,argument3,argument4));
|
||||
@@ -0,0 +1,2 @@
|
||||
(CPArray.isa.method_msgSend["new"]||_objj_forward)(CPArray,"new");
|
||||
(object==null?null:(object.isa.method_msgSend["message"]||_objj_forward)(object,"message"));
|
||||
@@ -0,0 +1,2 @@
|
||||
(CPArray.isa.method_msgSend["arrayWithArray:"]||_objj_forward)(CPArray,"arrayWithArray:",[]);
|
||||
(object==null?null:(object.isa.method_msgSend["label:"]||_objj_forward)(object,"label:",argument));
|
||||
@@ -0,0 +1,11 @@
|
||||
var the_class=objj_allocateClassPair(Nil,"MyClass"),meta_class=the_class.isa;
|
||||
objj_registerClassPair(the_class);
|
||||
class_addMethods(the_class,[new objj_method(sel_getUid("mySelector"),function $MyClass__mySelector(_1,_2){
|
||||
(_1.isa.method_msgSend["init"]||_objj_forward)(_1,"init");
|
||||
_1=nil;
|
||||
(_1==null?null:(_1.isa.method_msgSend["init"]||_objj_forward)(_1,"init"));
|
||||
},["id"]),new objj_method(sel_getUid("mySelector2"),function $MyClass__mySelector2(_3,_4){
|
||||
(_3.isa.method_msgSend["init"]||_objj_forward)(_3,"init");
|
||||
eval("self = null;");
|
||||
(_3==null?null:(_3.isa.method_msgSend["init"]||_objj_forward)(_3,"init"));
|
||||
},["id"])]);
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
(object==null?null:(object.isa.method_msgSend["label:"]||_objj_forward)(object,"label:",condition?true:false));
|
||||
(object==null?null:(object.isa.method_msgSend["label:"]||_objj_forward)(object,"label:",condition?true:false));
|
||||
(object==null?null:(object.isa.method_msgSend["label:"]||_objj_forward)(object,"label:",condition?true:false));
|
||||
@@ -0,0 +1,3 @@
|
||||
x=function(){
|
||||
return (someIval==null?null:(someIval.isa.method_msgSend["someMethod"]||_objj_forward)(someIval,"someMethod"));
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
{var the_class = objj_allocateClassPair(Nil, "TC"),
|
||||
meta_class = the_class.isa;class_addIvars(the_class, [new objj_ivar("_control")]);objj_registerClassPair(the_class);
|
||||
meta_class = the_class.isa;class_addIvars(the_class, [new objj_ivar("_control","id")]);objj_registerClassPair(the_class);
|
||||
class_addMethods(the_class, [new objj_method(sel_getUid("a"), function $TC__a(self, _cmd)
|
||||
{
|
||||
function(__input) { if (arguments.length) return self._control = __input; return self._control; };
|
||||
|
||||
@@ -43,18 +43,28 @@ var FILENAMES = [
|
||||
|
||||
class_addMethod(self, testSelector, function(self, _cmd)
|
||||
{
|
||||
var filePath = FILE.join(FILE.dirname(module.path), filename + ".j"),
|
||||
var d = FILE.dirname(module.path),
|
||||
filePath = FILE.join(d, filename + ".j"),
|
||||
unpreprocessed = FILE.read(filePath, { charset:"UTF-8" }),
|
||||
preprocessed,
|
||||
correct = FILE.read(FILE.join(FILE.dirname(module.path), filename + ".js"));
|
||||
preprocessedInlined,
|
||||
correct = FILE.read(FILE.join(d, filename + ".js")),
|
||||
p = FILE.join(d, filename + "-inlined.js"),
|
||||
correctInlined = FILE.exists(p) ? FILE.read(p) : correct; // Get inlined version if it exists. Otherwise use the regular one.
|
||||
|
||||
[self assertNoThrow:function() {
|
||||
preprocessed = ObjectiveJ.ObjJAcornCompiler.compileToExecutable(unpreprocessed).code();
|
||||
preprocessed = ObjectiveJ.ObjJAcornCompiler.compileToExecutable(unpreprocessed, nil, ObjectiveJ.ObjJAcornCompiler.Flags.IncludeDebugSymbols | ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures).code();
|
||||
preprocessed = compressor.compress(preprocessed, { charset : "UTF-8", useServer : true });
|
||||
correct = compressor.compress(correct, { charset : "UTF-8", useServer : true });
|
||||
|
||||
// Get an Inlined version
|
||||
preprocessedInlined = ObjectiveJ.ObjJAcornCompiler.compileToExecutable(unpreprocessed, nil, ObjectiveJ.ObjJAcornCompiler.Flags.IncludeDebugSymbols | ObjectiveJ.ObjJAcornCompiler.Flags.InlineMsgSend | ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures).code();
|
||||
preprocessedInlined = compressor.compress(preprocessedInlined, { charset : "UTF-8", useServer : true });
|
||||
correctInlined = compressor.compress(correctInlined, { charset : "UTF-8", useServer : true });
|
||||
}];
|
||||
|
||||
[self assert:correct equals:preprocessed];
|
||||
[self assert:correctInlined equals:preprocessedInlined];
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -29,12 +29,8 @@
|
||||
6824CDF01B0E9F1400F73447 /* XCCOperationError.m in Sources */ = {isa = PBXBuildFile; fileRef = 6824CDEF1B0E9F1400F73447 /* XCCOperationError.m */; };
|
||||
6841F2441AF98CE600CFE60E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6841F2431AF98CE600CFE60E /* main.m */; };
|
||||
6841F2461AF98CE600CFE60E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6841F2451AF98CE600CFE60E /* Images.xcassets */; };
|
||||
6841F2651AF98DCB00CFE60E /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 6841F2601AF98DCB00CFE60E /* DDASLLogger.m */; };
|
||||
6841F2661AF98DCB00CFE60E /* DDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 6841F2621AF98DCB00CFE60E /* DDLog.m */; };
|
||||
6841F2671AF98DCB00CFE60E /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 6841F2641AF98DCB00CFE60E /* DDTTYLogger.m */; };
|
||||
6841F26C1AF98DDD00CFE60E /* mod_pbxproj.py in Resources */ = {isa = PBXBuildFile; fileRef = 6841F2691AF98DDD00CFE60E /* mod_pbxproj.py */; };
|
||||
6841F26E1AF98DDD00CFE60E /* pbxprojModifier.py in Resources */ = {isa = PBXBuildFile; fileRef = 6841F26B1AF98DDD00CFE60E /* pbxprojModifier.py */; };
|
||||
6841F2781AF98FA300CFE60E /* DDLogLevel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6841F2771AF98FA300CFE60E /* DDLogLevel.m */; };
|
||||
6841F27C1AF990C300CFE60E /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 6841F27A1AF990C300CFE60E /* Debug.xcconfig */; };
|
||||
6841F27D1AF990C300CFE60E /* Release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 6841F27B1AF990C300CFE60E /* Release.xcconfig */; };
|
||||
6841F2A51AF9932300CFE60E /* project.pbxproj in Resources */ = {isa = PBXBuildFile; fileRef = 6841F28A1AF9932300CFE60E /* project.pbxproj */; };
|
||||
@@ -89,17 +85,9 @@
|
||||
6841F2401AF98CE600CFE60E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
6841F2431AF98CE600CFE60E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
6841F2451AF98CE600CFE60E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../Images.xcassets; sourceTree = "<group>"; };
|
||||
6841F25F1AF98DCB00CFE60E /* DDASLLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDASLLogger.h; sourceTree = "<group>"; };
|
||||
6841F2601AF98DCB00CFE60E /* DDASLLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDASLLogger.m; sourceTree = "<group>"; };
|
||||
6841F2611AF98DCB00CFE60E /* DDLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLog.h; sourceTree = "<group>"; };
|
||||
6841F2621AF98DCB00CFE60E /* DDLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDLog.m; sourceTree = "<group>"; };
|
||||
6841F2631AF98DCB00CFE60E /* DDTTYLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDTTYLogger.h; sourceTree = "<group>"; };
|
||||
6841F2641AF98DCB00CFE60E /* DDTTYLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDTTYLogger.m; sourceTree = "<group>"; };
|
||||
6841F2691AF98DDD00CFE60E /* mod_pbxproj.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = mod_pbxproj.py; sourceTree = "<group>"; };
|
||||
6841F26B1AF98DDD00CFE60E /* pbxprojModifier.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = pbxprojModifier.py; sourceTree = "<group>"; };
|
||||
6841F2741AF98F6F00CFE60E /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
||||
6841F2761AF98FA300CFE60E /* DDLogLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDLogLevel.h; sourceTree = "<group>"; };
|
||||
6841F2771AF98FA300CFE60E /* DDLogLevel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDLogLevel.m; sourceTree = "<group>"; };
|
||||
6841F2791AF9902B00CFE60E /* XcodeCapp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XcodeCapp-Prefix.pch"; sourceTree = "<group>"; };
|
||||
6841F27A1AF990C300CFE60E /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
6841F27B1AF990C300CFE60E /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||
@@ -150,7 +138,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0275390E1B227D6700F6D824 /* YRKSpinningProgressIndicator */,
|
||||
6841F25E1AF98DCB00CFE60E /* Lumberjack */,
|
||||
);
|
||||
name = Externals;
|
||||
sourceTree = "<group>";
|
||||
@@ -246,19 +233,6 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6841F25E1AF98DCB00CFE60E /* Lumberjack */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6841F25F1AF98DCB00CFE60E /* DDASLLogger.h */,
|
||||
6841F2601AF98DCB00CFE60E /* DDASLLogger.m */,
|
||||
6841F2611AF98DCB00CFE60E /* DDLog.h */,
|
||||
6841F2621AF98DCB00CFE60E /* DDLog.m */,
|
||||
6841F2631AF98DCB00CFE60E /* DDTTYLogger.h */,
|
||||
6841F2641AF98DCB00CFE60E /* DDTTYLogger.m */,
|
||||
);
|
||||
path = Lumberjack;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6841F2681AF98DDD00CFE60E /* Scripts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -287,8 +261,6 @@
|
||||
6841F2B81AFA83E900CFE60E /* XCCUserDefaults.h */,
|
||||
6841F2BD1AFA965300CFE60E /* XCCTaskLauncher.h */,
|
||||
6841F2BE1AFA965300CFE60E /* XCCTaskLauncher.m */,
|
||||
6841F2761AF98FA300CFE60E /* DDLogLevel.h */,
|
||||
6841F2771AF98FA300CFE60E /* DDLogLevel.m */,
|
||||
6815BBE91AFC24430030D8BB /* XcodeProjectCloser.h */,
|
||||
6815BBEA1AFC24430030D8BB /* XcodeProjectCloser.m */,
|
||||
6863FBA11AFD55A900040C8E /* XCCFSEventLogUtils.h */,
|
||||
@@ -409,7 +381,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6841F2781AF98FA300CFE60E /* DDLogLevel.m in Sources */,
|
||||
68B6BF321B1E2546003B265B /* XCCPPXOperation.m in Sources */,
|
||||
021B94701B20E31F00F12DDA /* XCCSettingsViewController.m in Sources */,
|
||||
0255B8401B1F71FB000CA4BC /* AppDelegate.m in Sources */,
|
||||
@@ -417,7 +388,6 @@
|
||||
6841F2BF1AFA965300CFE60E /* XCCTaskLauncher.m in Sources */,
|
||||
027539111B227D7500F6D824 /* YRKSpinningProgressIndicator.m in Sources */,
|
||||
6841F2C41AFABD7200CFE60E /* XCCCappuccinoProject.m in Sources */,
|
||||
6841F2661AF98DCB00CFE60E /* DDLog.m in Sources */,
|
||||
686ACD311B16397F0089EB03 /* XCCCappuccinoProjectController.m in Sources */,
|
||||
021B946C1B20D71200F12DDA /* XCCErrorsViewController.m in Sources */,
|
||||
021B94651B20CECA00F12DDA /* XCCOperationsViewController.m in Sources */,
|
||||
@@ -430,12 +400,10 @@
|
||||
686C69711B0FAE620095BB3C /* XCCOperationErrorHeaderDataView.m in Sources */,
|
||||
6824CDF01B0E9F1400F73447 /* XCCOperationError.m in Sources */,
|
||||
021B94751B21112500F12DDA /* XCCWelcomeView.m in Sources */,
|
||||
6841F2671AF98DCB00CFE60E /* DDTTYLogger.m in Sources */,
|
||||
6841F2441AF98CE600CFE60E /* main.m in Sources */,
|
||||
6824CDDA1B0D5AA700F73447 /* XCCOperationDataView.m in Sources */,
|
||||
6841F2CA1AFADEBC00CFE60E /* XCCSourcesFinderOperation.m in Sources */,
|
||||
681ADE8F1B0D032C00FC8E08 /* XCCPath.m in Sources */,
|
||||
6841F2651AF98DCB00CFE60E /* DDASLLogger.m in Sources */,
|
||||
6841F2B71AFA83D500CFE60E /* XCCUserDefaults.m in Sources */,
|
||||
6824CDEA1B0E9CDB00F73447 /* XCCOperationErrorDataView.m in Sources */,
|
||||
);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
{
|
||||
NSDictionary *appDefaults = @{
|
||||
XCCUserDefaultsAutoOpenXcodeProject: @YES,
|
||||
XCCUserDefaultsLogLevel: @LOG_LEVEL_WARN,
|
||||
XCCUserDefaultsMaxNumberOfConcurrentOperations: @20
|
||||
};
|
||||
|
||||
@@ -40,26 +39,6 @@
|
||||
self->statusItem.length = self->imageStatusInactive.size.width + 12;
|
||||
}
|
||||
|
||||
- (void)_initLogging
|
||||
{
|
||||
#if DEBUG
|
||||
[DDLog addLogger:[DDTTYLogger sharedInstance]];
|
||||
[[DDTTYLogger sharedInstance] setColorsEnabled:YES];
|
||||
[DDLogLevel setLogLevel:LOG_LEVEL_VERBOSE];
|
||||
#else
|
||||
[DDLog addLogger:[DDASLLogger sharedInstance]];
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
int logLevel = (int)[defaults integerForKey:XCCUserDefaultsLogLevel];
|
||||
NSUInteger modifiers = [NSEvent modifierFlags];
|
||||
|
||||
if (modifiers & NSAlternateKeyMask)
|
||||
logLevel = LOG_LEVEL_VERBOSE;
|
||||
|
||||
[DDLogLevel setLogLevel:logLevel];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)_initOperationQueue
|
||||
{
|
||||
self.mainOperationQueue = [NSOperationQueue new];
|
||||
@@ -116,12 +95,11 @@
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
DDLogVerbose(@"\n******************************\n** XcodeCapp started **\n******************************\n");
|
||||
NSLog(@"\n******************************\n** XcodeCapp started **\n******************************\n");
|
||||
|
||||
self.version = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];
|
||||
|
||||
[self _initUserDefaults];
|
||||
[self _initLogging];
|
||||
[self _initOperationQueue];
|
||||
[self _initStatusItem];
|
||||
|
||||
@@ -132,7 +110,7 @@
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
|
||||
{
|
||||
DDLogVerbose(@"Stop listening to all projects");
|
||||
NSLog(@"Stop listening to all projects");
|
||||
[self.mainWindowController notifyCappuccinoControllersApplicationIsClosing];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
|
||||
@@ -141,7 +119,7 @@
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||
{
|
||||
DDLogVerbose(@"\n******************************\n** XcodeCapp stopped **\n******************************\n");
|
||||
NSLog(@"\n******************************\n** XcodeCapp stopped **\n******************************\n");
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// DDLogLevel.h
|
||||
// XcodeCapp
|
||||
//
|
||||
// Created by Aparajita on 4/29/13.
|
||||
// Copyright (c) 2013 Cappuccino Project. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern int ddLogLevel;
|
||||
|
||||
@interface DDLogLevel : NSObject
|
||||
|
||||
+ (void)setLogLevel:(int)logLevel;
|
||||
|
||||
@end
|
||||
@@ -1,27 +0,0 @@
|
||||
//
|
||||
// DDLog.m
|
||||
// XcodeCapp
|
||||
//
|
||||
// Created by Aparajita on 4/29/13.
|
||||
// Copyright (c) 2013 Cappuccino Project. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DDLogLevel.h"
|
||||
|
||||
|
||||
int ddLogLevel = LOG_LEVEL_OFF;
|
||||
|
||||
|
||||
@implementation DDLogLevel
|
||||
|
||||
+ (int)ddLogLevel
|
||||
{
|
||||
return ddLogLevel;
|
||||
}
|
||||
|
||||
+ (void)setLogLevel:(int)logLevel
|
||||
{
|
||||
ddLogLevel = logLevel;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,41 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <asl.h>
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a logger for the Apple System Log facility.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* the traditional NSLog() function directs it's output to two places:
|
||||
*
|
||||
* - Apple System Log
|
||||
* - StdErr (if stderr is a TTY) so log statements show up in Xcode console
|
||||
*
|
||||
* To duplicate NSLog() functionality you can simply add this logger and a tty logger.
|
||||
* However, if you instead choose to use file logging (for faster performance),
|
||||
* you may choose to use a file logger and a tty logger.
|
||||
**/
|
||||
|
||||
@interface DDASLLogger : DDAbstractLogger <DDLogger>
|
||||
{
|
||||
aslclient client;
|
||||
}
|
||||
|
||||
+ (DDASLLogger *)sharedInstance;
|
||||
|
||||
// Inherited from DDAbstractLogger
|
||||
|
||||
// - (id <DDLogFormatter>)logFormatter;
|
||||
// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
@@ -1,99 +0,0 @@
|
||||
#import "DDASLLogger.h"
|
||||
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
|
||||
@implementation DDASLLogger
|
||||
|
||||
static DDASLLogger *sharedInstance;
|
||||
|
||||
/**
|
||||
* The runtime sends initialize to each class in a program exactly one time just before the class,
|
||||
* or any class that inherits from it, is sent its first message from within the program. (Thus the
|
||||
* method may never be invoked if the class is not used.) The runtime sends the initialize message to
|
||||
* classes in a thread-safe manner. Superclasses receive this message before their subclasses.
|
||||
*
|
||||
* This method may also be called directly (assumably by accident), hence the safety mechanism.
|
||||
**/
|
||||
+ (void)initialize
|
||||
{
|
||||
static BOOL initialized = NO;
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = YES;
|
||||
|
||||
sharedInstance = [[DDASLLogger alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
+ (DDASLLogger *)sharedInstance
|
||||
{
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (sharedInstance != nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
// A default asl client is provided for the main thread,
|
||||
// but background threads need to create their own client.
|
||||
|
||||
client = asl_open(NULL, "com.apple.console", 0);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
NSString *logMsg = logMessage->logMsg;
|
||||
|
||||
if (formatter)
|
||||
{
|
||||
logMsg = [formatter formatLogMessage:logMessage];
|
||||
}
|
||||
|
||||
if (logMsg)
|
||||
{
|
||||
const char *msg = [logMsg UTF8String];
|
||||
|
||||
int aslLogLevel;
|
||||
switch (logMessage->logLevel)
|
||||
{
|
||||
// Note: By default ASL will filter anything above level 5 (Notice).
|
||||
// So our mappings shouldn't go above that level.
|
||||
|
||||
case 1 : aslLogLevel = ASL_LEVEL_CRIT; break;
|
||||
case 2 : aslLogLevel = ASL_LEVEL_ERR; break;
|
||||
case 3 : aslLogLevel = ASL_LEVEL_WARNING; break;
|
||||
default : aslLogLevel = ASL_LEVEL_NOTICE; break;
|
||||
}
|
||||
|
||||
asl_log(client, NULL, aslLogLevel, "%s", msg);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)loggerName
|
||||
{
|
||||
return @"cocoa.lumberjack.aslLogger";
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,596 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
* Otherwise, here is a quick refresher.
|
||||
* There are three steps to using the macros:
|
||||
*
|
||||
* Step 1:
|
||||
* Import the header in your implementation file:
|
||||
*
|
||||
* #import "DDLog.h"
|
||||
*
|
||||
* Step 2:
|
||||
* Define your logging level in your implementation file:
|
||||
*
|
||||
* // Log levels: off, error, warn, info, verbose
|
||||
* static const int ddLogLevel = LOG_LEVEL_VERBOSE;
|
||||
*
|
||||
* Step 3:
|
||||
* Replace your NSLog statements with DDLog statements according to the severity of the message.
|
||||
*
|
||||
* NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!");
|
||||
*
|
||||
* DDLog works exactly the same as NSLog.
|
||||
* This means you can pass it multiple variables just like NSLog.
|
||||
**/
|
||||
|
||||
|
||||
@class DDLogMessage;
|
||||
|
||||
@protocol DDLogger;
|
||||
@protocol DDLogFormatter;
|
||||
|
||||
/**
|
||||
* This is the single macro that all other macros below compile into.
|
||||
* This big multiline macro makes all the other macros easier to read.
|
||||
**/
|
||||
|
||||
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
|
||||
[DDLog log:isAsynchronous \
|
||||
level:lvl \
|
||||
flag:flg \
|
||||
context:ctx \
|
||||
file:__FILE__ \
|
||||
function:fnct \
|
||||
line:__LINE__ \
|
||||
tag:atag \
|
||||
format:(frmt), ##__VA_ARGS__]
|
||||
|
||||
/**
|
||||
* Define the Objective-C and C versions of the macro.
|
||||
* These automatically inject the proper function name for either an objective-c method or c function.
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
|
||||
#define LOG_OBJC_MACRO(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_MACRO(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define version of the macro that only execute if the logLevel is above the threshold.
|
||||
* The compiled versions essentially look like this:
|
||||
*
|
||||
* if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
|
||||
*
|
||||
* As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
|
||||
* This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
|
||||
*
|
||||
* Note that when compiler optimizations are enabled (as they are for your release builds),
|
||||
* the log messages above your logging threshold will automatically be compiled out.
|
||||
*
|
||||
* (If the compiler sees ddLogLevel declared as a constant, the compiler simply checks to see if the 'if' statement
|
||||
* would execute, and if not it strips it from the binary.)
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
|
||||
#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
|
||||
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_MAYBE(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MAYBE(async, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define versions of the macros that also accept tags.
|
||||
*
|
||||
* The DDLogMessage object includes a 'tag' ivar that may be used for a variety of purposes.
|
||||
* It may be used to pass custom information to loggers or formatters.
|
||||
* Or it may be used by 3rd party extensions to the framework.
|
||||
*
|
||||
* Thes macros just make it a little easier to extend logging functionality.
|
||||
**/
|
||||
|
||||
#define LOG_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
|
||||
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define the standard options.
|
||||
*
|
||||
* We default to only 4 levels because it makes it easier for beginners
|
||||
* to make the transition to a logging framework.
|
||||
*
|
||||
* More advanced users may choose to completely customize the levels (and level names) to suite their needs.
|
||||
* For more information on this see the "Custom Log Levels" page:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels
|
||||
*
|
||||
* Advanced users may also notice that we're using a bitmask.
|
||||
* This is to allow for custom fine grained logging:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/FineGrainedLogging
|
||||
*
|
||||
* -- Flags --
|
||||
*
|
||||
* Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations.
|
||||
* For example, say you have a lot of warning log messages, and you wanted to disable them.
|
||||
* However, you still needed to see your error and info log messages.
|
||||
* You could accomplish that with the following:
|
||||
*
|
||||
* static const int ddLogLevel = LOG_FLAG_ERROR | LOG_FLAG_INFO;
|
||||
*
|
||||
* Flags may also be consulted when writing custom log formatters,
|
||||
* as the DDLogMessage class captures the individual flag that caused the log message to fire.
|
||||
*
|
||||
* -- Levels --
|
||||
*
|
||||
* Log levels are simply the proper bitmask of the flags.
|
||||
*
|
||||
* -- Booleans --
|
||||
*
|
||||
* The booleans may be used when your logging code involves more than one line.
|
||||
* For example:
|
||||
*
|
||||
* if (LOG_VERBOSE) {
|
||||
* for (id sprocket in sprockets)
|
||||
* DDLogVerbose(@"sprocket: %@", [sprocket description])
|
||||
* }
|
||||
*
|
||||
* -- Async --
|
||||
*
|
||||
* Defines the default asynchronous options.
|
||||
* The default philosophy for asynchronous logging is very simple:
|
||||
*
|
||||
* Log messages with errors should be executed synchronously.
|
||||
* After all, an error just occurred. The application could be unstable.
|
||||
*
|
||||
* All other log messages, such as debug output, are executed asynchronously.
|
||||
* After all, if it wasn't an error, then it was just informational output,
|
||||
* or something the application was easily able to recover from.
|
||||
*
|
||||
* -- Changes --
|
||||
*
|
||||
* You are strongly discouraged from modifying this file.
|
||||
* If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project.
|
||||
* Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h
|
||||
*
|
||||
* For an example of customizing your logging experience, see the "Custom Log Levels" page:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels
|
||||
**/
|
||||
|
||||
#define LOG_FLAG_ERROR (1 << 0) // 0...0001
|
||||
#define LOG_FLAG_WARN (1 << 1) // 0...0010
|
||||
#define LOG_FLAG_INFO (1 << 2) // 0...0100
|
||||
#define LOG_FLAG_VERBOSE (1 << 3) // 0...1000
|
||||
|
||||
#define LOG_LEVEL_OFF 0
|
||||
#define LOG_LEVEL_ERROR (LOG_FLAG_ERROR) // 0...0001
|
||||
#define LOG_LEVEL_WARN (LOG_FLAG_ERROR | LOG_FLAG_WARN) // 0...0011
|
||||
#define LOG_LEVEL_INFO (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO) // 0...0111
|
||||
#define LOG_LEVEL_VERBOSE (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_VERBOSE) // 0...1111
|
||||
|
||||
#define LOG_ERROR (ddLogLevel & LOG_FLAG_ERROR)
|
||||
#define LOG_WARN (ddLogLevel & LOG_FLAG_WARN)
|
||||
#define LOG_INFO (ddLogLevel & LOG_FLAG_INFO)
|
||||
#define LOG_VERBOSE (ddLogLevel & LOG_FLAG_VERBOSE)
|
||||
|
||||
#define LOG_ASYNC_ENABLED YES
|
||||
|
||||
#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED)
|
||||
|
||||
#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define DDLogCError(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCWarn(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCInfo(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCVerbose(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* The THIS_FILE macro gives you an NSString of the file name.
|
||||
* For simplicity and clarity, the file name does not include the full path or file extension.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
|
||||
**/
|
||||
|
||||
NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
|
||||
|
||||
#define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO))
|
||||
|
||||
/**
|
||||
* The THIS_METHOD macro gives you the name of the current objective-c method.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@ - Requires non-nil strings") -> @"setMake:model: requires non-nil strings"
|
||||
*
|
||||
* Note: This does NOT work in straight C functions (non objective-c).
|
||||
* Instead you should use the predefined __FUNCTION__ macro.
|
||||
**/
|
||||
|
||||
#define THIS_METHOD NSStringFromSelector(_cmd)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDLog : NSObject
|
||||
|
||||
/**
|
||||
* Provides access to the underlying logging queue.
|
||||
* This may be helpful to Logger classes for things like thread synchronization.
|
||||
**/
|
||||
|
||||
+ (dispatch_queue_t)loggingQueue;
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method is used by the macros above.
|
||||
* It is suggested you stick with the macros as they're easier to use.
|
||||
**/
|
||||
|
||||
+ (void)log:(BOOL)synchronous
|
||||
level:(int)level
|
||||
flag:(int)flag
|
||||
context:(int)context
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
format:(NSString *)format, ... __attribute__ ((format (__NSString__, 9, 10)));
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you have a prepared va_list.
|
||||
**/
|
||||
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
level:(int)level
|
||||
flag:(int)flag
|
||||
context:(int)context
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
format:(NSString *)format
|
||||
args:(va_list)argList;
|
||||
|
||||
|
||||
/**
|
||||
* Since logging can be asynchronous, there may be times when you want to flush the logs.
|
||||
* The framework invokes this automatically when the application quits.
|
||||
**/
|
||||
|
||||
+ (void)flushLog;
|
||||
|
||||
/**
|
||||
* Loggers
|
||||
*
|
||||
* If you want your log statements to go somewhere,
|
||||
* you should create and add a logger.
|
||||
**/
|
||||
|
||||
+ (void)addLogger:(id <DDLogger>)logger;
|
||||
+ (void)removeLogger:(id <DDLogger>)logger;
|
||||
|
||||
+ (void)removeAllLoggers;
|
||||
|
||||
/**
|
||||
* Registered Dynamic Logging
|
||||
*
|
||||
* These methods allow you to obtain a list of classes that are using registered dynamic logging,
|
||||
* and also provides methods to get and set their log level during run time.
|
||||
**/
|
||||
|
||||
+ (NSArray *)registeredClasses;
|
||||
+ (NSArray *)registeredClassNames;
|
||||
|
||||
+ (int)logLevelForClass:(Class)aClass;
|
||||
+ (int)logLevelForClassWithName:(NSString *)aClassName;
|
||||
|
||||
+ (void)setLogLevel:(int)logLevel forClass:(Class)aClass;
|
||||
+ (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDLogger <NSObject>
|
||||
@required
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
**/
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Since logging is asynchronous, adding and removing loggers is also asynchronous.
|
||||
* In other words, the loggers are added and removed at appropriate times with regards to log messages.
|
||||
*
|
||||
* - Loggers will not receive log messages that were executed prior to when they were added.
|
||||
* - Loggers will not receive log messages that were executed after they were removed.
|
||||
*
|
||||
* These methods are executed in the logging thread/queue.
|
||||
* This is the same thread/queue that will execute every logMessage: invocation.
|
||||
* Loggers may use these methods for thread synchronization or other setup/teardown tasks.
|
||||
**/
|
||||
- (void)didAddLogger;
|
||||
- (void)willRemoveLogger;
|
||||
|
||||
/**
|
||||
* Some loggers may buffer IO for optimization purposes.
|
||||
* For example, a database logger may only save occasionaly as the disk IO is slow.
|
||||
* In such loggers, this method should be implemented to flush any pending IO.
|
||||
*
|
||||
* This allows invocations of DDLog's flushLog method to be propogated to loggers that need it.
|
||||
*
|
||||
* Note that DDLog's flushLog method is invoked automatically when the application quits,
|
||||
* and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
|
||||
**/
|
||||
- (void)flush;
|
||||
|
||||
/**
|
||||
* Each logger is executed concurrently with respect to the other loggers.
|
||||
* Thus, a dedicated dispatch queue is used for each logger.
|
||||
* Logger implementations may optionally choose to provide their own dispatch queue.
|
||||
**/
|
||||
- (dispatch_queue_t)loggerQueue;
|
||||
|
||||
/**
|
||||
* If the logger implementation does not choose to provide its own queue,
|
||||
* one will automatically be created for it.
|
||||
* The created queue will receive its name from this method.
|
||||
* This may be helpful for debugging or profiling reasons.
|
||||
**/
|
||||
- (NSString *)loggerName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDLogFormatter <NSObject>
|
||||
@required
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
* This allows for increased flexibility in the logging environment.
|
||||
* For example, log messages for log files may be formatted differently than log messages for the console.
|
||||
*
|
||||
* For more information about formatters, see the "Custom Formatters" page:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* The formatter may also optionally filter the log message by returning nil,
|
||||
* in which case the logger will not log the message.
|
||||
**/
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* A single formatter instance can be added to multiple loggers.
|
||||
* These methods provides hooks to notify the formatter of when it's added/removed.
|
||||
*
|
||||
* This is primarily for thread-safety.
|
||||
* If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
|
||||
* Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
|
||||
* it could possibly use these hooks to switch to thread-safe versions of the code.
|
||||
**/
|
||||
- (void)didAddToLogger:(id <DDLogger>)logger;
|
||||
- (void)willRemoveFromLogger:(id <DDLogger>)logger;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDRegisteredDynamicLogging
|
||||
|
||||
/**
|
||||
* Implement these methods to allow a file's log level to be managed from a central location.
|
||||
*
|
||||
* This is useful if you'd like to be able to change log levels for various parts
|
||||
* of your code from within the running application.
|
||||
*
|
||||
* Imagine pulling up the settings for your application,
|
||||
* and being able to configure the logging level on a per file basis.
|
||||
*
|
||||
* The implementation can be very straight-forward:
|
||||
*
|
||||
* + (int)ddLogLevel
|
||||
* {
|
||||
* return ddLogLevel;
|
||||
* }
|
||||
*
|
||||
* + (void)ddSetLogLevel:(int)logLevel
|
||||
* {
|
||||
* ddLogLevel = logLevel;
|
||||
* }
|
||||
**/
|
||||
|
||||
+ (int)ddLogLevel;
|
||||
+ (void)ddSetLogLevel:(int)logLevel;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The DDLogMessage class encapsulates information about the log message.
|
||||
* If you write custom loggers or formatters, you will be dealing with objects of this class.
|
||||
**/
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, DDLogMessageOptions)
|
||||
{
|
||||
DDLogMessageCopyFile = 1 << 0,
|
||||
DDLogMessageCopyFunction = 1 << 1,
|
||||
};
|
||||
|
||||
@interface DDLogMessage : NSObject
|
||||
{
|
||||
|
||||
// The public variables below can be accessed directly (for speed).
|
||||
// For example: logMessage->logLevel
|
||||
|
||||
@public
|
||||
int logLevel;
|
||||
int logFlag;
|
||||
int logContext;
|
||||
NSString *logMsg;
|
||||
NSDate *timestamp;
|
||||
char *file;
|
||||
char *function;
|
||||
int lineNumber;
|
||||
mach_port_t machThreadID;
|
||||
char *queueLabel;
|
||||
NSString *threadName;
|
||||
|
||||
// For 3rd party extensions to the framework, where flags and contexts aren't enough.
|
||||
id tag;
|
||||
|
||||
// For 3rd party extensions that manually create DDLogMessage instances.
|
||||
DDLogMessageOptions options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard init method for a log message object.
|
||||
* Used by the logging primitives. (And the macros use the logging primitives.)
|
||||
*
|
||||
* If you find need to manually create logMessage objects, there is one thing you should be aware of:
|
||||
*
|
||||
* If no flags are passed, the method expects the file and function parameters to be string literals.
|
||||
* That is, it expects the given strings to exist for the duration of the object's lifetime,
|
||||
* and it expects the given strings to be immutable.
|
||||
* In other words, it does not copy these strings, it simply points to them.
|
||||
* This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
|
||||
* so it makes sense to optimize and skip the unnecessary allocations.
|
||||
* However, if you need them to be copied you may use the options parameter to specify this.
|
||||
* Options is a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
|
||||
**/
|
||||
- (instancetype)initWithLogMsg:(NSString *)logMsg
|
||||
level:(int)logLevel
|
||||
flag:(int)logFlag
|
||||
context:(int)logContext
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
options:(DDLogMessageOptions)optionsMask;
|
||||
|
||||
/**
|
||||
* Returns the threadID as it appears in NSLog.
|
||||
* That is, it is a hexadecimal value which is calculated from the machThreadID.
|
||||
**/
|
||||
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *threadID;
|
||||
|
||||
/**
|
||||
* Convenience property to get just the file name, as the file variable is generally the full file path.
|
||||
* This method does not include the file extension, which is generally unwanted for logging purposes.
|
||||
**/
|
||||
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *fileName;
|
||||
|
||||
/**
|
||||
* Returns the function variable in NSString form.
|
||||
**/
|
||||
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *methodName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The DDLogger protocol specifies that an optional formatter can be added to a logger.
|
||||
* Most (but not all) loggers will want to support formatters.
|
||||
*
|
||||
* However, writting getters and setters in a thread safe manner,
|
||||
* while still maintaining maximum speed for the logging process, is a difficult task.
|
||||
*
|
||||
* To do it right, the implementation of the getter/setter has strict requiremenets:
|
||||
* - Must NOT require the logMessage method to acquire a lock.
|
||||
* - Must NOT require the logMessage method to access an atomic property (also a lock of sorts).
|
||||
*
|
||||
* To simplify things, an abstract logger is provided that implements the getter and setter.
|
||||
*
|
||||
* Logger implementations may simply extend this class,
|
||||
* and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their logMessage method!
|
||||
**/
|
||||
|
||||
@interface DDAbstractLogger : NSObject <DDLogger>
|
||||
{
|
||||
id <DDLogFormatter> formatter;
|
||||
|
||||
dispatch_queue_t loggerQueue;
|
||||
}
|
||||
|
||||
@property (NS_NONATOMIC_IOSONLY, strong) id<DDLogFormatter> logFormatter;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,167 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIColor.h>
|
||||
#else
|
||||
#import <AppKit/NSColor.h>
|
||||
#endif
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a logger for Terminal output or Xcode console output,
|
||||
* depending on where you are running your code.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* the traditional NSLog() function directs it's output to two places:
|
||||
*
|
||||
* - Apple System Log (so it shows up in Console.app)
|
||||
* - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
|
||||
*
|
||||
* To duplicate NSLog() functionality you can simply add this logger and an asl logger.
|
||||
* However, if you instead choose to use file logging (for faster performance),
|
||||
* you may choose to use only a file logger and a tty logger.
|
||||
**/
|
||||
|
||||
@interface DDTTYLogger : DDAbstractLogger <DDLogger>
|
||||
{
|
||||
NSCalendar *calendar;
|
||||
NSUInteger calendarUnitFlags;
|
||||
|
||||
NSString *appName;
|
||||
char *app;
|
||||
size_t appLen;
|
||||
|
||||
NSString *processID;
|
||||
char *pid;
|
||||
size_t pidLen;
|
||||
|
||||
BOOL colorsEnabled;
|
||||
NSMutableArray *colorProfilesArray;
|
||||
NSMutableDictionary *colorProfilesDict;
|
||||
}
|
||||
|
||||
+ (DDTTYLogger *)sharedInstance;
|
||||
|
||||
/* Inherited from the DDLogger protocol:
|
||||
*
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
*
|
||||
* More information about formatters can be found here:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* The actual implementation of these methods is inherited from DDAbstractLogger.
|
||||
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Want to use different colors for different log levels?
|
||||
* Enable this property.
|
||||
*
|
||||
* If you run the application via the Terminal (not Xcode),
|
||||
* the logger will map colors to xterm-256color or xterm-color (if available).
|
||||
*
|
||||
* Xcode does NOT natively support colors in the Xcode debugging console.
|
||||
* You'll need to install the XcodeColors plugin to see colors in the Xcode console.
|
||||
* https://github.com/robbiehanson/XcodeColors
|
||||
*
|
||||
* The default value if NO.
|
||||
**/
|
||||
@property (readwrite, assign) BOOL colorsEnabled;
|
||||
|
||||
/**
|
||||
* The default color set (foregroundColor, backgroundColor) is:
|
||||
*
|
||||
* - LOG_FLAG_ERROR = (red, nil)
|
||||
* - LOG_FLAG_WARN = (orange, nil)
|
||||
*
|
||||
* You can customize the colors however you see fit.
|
||||
* Please note that you are passing a flag, NOT a level.
|
||||
*
|
||||
* GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
|
||||
* BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
|
||||
*
|
||||
* LOG_FLAG_INFO = 0...00100
|
||||
* LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR
|
||||
*
|
||||
* If you run the application within Xcode, then the XcodeColors plugin is required.
|
||||
*
|
||||
* If you run the application from a shell, then DDTTYLogger will automatically map the given color to
|
||||
* the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
|
||||
*
|
||||
* This method invokes setForegroundColor:backgroundColor:forFlag:context: and passes the default context (0).
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask;
|
||||
#else
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
|
||||
*
|
||||
* A logging context is often used to identify log messages coming from a 3rd party framework,
|
||||
* although logging context's can be used for many different functions.
|
||||
*
|
||||
* Logging context's are explained in further detail here:
|
||||
* https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask context:(int)ctxt;
|
||||
#else
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask context:(int)ctxt;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
|
||||
* For example, you could do something like this:
|
||||
*
|
||||
* static NSString *const PurpleTag = @"PurpleTag";
|
||||
*
|
||||
* #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
|
||||
*
|
||||
* And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack:
|
||||
*
|
||||
* #if TARGET_OS_IPHONE
|
||||
* UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
|
||||
* #else
|
||||
* NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
|
||||
*
|
||||
* [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
|
||||
* [DDLog addLogger:[DDTTYLogger sharedInstance]];
|
||||
*
|
||||
* This would essentially give you a straight NSLog replacement that prints in purple:
|
||||
*
|
||||
* DDLogPurple(@"I'm a purple log message!");
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
#else
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Clearing color profiles.
|
||||
**/
|
||||
- (void)clearColorsForFlag:(int)mask;
|
||||
- (void)clearColorsForFlag:(int)mask context:(int)context;
|
||||
- (void)clearColorsForTag:(id <NSCopying>)tag;
|
||||
- (void)clearColorsForAllFlags;
|
||||
- (void)clearColorsForAllTags;
|
||||
- (void)clearAllColors;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large.
Load diff
@@ -16,7 +16,9 @@ static NSDictionary* XCCCappuccinoProjectDefaultSettings;
|
||||
static NSString * const XCCSlashReplacement = @"::";
|
||||
|
||||
static NSPredicate * XCCDirectoriesToIgnorePredicate = nil;
|
||||
static NSString * const XCCDirectoriesToIgnorePattern = @"^(?:Build|F(?:rameworks|oundation)|AppKit|Objective-J|(?:Browser|CommonJS)\\.environment|Resources|XcodeSupport|.+\\.xcodeproj)$";
|
||||
static NSPredicate * XCCXcodeCappNibToIgnorePredicate = nil;
|
||||
static NSString * const XCCDirectoriesToIgnorePattern = @"^(?:Build|F(?:rameworks|oundation)|AppKit|Objective-J|(?:Browser|CommonJS)\\.environment|XcodeSupport|.+\\.xcodeproj)$";
|
||||
static NSString * const XCCXcodeCappNibToIgnorePattern = @"^/Applications/XcodeCapp.app/.*$";
|
||||
|
||||
static NSArray *XCCCappuccinoProjectDefaultIgnoredPaths = nil;
|
||||
|
||||
@@ -51,6 +53,7 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
NSNumber *appCompatibilityVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:XCCCompatibilityVersionKey];
|
||||
|
||||
XCCDirectoriesToIgnorePredicate = [NSPredicate predicateWithFormat:@"SELF matches %@", XCCDirectoriesToIgnorePattern];
|
||||
XCCXcodeCappNibToIgnorePredicate = [NSPredicate predicateWithFormat:@"SELF matches %@", XCCXcodeCappNibToIgnorePattern];
|
||||
|
||||
XCCCappuccinoProjectDefaultSettings = @{XCCCompatibilityVersionKey: appCompatibilityVersion,
|
||||
XCCCappuccinoProcessCappLintKey: @NO,
|
||||
@@ -129,7 +132,11 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
+ (BOOL)pathMatchesIgnoredPaths:(NSString*)aPath cappuccinoProjectIgnoredPathPredicates:(NSMutableArray*)cappuccinoProjectIgnoredPathPredicates
|
||||
{
|
||||
BOOL ignore = NO;
|
||||
|
||||
|
||||
// This is a bit tricky, is to avoid to fetch nib of a compiled XcodeCapp
|
||||
if ([XCCXcodeCappNibToIgnorePredicate evaluateWithObject:aPath])
|
||||
return YES;
|
||||
|
||||
for (NSDictionary *ignoreInfo in cappuccinoProjectIgnoredPathPredicates)
|
||||
{
|
||||
BOOL matches = [ignoreInfo[@"predicate"] evaluateWithObject:aPath];
|
||||
@@ -242,7 +249,7 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
|
||||
if (![self shouldIgnoreDirectoryNamed:filename] && ![self pathMatchesIgnoredPaths:path cappuccinoProjectIgnoredPathPredicates:aCappuccinoProject.ignoredPathPredicates])
|
||||
{
|
||||
DDLogVerbose(@"Watching symlinked directory: %@", path);
|
||||
NSLog(@"Watching symlinked directory: %@", path);
|
||||
|
||||
[pathsToWatch addObject:path];
|
||||
}
|
||||
@@ -393,11 +400,11 @@ NSString * const XCCCappuccinoProjectLastEventIDKey = @"XCCCappuccinoPro
|
||||
NSArray *parsedPaths = [XCCCappuccinoProject parseIgnorePaths:ignoredPatterns basePath:self.projectPath];
|
||||
[self.ignoredPathPredicates addObjectsFromArray:parsedPaths];
|
||||
|
||||
DDLogVerbose(@"Content of xcodecapp-ignorepath correctly updated %@", self.ignoredPathPredicates);
|
||||
NSLog(@"Content of xcodecapp-ignorepath correctly updated %@", self.ignoredPathPredicates);
|
||||
}
|
||||
@catch(NSException *exception)
|
||||
{
|
||||
DDLogVerbose(@"Content of xcodecapp-ignorepath does not math the expected input");
|
||||
NSLog(@"Content of xcodecapp-ignorepath does not math the expected input");
|
||||
self.ignoredPathPredicates = [@[] mutableCopy];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
if (![self _projectPathExists] || self.cappuccinoProject.status == XCCCappuccinoProjectStatusListening)
|
||||
return;
|
||||
|
||||
DDLogInfo(@"Start to listen project: %@", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Start to listen project: %@", self.cappuccinoProject.projectPath);
|
||||
|
||||
[self _synchronizeXcodeSupport];
|
||||
|
||||
@@ -166,7 +166,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
- (void)_synchronizeXcodeSupport
|
||||
{
|
||||
DDLogInfo(@"Synchronize project: %@", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Synchronize project: %@", self.cappuccinoProject.projectPath);
|
||||
|
||||
[self _reinitializeProjectController];
|
||||
[self _reinitializeTaskLauncher];
|
||||
@@ -202,11 +202,11 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (projectCompatibilityVersion == nil)
|
||||
{
|
||||
DDLogVerbose(@"No compatibility version in project");
|
||||
NSLog(@"No compatibility version in project");
|
||||
return NO;
|
||||
}
|
||||
|
||||
DDLogVerbose(@"XcodeCapp/project compatibility version: %0.1f/%0.1f", projectCompatibilityVersion.doubleValue, appCompatibilityVersion);
|
||||
NSLog(@"XcodeCapp/project compatibility version: %0.1f/%0.1f", projectCompatibilityVersion.doubleValue, appCompatibilityVersion);
|
||||
|
||||
return projectCompatibilityVersion.doubleValue >= appCompatibilityVersion;
|
||||
}
|
||||
@@ -227,7 +227,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
[content writeToFile:pbxPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
|
||||
DDLogInfo(@"Xcode support project created at: %@", self.cappuccinoProject.XcodeProjectPath);
|
||||
NSLog(@"Xcode support project created at: %@", self.cappuccinoProject.XcodeProjectPath);
|
||||
}
|
||||
|
||||
- (void)_removeXcodeProject
|
||||
@@ -246,7 +246,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
[self.cappuccinoProject saveSettings];
|
||||
|
||||
DDLogInfo(@".XcodeSupport directory created at: %@", self.cappuccinoProject.supportPath);
|
||||
NSLog(@".XcodeSupport directory created at: %@", self.cappuccinoProject.supportPath);
|
||||
}
|
||||
|
||||
- (void)_removeXcodeSupportDirectory
|
||||
@@ -311,7 +311,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
- (void)_updateXcodeSupportFilesWithModifiedPaths:(NSArray *)modifiedPaths
|
||||
{
|
||||
DDLogVerbose(@"Modified files: %@", modifiedPaths);
|
||||
NSLog(@"Modified files: %@", modifiedPaths);
|
||||
|
||||
for (NSString *path in modifiedPaths)
|
||||
{
|
||||
@@ -328,7 +328,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
- (void)_updateXcodeSupportFilesWithRenamedDirectories:(NSArray *)directories
|
||||
{
|
||||
DDLogVerbose(@"Renamed directories: %@", directories);
|
||||
NSLog(@"Renamed directories: %@", directories);
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
@@ -851,7 +851,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
FSEventStreamScheduleWithRunLoop(self->stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
FSEventStreamStart(self->stream);
|
||||
|
||||
DDLogVerbose(@"FSEventStream started for paths: %@", pathsToWatch);
|
||||
NSLog(@"FSEventStream started for paths: %@", pathsToWatch);
|
||||
}
|
||||
|
||||
- (void)_stopFSEventStream
|
||||
@@ -874,7 +874,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
self->stream = NULL;
|
||||
|
||||
DDLogVerbose(@"FSEventStream stopped");
|
||||
NSLog(@"FSEventStream stopped");
|
||||
}
|
||||
|
||||
- (void)_handleFSEventsWithPaths:(NSArray *)paths flags:(const FSEventStreamEventFlags[])eventFlags ids:(const FSEventStreamEventId[])eventIds
|
||||
@@ -895,7 +895,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (rootChanged || needRescan)
|
||||
{
|
||||
DDLogVerbose(@"Watched path changed: %@", path);
|
||||
NSLog(@"Watched path changed: %@", path);
|
||||
|
||||
[self _handleProjectPathChange:path];
|
||||
return;
|
||||
@@ -905,7 +905,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (isHistoryDoneSentinalEvent)
|
||||
{
|
||||
DDLogVerbose(@"History done sentinal event");
|
||||
NSLog(@"History done sentinal event");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -913,7 +913,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (isMountEvent)
|
||||
{
|
||||
DDLogVerbose(@"Volume %@: %@", (flags & kFSEventStreamEventFlagMount) ? @"mounted" : @"unmounted", path);
|
||||
NSLog(@"Volume %@: %@", (flags & kFSEventStreamEventFlagMount) ? @"mounted" : @"unmounted", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -936,7 +936,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
![XCCCappuccinoProject shouldIgnoreDirectoryNamed:path.lastPathComponent] &&
|
||||
![XCCCappuccinoProject pathMatchesIgnoredPaths:path cappuccinoProjectIgnoredPathPredicates:self.cappuccinoProject.ignoredPathPredicates])
|
||||
{
|
||||
DDLogVerbose(@"Renamed directory: %@", path);
|
||||
NSLog(@"Renamed directory: %@", path);
|
||||
|
||||
[renamedDirectories addObject:path];
|
||||
}
|
||||
@@ -947,7 +947,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
(created || modified || renamed || removed || inodeMetaModified) &&
|
||||
[XCCCappuccinoProject isSourceFile:path cappuccinoProject:self.cappuccinoProject])
|
||||
{
|
||||
DDLogVerbose(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
NSLog(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
|
||||
if ([fm fileExistsAtPath:path])
|
||||
{
|
||||
@@ -973,7 +973,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
}
|
||||
else if ((isFile || isSymlink) && (renamed || removed) && !(modified || created) && [XCCCappuccinoProject isCibFile:path])
|
||||
{
|
||||
DDLogVerbose(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
NSLog(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
|
||||
// If a cib is deleted, mark its xib as needing update so the cib is regenerated
|
||||
NSString *xibPath = [path.stringByDeletingPathExtension stringByAppendingPathExtension:@"xib"];
|
||||
@@ -988,7 +988,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
(created || modified || renamed || removed || inodeMetaModified) &&
|
||||
[XCCCappuccinoProject isXCCIgnoreFile:path cappuccinoProject:self.cappuccinoProject])
|
||||
{
|
||||
DDLogVerbose(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
NSLog(@"FSEvent accepted: %@ (%@)", path, [XCCFSEventLogUtils dumpFSEventFlags:flags]);
|
||||
|
||||
[self.cappuccinoProject reloadXcodeCappIgnoreFile];
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
- (void)reinitializeProjectFromSettings
|
||||
{
|
||||
DDLogVerbose(@"Saving Cappuccino configuration project %@", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Saving Cappuccino configuration project %@", self.cappuccinoProject.projectPath);
|
||||
|
||||
[self _cancelAllProjectRelatedOperations];
|
||||
[self.cappuccinoProject saveSettings];
|
||||
@@ -1152,7 +1152,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
if (previousStatus == XCCCappuccinoProjectStatusListening)
|
||||
[self _startListeningToProject];
|
||||
|
||||
DDLogVerbose(@"Cappuccino configuration project %@ has been saved", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Cappuccino configuration project %@ has been saved", self.cappuccinoProject.projectPath);
|
||||
}
|
||||
|
||||
- (void)applicationIsClosing
|
||||
@@ -1199,7 +1199,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t n
|
||||
|
||||
if (exists && isDirectory)
|
||||
{
|
||||
DDLogVerbose(@"Opening Xcode project at: %@", self.cappuccinoProject.XcodeProjectPath);
|
||||
NSLog(@"Opening Xcode project at: %@", self.cappuccinoProject.XcodeProjectPath);
|
||||
|
||||
isOpened = [[NSWorkspace sharedWorkspace] openFile:self.cappuccinoProject.XcodeProjectPath];
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ static NSColor * XCCCappuccinoProjectDataViewColorError;
|
||||
self->boxStatus.fillColor = XCCCappuccinoProjectDataViewColorStopped;
|
||||
self->buttonSwitchStatus.image = self.backgroundStyle == NSBackgroundStyleDark ? [NSImage imageNamed:@"run-white"] : [NSImage imageNamed:@"run"];
|
||||
self->operationsProgressIndicator.hidden = YES;
|
||||
[self->operationsProgressIndicator stopAnimation:self];
|
||||
break;
|
||||
|
||||
case XCCCappuccinoProjectStatusListening:
|
||||
@@ -103,6 +104,7 @@ static NSColor * XCCCappuccinoProjectDataViewColorError;
|
||||
{
|
||||
self->operationsProgressIndicator.hidden = YES;
|
||||
[self->operationsProgressIndicator setNeedsDisplay:YES];
|
||||
[self->operationsProgressIndicator stopAnimation:self];
|
||||
}
|
||||
else if (self.controller.operationsTotal <= 4)
|
||||
{
|
||||
@@ -115,6 +117,7 @@ static NSColor * XCCCappuccinoProjectDataViewColorError;
|
||||
self->operationsProgressIndicator.hidden = NO;
|
||||
self->operationsProgressIndicator.indeterminate = NO;
|
||||
self->operationsProgressIndicator.currentValue = self.controller.operationsProgress;
|
||||
[self->operationsProgressIndicator startAnimation:self];
|
||||
[self->operationsProgressIndicator setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
}
|
||||
|
||||
@property XCCCappuccinoProjectController *cappuccinoProjectController;
|
||||
@property BOOL selected;
|
||||
|
||||
- (void)selectItem:(id)anItem;
|
||||
- (void)reload;
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
|
||||
- (void)reload
|
||||
{
|
||||
if (!_selected)
|
||||
return;
|
||||
|
||||
[self->errorOutlineView reloadData];
|
||||
[self->errorOutlineView expandItem:nil expandChildren:YES];
|
||||
|
||||
|
||||
@@ -125,13 +125,13 @@
|
||||
|
||||
- (void)_restoreLastSelectedProject
|
||||
{
|
||||
DDLogVerbose(@"Start : selecting last selected project");
|
||||
NSLog(@"Start : selecting last selected project");
|
||||
|
||||
NSString *lastSelectedProjectPath = [[NSUserDefaults standardUserDefaults] valueForKey:XCCUserDefaultsSelectedProjectPath];
|
||||
|
||||
[self _selectCappuccinoProjectControllerWithPath:lastSelectedProjectPath];
|
||||
|
||||
DDLogVerbose(@"Stop : selecting last selected project");
|
||||
NSLog(@"Stop : selecting last selected project");
|
||||
}
|
||||
|
||||
- (void)_selectCappuccinoProjectControllerWithPath:(NSString*)aCappuccinoProjectPath
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
- (void)_restoreManagedProjects
|
||||
{
|
||||
DDLogVerbose(@"restore managed projects");
|
||||
NSLog(@"restore managed projects");
|
||||
self.cappuccinoProjectControllers = [@[] mutableCopy];
|
||||
|
||||
NSArray *projectHistory = [[NSUserDefaults standardUserDefaults] arrayForKey:XCCUserDefaultsManagedProjects];
|
||||
@@ -164,11 +164,11 @@
|
||||
|
||||
for (NSString *path in projectHistory)
|
||||
{
|
||||
DDLogVerbose(@"Checking previously managed project at path: %@", path);
|
||||
NSLog(@"Checking previously managed project at path: %@", path);
|
||||
if (![fm fileExistsAtPath:path isDirectory:nil])
|
||||
{
|
||||
[missingProjects addObject:path];
|
||||
DDLogVerbose(@"Not found: project at path: %@", path);
|
||||
NSLog(@"Not found: project at path: %@", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
[controller switchProjectListeningStatus:self];
|
||||
}
|
||||
|
||||
DDLogVerbose(@"managed projects restored");
|
||||
NSLog(@"managed projects restored");
|
||||
}
|
||||
|
||||
- (void)_saveSelectedProject
|
||||
@@ -344,11 +344,26 @@
|
||||
[self _setTextColor:[NSColor colorWithCalibratedRed:107.0/255.0 green:148.0/255.0 blue:236.0/255.0 alpha:1.0] forButton:sender];
|
||||
|
||||
if (sender == self->buttonSelectConfigurationTab)
|
||||
{
|
||||
[_operationsViewController setSelected:NO];
|
||||
[_errorsViewController setSelected:NO];
|
||||
[self->tabViewProject selectTabViewItemAtIndex:0];
|
||||
if (sender == self->buttonSelectErrorsTab)
|
||||
}
|
||||
else if (sender == self->buttonSelectErrorsTab)
|
||||
{
|
||||
[_operationsViewController setSelected:NO];
|
||||
[_errorsViewController setSelected:YES];
|
||||
[self->tabViewProject selectTabViewItemAtIndex:1];
|
||||
if (sender == self->buttonSelectOperationsTab)
|
||||
[_errorsViewController reload];
|
||||
}
|
||||
else if (sender == self->buttonSelectOperationsTab)
|
||||
{
|
||||
[_operationsViewController setSelected:YES];
|
||||
[_errorsViewController setSelected:NO];
|
||||
[self->tabViewProject selectTabViewItemAtIndex:2];
|
||||
[_operationsViewController reload];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
}
|
||||
|
||||
@property XCCCappuccinoProjectController *cappuccinoProjectController;
|
||||
@property BOOL selected;
|
||||
|
||||
- (void)reload;
|
||||
- (IBAction)cancelAllOperations:(id)sender;
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
|
||||
- (void)reload
|
||||
{
|
||||
if (!_selected)
|
||||
return;
|
||||
|
||||
[self->operationTableView reloadData];
|
||||
|
||||
[self _showMaskingView:![self.cappuccinoProjectController projectRelatedOperations].count];
|
||||
|
||||
@@ -69,7 +69,7 @@ NSString * const XCCPBXOperationDidEndNotification = @"XCCPbxCreationDidEndNotif
|
||||
{
|
||||
[self dispatchNotificationName:XCCPBXOperationDidStartNotification];
|
||||
|
||||
DDLogVerbose(@"Pbx creation started: %@", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Pbx creation started: %@", self.cappuccinoProject.projectPath);
|
||||
|
||||
@try
|
||||
{
|
||||
@@ -88,7 +88,7 @@ NSString * const XCCPBXOperationDidEndNotification = @"XCCPbxCreationDidEndNotif
|
||||
shouldLaunchTask = YES;
|
||||
}
|
||||
|
||||
DDLogVerbose(@"PBX: path to %@ : %@", action, paths);
|
||||
NSLog(@"PBX: path to %@ : %@", action, paths);
|
||||
}
|
||||
|
||||
if (shouldLaunchTask)
|
||||
@@ -109,7 +109,7 @@ NSString * const XCCPBXOperationDidEndNotification = @"XCCPbxCreationDidEndNotif
|
||||
@catch (NSException *exception)
|
||||
{
|
||||
[self dispatchNotificationName:XCCPbxCreationGenerateErrorNotification];
|
||||
DDLogVerbose(@"Pbx creation failed: %@", exception);
|
||||
NSLog(@"Pbx creation failed: %@", exception);
|
||||
}
|
||||
@finally
|
||||
{
|
||||
@@ -117,10 +117,11 @@ NSString * const XCCPBXOperationDidEndNotification = @"XCCPbxCreationDidEndNotif
|
||||
|
||||
self.completionBlock = ^{
|
||||
[weakOperation dispatchNotificationName:XCCPBXOperationDidEndNotification];
|
||||
[weakOperation setCompletionBlock:nil];
|
||||
};
|
||||
}
|
||||
|
||||
DDLogVerbose(@"Pbx creation ended: %@", self.cappuccinoProject.projectPath);
|
||||
NSLog(@"Pbx creation ended: %@", self.cappuccinoProject.projectPath);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -91,7 +91,7 @@ NSString * const XCCNib2CibDidEndNotification = @"XCCNib2C
|
||||
|
||||
- (NSDictionary*)_launchTaskWithCommand:(NSString*)aCommand arguments:(NSArray*)arguments
|
||||
{
|
||||
DDLogVerbose(@"Running processing task: %@ on file: %@", aCommand, self.sourcePath);
|
||||
NSLog(@"Running processing task: %@ on file: %@", aCommand, self.sourcePath);
|
||||
|
||||
self->task = [self->taskLauncher taskWithCommand:aCommand arguments:arguments];
|
||||
|
||||
@@ -184,7 +184,7 @@ NSString * const XCCNib2CibDidEndNotification = @"XCCNib2C
|
||||
|
||||
- (void)main
|
||||
{
|
||||
DDLogVerbose(@"Conversion started: %@", self.sourcePath);
|
||||
NSLog(@"Conversion started: %@", self.sourcePath);
|
||||
|
||||
[self dispatchNotificationName:XCCConversionDidStartNotification];
|
||||
|
||||
@@ -211,7 +211,7 @@ NSString * const XCCNib2CibDidEndNotification = @"XCCNib2C
|
||||
}
|
||||
@catch (NSException *exception)
|
||||
{
|
||||
DDLogVerbose(@"Conversion failed: %@", exception);
|
||||
NSLog(@"Conversion failed: %@", exception);
|
||||
}
|
||||
@finally
|
||||
{
|
||||
@@ -219,10 +219,11 @@ NSString * const XCCNib2CibDidEndNotification = @"XCCNib2C
|
||||
|
||||
self.completionBlock = ^{
|
||||
[weakOperation dispatchNotificationName:XCCConversionDidEndNotification];
|
||||
[weakOperation setCompletionBlock:nil];
|
||||
};
|
||||
}
|
||||
|
||||
DDLogVerbose(@"Conversion ended: %@", self.sourcePath);
|
||||
NSLog(@"Conversion ended: %@", self.sourcePath);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -36,7 +36,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
#pragma mark - Utilities
|
||||
|
||||
- (NSArray *)_findSourceFilesAtProjectPath:(NSString *)aProjectPath
|
||||
{
|
||||
{
|
||||
NSError *error = NULL;
|
||||
NSString *projectPath = [self.cappuccinoProject.projectPath stringByAppendingPathComponent:aProjectPath];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
@@ -80,7 +80,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
{
|
||||
if ([XCCCappuccinoProject shouldIgnoreDirectoryNamed:filename])
|
||||
{
|
||||
DDLogVerbose(@"%@: ignored symlinked directory: %@", self.cappuccinoProject.name, projectRelativePath);
|
||||
NSLog(@"%@: ignored symlinked directory: %@", self.cappuccinoProject.name, projectRelativePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
|
||||
if (![realPath hasPrefix:fullProjectPath] && ![XCCCappuccinoProject pathMatchesIgnoredPaths:fullProjectPath cappuccinoProjectIgnoredPathPredicates:self.cappuccinoProject.ignoredPathPredicates])
|
||||
{
|
||||
DDLogVerbose(@"%@: symlinked directory: %@ -> %@", self.cappuccinoProject.name, projectRelativePath, realPath);
|
||||
NSLog(@"%@: symlinked directory: %@ -> %@", self.cappuccinoProject.name, projectRelativePath, realPath);
|
||||
|
||||
NSMutableDictionary *info = [self operationInformations];
|
||||
info[@"sourcePath"] = realPath;
|
||||
@@ -101,12 +101,13 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
[self dispatchNotificationName:XCCNeedSourceToProjectPathMappingNotification userInfo:info];
|
||||
}
|
||||
else
|
||||
DDLogVerbose(@"%@: ignored symlinked directory: %@", self.cappuccinoProject.name, projectRelativePath);
|
||||
NSLog(@"%@: ignored symlinked directory: %@", self.cappuccinoProject.name, projectRelativePath);
|
||||
}
|
||||
|
||||
DDLogVerbose(@"%@: found directory. checking for source files: %@", self.cappuccinoProject.name, filename);
|
||||
|
||||
NSLog(@"%@: found directory. checking for source files: %@", self.cappuccinoProject.name, filename);
|
||||
|
||||
[sourcePaths addObjectsFromArray:[self _findSourceFilesAtProjectPath:projectRelativePath]];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
|
||||
if ([XCCCappuccinoProject isObjjFile:filename] || [XCCCappuccinoProject isXibFile:filename])
|
||||
{
|
||||
DDLogVerbose(@"%@: found source file: %@", self.cappuccinoProject.name, filename);
|
||||
NSLog(@"%@: found source file: %@", self.cappuccinoProject.name, filename);
|
||||
|
||||
NSString *processedPath;
|
||||
|
||||
@@ -130,7 +131,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
[sourcePaths addObject:projectSourcePath];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return sourcePaths;
|
||||
}
|
||||
|
||||
@@ -139,7 +140,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
|
||||
- (void)main
|
||||
{
|
||||
DDLogVerbose(@"Finding source files started");
|
||||
NSLog(@"Finding source files started");
|
||||
|
||||
NSArray *sourcesPaths;
|
||||
|
||||
@@ -151,7 +152,7 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
}
|
||||
@catch (NSException *exception)
|
||||
{
|
||||
DDLogVerbose(@"Finding source files failed: %@", exception);
|
||||
NSLog(@"Finding source files failed: %@", exception);
|
||||
}
|
||||
@finally
|
||||
{
|
||||
@@ -160,10 +161,11 @@ NSString * const XCCNeedSourceToProjectPathMappingNotification = @"XCCNeedSource
|
||||
|
||||
self.completionBlock = ^{
|
||||
[weakOperation dispatchNotificationName:XCCSourcesFinderOperationDidEndNotification userInfo:@{@"cappuccinoProject": weakOperation.cappuccinoProject, @"sourcePaths" : weakSourcesPaths}];
|
||||
[weakOperation setCompletionBlock:nil];
|
||||
};
|
||||
}
|
||||
|
||||
DDLogVerbose(@"Finding source files ended");
|
||||
NSLog(@"Finding source files ended");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -29,7 +29,7 @@
|
||||
[self.binaryPaths addObject:@"/usr/local/narwhal/bin"];
|
||||
[self.binaryPaths addObject:@"~/narwhal/bin"];
|
||||
|
||||
DDLogError(@"Init task manager with environements %@", self.binaryPaths);
|
||||
NSLog(@"Init task manager with environements %@", self.binaryPaths);
|
||||
|
||||
NSMutableArray *paths = [self.binaryPaths mutableCopy];
|
||||
|
||||
@@ -59,13 +59,13 @@
|
||||
|
||||
if ([taskResult[@"status"] integerValue] != 0)
|
||||
{
|
||||
DDLogError(@"Could not find executable in PATH: %@", self.environment[@"PATH"]);
|
||||
NSLog(@"Could not find executable in PATH: %@", self.environment[@"PATH"]);
|
||||
return NO;
|
||||
}
|
||||
|
||||
self.executablePaths = (NSMutableDictionary*)[NSJSONSerialization JSONObjectWithData:[taskResult[@"response"] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
|
||||
|
||||
DDLogVerbose(@"Executable paths: %@", self.executablePaths);
|
||||
NSLog(@"Executable paths: %@", self.executablePaths);
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -145,13 +145,13 @@
|
||||
{
|
||||
[aTask launch];
|
||||
|
||||
DDLogVerbose(@"Task launched: %@\n%@", aTask.launchPath, aTask.arguments);
|
||||
NSLog(@"Task launched: %@\n%@", aTask.launchPath, aTask.arguments);
|
||||
|
||||
if (returnType != kTaskReturnTypeNone)
|
||||
{
|
||||
[aTask waitUntilExit];
|
||||
|
||||
DDLogVerbose(@"Task exited: %@\n%@\nExit code:%d", aTask.launchPath, aTask.arguments, aTask.terminationStatus);
|
||||
NSLog(@"Task exited: %@\n%@\nExit code:%d", aTask.launchPath, aTask.arguments, aTask.terminationStatus);
|
||||
|
||||
NSData *data = nil;
|
||||
|
||||
@@ -203,11 +203,11 @@
|
||||
|
||||
[task launch];
|
||||
|
||||
DDLogVerbose(@"Task launched: %@\n%@", launchPath, arguments);
|
||||
NSLog(@"Task launched: %@\n%@", launchPath, arguments);
|
||||
|
||||
[task waitUntilExit];
|
||||
|
||||
DDLogVerbose(@"Task exited: %@:%d", launchPath, task.terminationStatus);
|
||||
NSLog(@"Task exited: %@:%d", launchPath, task.terminationStatus);
|
||||
|
||||
NSNumber *status = @(task.terminationStatus);
|
||||
NSData *data = nil;
|
||||
@@ -230,7 +230,7 @@
|
||||
NSData *data = [notification userInfo][NSFileHandleNotificationDataItem];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
|
||||
|
||||
DDLogVerbose(@"Jake receive data\n %@", string);
|
||||
NSLog(@"Jake receive data\n %@", string);
|
||||
|
||||
[[notification object] readInBackgroundAndNotify];
|
||||
}
|
||||
@@ -240,7 +240,7 @@
|
||||
NSData *data = [notification userInfo][NSFileHandleNotificationDataItem];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
|
||||
|
||||
DDLogVerbose(@"Jake receive error\%@", string);
|
||||
NSLog(@"Jake receive error\%@", string);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
extern NSString * const XCCUserDefaultsAutoOpenXcodeProject;
|
||||
extern NSString * const XCCUserDefaultsManagedProjects;
|
||||
extern NSString * const XCCUserDefaultsLogLevel;
|
||||
extern NSString * const XCCUserDefaultsSelectedProjectPath;
|
||||
extern NSString * const XCCUserDefaultsMaxNumberOfConcurrentOperations;
|
||||
|
||||
|
||||
@@ -10,6 +10,5 @@
|
||||
|
||||
NSString * const XCCUserDefaultsAutoOpenXcodeProject = @"XCCUserDefaultsAutoOpenXcodeProject";
|
||||
NSString * const XCCUserDefaultsManagedProjects = @"XCCUserDefaultsManagedProjects";
|
||||
NSString * const XCCUserDefaultsLogLevel = @"XCCUserDefaultsLogLevel";
|
||||
NSString * const XCCUserDefaultsSelectedProjectPath = @"XCCUserDefaultsSelectedProjectPath";
|
||||
NSString * const XCCUserDefaultsMaxNumberOfConcurrentOperations = @"XCCUserDefaultsMaxNumberOfConcurrentOperations";
|
||||
@@ -4,13 +4,4 @@
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "DDLog.h"
|
||||
|
||||
#if DEBUG
|
||||
#import "DDTTYLogger.h"
|
||||
#else
|
||||
#import "DDASLLogger.h"
|
||||
#endif
|
||||
|
||||
#import "DDLogLevel.h"
|
||||
#endif
|
||||
@@ -28,12 +28,17 @@ static const char *kCloseXcodeProjectScript =
|
||||
@implementation XcodeProjectCloser
|
||||
|
||||
+ (void)closeXcodeProjectForProject:(NSString *)projectPath
|
||||
{
|
||||
NSString *format = @(kCloseXcodeProjectScript);
|
||||
NSString *source = [NSString stringWithFormat:format, projectPath];
|
||||
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:source];
|
||||
|
||||
[script executeAndReturnError:nil];
|
||||
{
|
||||
NSString *format = @(kCloseXcodeProjectScript);
|
||||
NSString *source = [NSString stringWithFormat:format, projectPath];
|
||||
NSString *arguments = [NSString stringWithFormat:@"-e %@", source];
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
|
||||
[task setLaunchPath:@"/usr/bin/osascript"];
|
||||
[task setArguments:[NSArray arrayWithObjects:arguments, nil]];
|
||||
[task launch];
|
||||
|
||||
NSLog(@"Osascript launched for the project %@", projectPath);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -40,7 +40,7 @@ app (projectName, function(task)
|
||||
if (configuration === "Debug")
|
||||
task.setCompilerFlags("-DDEBUG -g");
|
||||
else
|
||||
task.setCompilerFlags("-O");
|
||||
task.setCompilerFlags("-O2");
|
||||
});
|
||||
|
||||
task ("default", [projectName], function()
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
|
||||
// The below will tell the compiler to generate debug symbols, type signatures and not inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
//
|
||||
// Debug symbols will give each Objective-J method a Javascript function name. Without a name it will be very hard to find
|
||||
// the methods in the debugger.
|
||||
// Type Signatures will give type information to the Objective-J runtime for instance variables and methods.
|
||||
// Inline objj_msgSend will give a speed increase but decorators will not work. Check below on debug options for
|
||||
// more information on decorators.
|
||||
//
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures"/*, "InlineMsgSend"*/];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
@@ -62,6 +74,7 @@
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
// Decorators will only work when the code is compiled without the compiler option 'InlineMsgSend'. Check above.
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
// The below will tell the compiler to not generate debug symbols but will generate type signatures and inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = [/*"IncludeDebugSymbols"*/, "IncludeTypeSignatures", "InlineMsgSend"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ var frameworkTask = framework (productName, function(frameworkTask)
|
||||
if (configuration === "Debug")
|
||||
frameworkTask.setCompilerFlags("-DDEBUG -g");
|
||||
else
|
||||
frameworkTask.setCompilerFlags("-O");
|
||||
frameworkTask.setCompilerFlags("-O2");
|
||||
});
|
||||
|
||||
task ("debug", function()
|
||||
|
||||
@@ -40,7 +40,7 @@ app (projectName, function(task)
|
||||
if (configuration === "Debug")
|
||||
task.setCompilerFlags("-DDEBUG -g");
|
||||
else
|
||||
task.setCompilerFlags("-O");
|
||||
task.setCompilerFlags("-O2");
|
||||
});
|
||||
|
||||
task ("default", [projectName], function()
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
|
||||
// The below will tell the compiler to generate debug symbols, type signatures and not inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
//
|
||||
// Debug symbols will give each Objective-J method a Javascript function name. Without a name it will be very hard to find
|
||||
// the methods in the debugger.
|
||||
// Type Signatures will give type information to the Objective-J runtime for instance variables and methods.
|
||||
// Inline objj_msgSend will give a speed increase but decorators will not work. Check below on debug options for
|
||||
// more information on decorators.
|
||||
//
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures"/*, "InlineMsgSend"*/];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
@@ -62,6 +74,7 @@
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
// Decorators will only work when the code is compiled without the compiler option 'InlineMsgSend'. Check above.
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
// The below will tell the compiler to not generate debug symbols but will generate type signatures and inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = [/*"IncludeDebugSymbols"*/, "IncludeTypeSignatures", "InlineMsgSend"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
|
||||
// The below will tell the compiler to generate debug symbols, type signatures and not inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
//
|
||||
// Debug symbols will give each Objective-J method a Javascript function name. Without a name it will be very hard to find
|
||||
// the methods in the debugger.
|
||||
// Type Signatures will give type information to the Objective-J runtime for instance variables and methods.
|
||||
// Inline objj_msgSend will give a speed increase but decorators will not work. Check below on debug options for
|
||||
// more information on decorators.
|
||||
//
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures"/*, "InlineMsgSend"*/];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
@@ -62,6 +74,7 @@
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
// Decorators will only work when the code is compiled without the compiler option 'InlineMsgSend'. Check above.
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
// The below will tell the compiler to not generate debug symbols but will generate type signatures and inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = [/*"IncludeDebugSymbols"*/, "IncludeTypeSignatures", "InlineMsgSend"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ global.filedir = JAKE.filedir;
|
||||
global.FileList = JAKE.FileList;
|
||||
|
||||
global.$CONFIGURATION = SYSTEM.env['CONFIG'];
|
||||
global.$INLINE_MSG_SEND = SYSTEM.env['INLINE_MSG_SEND'];
|
||||
global.$BUILD_DIR = SYSTEM.env['BUILD_PATH'];
|
||||
global.$BUILD_CONFIGURATION_DIR = FILE.join($BUILD_DIR, $CONFIGURATION);
|
||||
|
||||
|
||||
Reference in new issue
Block a user