Merge branch 'objj_compiler2' into objj2integration

Conflicts:
	AppKit/CPWindow/CPWindow.j
This commit is contained in:
Antoine Mercadal
2013-01-14 11:43:24 -08:00
98 changed files with 9780 additions and 6153 deletions
+1 -1
View File
@@ -407,7 +407,7 @@ CPRunContinuesResponse = -1002;
}
- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
- (void)_documentController:(CPDocumentController)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
{
// callback method for terminate:
if (didCloseAll)
+2 -2
View File
@@ -989,5 +989,5 @@ var CPButtonImageKey = @"CPButtonImageKey",
@end
@import "CPCheckBox.j"
@import "CPRadio.j"
//@import "CPCheckBox.j"
//@import "CPRadio.j"
+1 -1
View File
@@ -22,7 +22,7 @@
#import "../Foundation/Ref.h"
@import "../Foundation/CPFormatter.j"
@import <Foundation/CPFormatter.j>
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
+2 -2
View File
@@ -142,7 +142,7 @@ var CPDocumentUntitledCount = 0;
@param anError not used
@return the initialized document
*/
- (id)initWithType:(CPString)aType error:({CPError})anError
- (id)initWithType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
self = [self init];
@@ -211,7 +211,7 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overridden by the subclass
@return the document data
*/
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
- (CPData)dataOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
[CPException raise:CPUnsupportedMethodException
reason:"dataOfType:error: must be overridden by the document subclass."];
+1 -1
View File
@@ -124,7 +124,7 @@ var CPSharedDocumentController = nil;
@param anError not used
@return the created document
*/
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:({CPError})anError
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
return [[[self documentClassForType:aType] alloc] initWithType:aType error:anError];
}
+1 -1
View File
@@ -1,5 +1,5 @@
@import <AppKit/CPControl.j>
@import "CPControl.j"
@import "_CPMenuItemSeparatorView.j"
@import "_CPMenuItemStandardView.j"
+3 -3
View File
@@ -20,13 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPTextField.j>
@import <AppKit/CPViewAnimation.j>
@import <AppKit/CPView.j>
@import <Foundation/CPPredicate.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPIndexSet.j>
@import "CPTextField.j"
@import "CPViewAnimation.j"
@import "CPView.j"
@import "_CPRuleEditorViewSliceRow.j"
@import "_CPRuleEditorLocalizer.j"
@@ -3,7 +3,7 @@
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*/
@class _CPPredicateEditorTree;
//@class _CPPredicateEditorTree;
@implementation _CPPredicateEditorRowNode : CPObject
{
_CPPredicateEditorTree tree @accessors;
@@ -77,3 +77,5 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
return aString;
}
@end
+3 -3
View File
@@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import "CPControl.j"
@import "CPButton.j"
@import "CPTextField.j"
+1
View File
@@ -27,6 +27,7 @@
@import <Foundation/CPString.j>
@import "CPTableHeaderView.j"
@import "CPKeyValueBinding.j"
CPTableColumnNoResizing = 0;
+1
View File
@@ -21,6 +21,7 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPMutableArray.j>
@import <Foundation/CPString.j>
@import <Foundation/CPKeyedUnarchiver.j>
+1 -1
View File
@@ -921,7 +921,7 @@ var CPScrollDestinationNone = 0,
[self interpretKeyEvents:[anEvent]];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}}
}
- (void)keyUp:(CPEvent)anEvent
{
+1 -634
View File
@@ -20,641 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPView.j"
CPToolbarItemVisibilityPriorityStandard = 0;
CPToolbarItemVisibilityPriorityLow = -1000;
CPToolbarItemVisibilityPriorityHigh = 1000;
CPToolbarItemVisibilityPriorityUser = 2000;
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItem";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItem";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItem";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItem";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
/*!
@ingroup appkit
@class CPToolbarItem
A representation of an item in a CPToolbar.
*/
@implementation CPToolbarItem : CPObject
{
CPString _itemIdentifier;
CPToolbar _toolbar;
CPString _label;
CPString _paletteLabel;
CPString _toolTip;
int _tag;
id _target;
SEL _action;
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
int _visibilityPriority;
BOOL _autovalidates;
}
- (id)init
{
return [self initWithItemIdentifier:@""];
}
// Creating a Toolbar Item
/*!
Initializes the toolbar item with a specified identifier.
@param anItemIdentifier the item's identifier
@return the initialized toolbar item
*/
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
{
self = [super init];
if (self)
{
_itemIdentifier = anItemIdentifier;
_tag = 0;
_isEnabled = YES;
_minSize = CGSizeMakeZero();
_maxSize = CGSizeMakeZero();
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
_autovalidates = YES;
}
return self;
}
// Managing Attributes
/*!
Returns the item's identifier.
*/
- (CPString)itemIdentifier
{
return _itemIdentifier;
}
/*!
Returns the toolbar of which this item is a part.
*/
- (CPToolbar)toolbar
{
return _toolbar;
}
/* @ignore */
- (void)_setToolbar:(CPToolbar)aToolbar
{
_toolbar = aToolbar;
}
/*!
Returns the item's label
*/
- (CPString)label
{
return _label;
}
/*!
Sets the item's label.
@param aLabel the new label for the item
*/
- (void)setLabel:(CPString)aLabel
{
_label = aLabel;
}
/*!
Returns the palette label.
*/
- (CPString)paletteLabel
{
return _paletteLabel;
}
/*!
Sets the palette label
@param aPaletteLabel the new palette label
*/
- (void)setPaletteLabel:(CPString)aPaletteLabel
{
_paletteLabel = aPaletteLabel;
}
/*!
Returns the item's tooltip. A tooltip pops up
next to the cursor when the user hovers over
the item with the mouse.
*/
- (CPString)toolTip
{
if ([_view respondsToSelector:@selector(toolTip)])
return [_view toolTip];
return _toolTip;
}
/*!
Sets the item's tooltip. A tooltip pops up next to the cursor when the user hovers over the item with the mouse.
@param aToolTip the new item tool tip
*/
- (void)setToolTip:(CPString)aToolTip
{
if ([_view respondsToSelector:@selector(setToolTip:)])
[_view setToolTip:aToolTip];
_toolTip = aToolTip;
}
/*!
Returns the item's tag.
*/
- (int)tag
{
if ([_view respondsToSelector:@selector(tag)])
return [_view tag];
return _tag;
}
/*!
Sets the item's tag.
@param aTag the new tag for the item
*/
- (void)setTag:(int)aTag
{
if ([_view respondsToSelector:@selector(setTag:)])
[_view setTag:aTag];
_tag = aTag;
}
/*!
Returns the item's action target.
*/
- (id)target
{
if (_view)
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
return _target;
}
/*!
Sets the target of the action that is triggered when the user clicks this item. \c nil will cause
the action to be passed on to the first responder.
@param aTarget the new target
*/
- (void)setTarget:(id)aTarget
{
if (!_view)
_target = aTarget;
else if ([_view respondsToSelector:@selector(setTarget:)])
[_view setTarget:aTarget];
}
/*!
Returns the action that is triggered when the user clicks this item.
*/
- (SEL)action
{
if (_view)
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
return _action;
}
/*!
Sets the action that is triggered when the user clicks this item.
@param anAction the new action
*/
- (void)setAction:(SEL)anAction
{
if (!_view)
_action = anAction;
else if ([_view respondsToSelector:@selector(setAction:)])
[_view setAction:anAction];
}
/*!
Returns \c YES if the item is enabled.
*/
- (BOOL)isEnabled
{
if ([_view respondsToSelector:@selector(isEnabled)])
return [_view isEnabled];
return _isEnabled;
}
/*!
Sets whether the item is enabled.
@param aFlag \c YES enables the item
*/
- (void)setEnabled:(BOOL)shouldBeEnabled
{
if (_isEnabled === shouldBeEnabled)
return;
if ([_view respondsToSelector:@selector(setEnabled:)])
[_view setEnabled:shouldBeEnabled];
_isEnabled = shouldBeEnabled;
}
/*!
Returns the item's image
*/
- (CPImage)image
{
if ([_view respondsToSelector:@selector(image)])
return [_view image];
return _image;
}
/*!
Sets the item's image.
@param anImage the new item image
*/
- (void)setImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setImage:)])
[_view setImage:anImage];
_image = anImage;
if (!_image)
return;
if (_minSize.width === 0 && _minSize.height === 0 &&
_maxSize.width === 0 && _maxSize.height === 0)
{
var imageSize = [_image size];
if (imageSize.width > 0 || imageSize.height > 0)
{
[self setMinSize:imageSize];
[self setMaxSize:imageSize];
}
}
}
/*!
Sets the alternate image. This image is displayed on the item when the user is clicking it.
@param anImage the new alternate image
*/
- (void)setAlternateImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setAlternateImage:)])
[_view setAlternateImage:anImage];
_alternateImage = anImage;
}
/*!
Returns the alternate image. This image is displayed on the item when the user is clicking it.
*/
- (CPImage)alternateImage
{
if ([_view respondsToSelector:@selector(alternateIamge)])
return [_view alternateImage];
return _alternateImage;
}
/*!
Returns the item's view.
*/
- (CPView)view
{
return _view;
}
/*!
Sets the item's view
@param aView the item's new view
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if (_view)
{
// Tags get forwarded.
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
[_view setTag:_tag];
_target = nil;
_action = nil;
}
}
/*!
Returns the item's minimum size.
*/
- (CGSize)minSize
{
return _minSize;
}
/*!
Sets the item's minimum size.
@param aMinSize the new minimum size
*/
- (void)setMinSize:(CGSize)aMinSize
{
if (!aMinSize.height || !aMinSize.width)
return;
_minSize = CGSizeMakeCopy(aMinSize);
// Try to provide some sanity: Make maxSize >= minSize
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
}
/*!
Returns the item's maximum size.
*/
- (CGSize)maxSize
{
return _maxSize;
}
/*!
Sets the item's new maximum size.
@param aMaxSize the new maximum size
*/
- (void)setMaxSize:(CGSize)aMaxSize
{
if (!aMaxSize.height || !aMaxSize.width)
return;
_maxSize = CGSizeMakeCopy(aMaxSize);
// Try to provide some sanity: Make minSize <= maxSize
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
}
// Visibility Priority
/*!
Returns the item's visibility priority. The value will be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
*/
- (int)visibilityPriority
{
return _visibilityPriority;
}
/*!
Sets the item's visibility priority. The value must be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
@param aVisiblityPriority the priority
*/
- (void)setVisibilityPriority:(int)aVisibilityPriority
{
_visibilityPriority = aVisibilityPriority;
}
- (void)validate
{
var action = [self action],
target = [self target];
// View items do not do any target-action analysis.
if (_view)
{
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
return;
}
if (!action)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if (target && ![target respondsToSelector:action])
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
target = [CPApp targetForAction:action to:target from:self];
if (!target)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
else
{
if (!_isEnabled)
[self setEnabled:YES];
}
}
- (BOOL)autovalidates
{
return _autovalidates;
}
- (void)setAutovalidates:(BOOL)shouldAutovalidate
{
_autovalidates = !!shouldAutovalidate;
}
@end
var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
CPToolbarItemLabelKey = @"CPToolbarItemLabelKey",
CPToolbarItemPaletteLabelKey = @"CPToolbarItemPaletteLabelKey",
CPToolbarItemToolTipKey = @"CPToolbarItemToolTipKey",
CPToolbarItemTagKey = @"CPToolbarItemTagKey",
CPToolbarItemTargetKey = @"CPToolbarItemTargetKey",
CPToolbarItemActionKey = @"CPToolbarItemActionKey",
CPToolbarItemEnabledKey = @"CPToolbarItemEnabledKey",
CPToolbarItemImageKey = @"CPToolbarItemImageKey",
CPToolbarItemAlternateImageKey = @"CPToolbarItemAlternateImageKey",
CPToolbarItemViewKey = @"CPToolbarItemViewKey",
CPToolbarItemMinSizeKey = @"CPToolbarItemMinSizeKey",
CPToolbarItemMaxSizeKey = @"CPToolbarItemMaxSizeKey",
CPToolbarItemVisibilityPriorityKey = @"CPToolbarItemVisibilityPriorityKey",
CPToolbarItemAutovalidatesKey = @"CPToolbarItemAutovalidatesKey";
@implementation CPToolbarItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_itemIdentifier = [aCoder decodeObjectForKey:CPToolbarItemItemIdentifierKey];
_minSize = [aCoder decodeSizeForKey:CPToolbarItemMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:CPToolbarItemMaxSizeKey];
[self setLabel:[aCoder decodeObjectForKey:CPToolbarItemLabelKey]];
[self setPaletteLabel:[aCoder decodeObjectForKey:CPToolbarItemPaletteLabelKey]];
[self setToolTip:[aCoder decodeObjectForKey:CPToolbarItemToolTipKey]];
[self setTag:[aCoder decodeObjectForKey:CPToolbarItemTagKey]];
[self setTarget:[aCoder decodeObjectForKey:CPToolbarItemTargetKey]];
[self setAction:CPSelectorFromString([aCoder decodeObjectForKey:CPToolbarItemActionKey])];
[self setEnabled:[aCoder decodeBoolForKey:CPToolbarItemEnabledKey]];
[self setImage:[aCoder decodeObjectForKey:CPToolbarItemImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPToolbarItemAlternateImageKey]];
[self setView:[aCoder decodeObjectForKey:CPToolbarItemViewKey]];
[self setVisibilityPriority:[aCoder decodeIntForKey:CPToolbarItemVisibilityPriorityKey]];
[self setAutovalidates:[aCoder decodeBoolForKey:CPToolbarItemAutovalidatesKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_itemIdentifier forKey:CPToolbarItemItemIdentifierKey];
[aCoder encodeObject:[self label] forKey:CPToolbarItemLabelKey];
[aCoder encodeObject:[self paletteLabel] forKey:CPToolbarItemPaletteLabelKey];
[aCoder encodeObject:[self toolTip] forKey:CPToolbarItemToolTipKey];
[aCoder encodeObject:[self tag] forKey:CPToolbarItemTagKey];
[aCoder encodeObject:[self target] forKey:CPToolbarItemTargetKey];
[aCoder encodeObject:[self action] forKey:CPToolbarItemActionKey];
[aCoder encodeObject:[self isEnabled] forKey:CPToolbarItemEnabledKey];
[aCoder encodeObject:[self image] forKey:CPToolbarItemImageKey];
[aCoder encodeObject:[self alternateImage] forKey:CPToolbarItemAlternateImageKey];
[aCoder encodeObject:[self view] forKey:CPToolbarItemViewKey];
[aCoder encodeSize:[self minSize] forKey:CPToolbarItemMinSizeKey];
[aCoder encodeSize:[self maxSize] forKey:CPToolbarItemMaxSizeKey];
[aCoder encodeObject:[self visibilityPriority] forKey:CPToolbarItemVisibilityPriorityKey];
[aCoder encodeBool:[self autovalidates] forKey:CPToolbarItemAutovalidatesKey];
}
@end
@implementation CPToolbarItem (CPCopying)
- (id)copy
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy _setToolbar:_toolbar];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:[self image]];
[copy setAlternateImage:[self alternateImage]];
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
[copy setVisibilityPriority:[self visibilityPriority]];
[copy setAutovalidates:[self autovalidates]];
return copy;
}
@end
// Standard toolbar identifiers
@implementation CPToolbarItem (Standard)
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: return [_CPToolbarSeparatorItem new];
case CPToolbarSpaceItemIdentifier: return [_CPToolbarSpaceItem new];
case CPToolbarFlexibleSpaceItemIdentifier: return [_CPToolbarFlexibleSpaceItem new];
case CPToolbarShowColorsItemIdentifier: return [_CPToolbarShowColorsItem new];
case CPToolbarShowFontsItemIdentifier: return nil;
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
case CPToolbarPrintItemIdentifier: return nil;
}
return nil;
}
@end
@import "_CPToolbarItem.j"
@import "_CPToolbarFlexibleSpaceItem.j"
@import "_CPToolbarShowColorsItem.j"
@import "_CPToolbarSeparatorItem.j"
+1 -1
View File
@@ -25,7 +25,7 @@
@import <Foundation/CPString.j>
@import <AppKit/CPController.j>
@import "CPController.j"
var SharedUserDefaultsController = nil;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -75,7 +75,7 @@ var CAMediaNamedTimingFunctions = nil;
return self;
}
- (void)getControlPointAtIndex:(unsigned)anIndex values:(float[2])reference
- (void)getControlPointAtIndex:(unsigned)anIndex values:(float/*[2]*/)reference
{
if (anIndex == 0)
{
+1 -1
View File
@@ -278,5 +278,5 @@ var PrimaryPlatformWindow = NULL;
@end
#if PLATFORM(BROWSER)
@import "CPPlatformWindow+DOM.j"
//@import "CPPlatformWindow+DOM.j"
#endif
@@ -21,6 +21,9 @@
*/
@import <Foundation/CPObject.j>
@import <AppKit/CPWindow.j>
@import <AppKit/_CPStandardWindowView.j>
@import <AppKit/_CPToolTipWindowView.j>
var ItemSizes = { },
+1
View File
@@ -23,6 +23,7 @@
@import <Foundation/CPObject.j>
@import "CPTextField.j"
@import "CPTableView.j"
@import "_CPMenuWindow.j"
// TODO Make themable.
+1
View File
@@ -21,6 +21,7 @@
*/
@import "CPTableView.j"
@import "CPPanel.j"
@import "_CPPopUpListDataSource.j"
+1 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPToolbarItem.j"
@import "_CPToolbarItem.j"
@implementation _CPToolbarFlexibleSpaceItem : CPToolbarItem
+662
View File
@@ -0,0 +1,662 @@
/*
* CPToolbarItem.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPView.j"
CPToolbarItemVisibilityPriorityStandard = 0;
CPToolbarItemVisibilityPriorityLow = -1000;
CPToolbarItemVisibilityPriorityHigh = 1000;
CPToolbarItemVisibilityPriorityUser = 2000;
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItem";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItem";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItem";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItem";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
/*!
@ingroup appkit
@class CPToolbarItem
A representation of an item in a CPToolbar.
*/
@implementation CPToolbarItem : CPObject
{
CPString _itemIdentifier;
CPToolbar _toolbar;
CPString _label;
CPString _paletteLabel;
CPString _toolTip;
int _tag;
id _target;
SEL _action;
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
int _visibilityPriority;
BOOL _autovalidates;
}
- (id)init
{
return [self initWithItemIdentifier:@""];
}
// Creating a Toolbar Item
/*!
Initializes the toolbar item with a specified identifier.
@param anItemIdentifier the item's identifier
@return the initialized toolbar item
*/
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
{
self = [super init];
if (self)
{
_itemIdentifier = anItemIdentifier;
_tag = 0;
_isEnabled = YES;
_minSize = CGSizeMakeZero();
_maxSize = CGSizeMakeZero();
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
_autovalidates = YES;
}
return self;
}
// Managing Attributes
/*!
Returns the item's identifier.
*/
- (CPString)itemIdentifier
{
return _itemIdentifier;
}
/*!
Returns the toolbar of which this item is a part.
*/
- (CPToolbar)toolbar
{
return _toolbar;
}
/* @ignore */
- (void)_setToolbar:(CPToolbar)aToolbar
{
_toolbar = aToolbar;
}
/*!
Returns the item's label
*/
- (CPString)label
{
return _label;
}
/*!
Sets the item's label.
@param aLabel the new label for the item
*/
- (void)setLabel:(CPString)aLabel
{
_label = aLabel;
}
/*!
Returns the palette label.
*/
- (CPString)paletteLabel
{
return _paletteLabel;
}
/*!
Sets the palette label
@param aPaletteLabel the new palette label
*/
- (void)setPaletteLabel:(CPString)aPaletteLabel
{
_paletteLabel = aPaletteLabel;
}
/*!
Returns the item's tooltip. A tooltip pops up
next to the cursor when the user hovers over
the item with the mouse.
*/
- (CPString)toolTip
{
if ([_view respondsToSelector:@selector(toolTip)])
return [_view toolTip];
return _toolTip;
}
/*!
Sets the item's tooltip. A tooltip pops up next to the cursor when the user hovers over the item with the mouse.
@param aToolTip the new item tool tip
*/
- (void)setToolTip:(CPString)aToolTip
{
if ([_view respondsToSelector:@selector(setToolTip:)])
[_view setToolTip:aToolTip];
_toolTip = aToolTip;
}
/*!
Returns the item's tag.
*/
- (int)tag
{
if ([_view respondsToSelector:@selector(tag)])
return [_view tag];
return _tag;
}
/*!
Sets the item's tag.
@param aTag the new tag for the item
*/
- (void)setTag:(int)aTag
{
if ([_view respondsToSelector:@selector(setTag:)])
[_view setTag:aTag];
_tag = aTag;
}
/*!
Returns the item's action target.
*/
- (id)target
{
if (_view)
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
return _target;
}
/*!
Sets the target of the action that is triggered when the user clicks this item. \c nil will cause
the action to be passed on to the first responder.
@param aTarget the new target
*/
- (void)setTarget:(id)aTarget
{
if (!_view)
_target = aTarget;
else if ([_view respondsToSelector:@selector(setTarget:)])
[_view setTarget:aTarget];
}
/*!
Returns the action that is triggered when the user clicks this item.
*/
- (SEL)action
{
if (_view)
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
return _action;
}
/*!
Sets the action that is triggered when the user clicks this item.
@param anAction the new action
*/
- (void)setAction:(SEL)anAction
{
if (!_view)
_action = anAction;
else if ([_view respondsToSelector:@selector(setAction:)])
[_view setAction:anAction];
}
/*!
Returns \c YES if the item is enabled.
*/
- (BOOL)isEnabled
{
if ([_view respondsToSelector:@selector(isEnabled)])
return [_view isEnabled];
return _isEnabled;
}
/*!
Sets whether the item is enabled.
@param aFlag \c YES enables the item
*/
- (void)setEnabled:(BOOL)shouldBeEnabled
{
if (_isEnabled === shouldBeEnabled)
return;
if ([_view respondsToSelector:@selector(setEnabled:)])
[_view setEnabled:shouldBeEnabled];
_isEnabled = shouldBeEnabled;
}
/*!
Returns the item's image
*/
- (CPImage)image
{
if ([_view respondsToSelector:@selector(image)])
return [_view image];
return _image;
}
/*!
Sets the item's image.
@param anImage the new item image
*/
- (void)setImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setImage:)])
[_view setImage:anImage];
_image = anImage;
if (!_image)
return;
if (_minSize.width === 0 && _minSize.height === 0 &&
_maxSize.width === 0 && _maxSize.height === 0)
{
var imageSize = [_image size];
if (imageSize.width > 0 || imageSize.height > 0)
{
[self setMinSize:imageSize];
[self setMaxSize:imageSize];
}
}
}
/*!
Sets the alternate image. This image is displayed on the item when the user is clicking it.
@param anImage the new alternate image
*/
- (void)setAlternateImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setAlternateImage:)])
[_view setAlternateImage:anImage];
_alternateImage = anImage;
}
/*!
Returns the alternate image. This image is displayed on the item when the user is clicking it.
*/
- (CPImage)alternateImage
{
if ([_view respondsToSelector:@selector(alternateIamge)])
return [_view alternateImage];
return _alternateImage;
}
/*!
Returns the item's view.
*/
- (CPView)view
{
return _view;
}
/*!
Sets the item's view
@param aView the item's new view
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if (_view)
{
// Tags get forwarded.
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
[_view setTag:_tag];
_target = nil;
_action = nil;
}
}
/*!
Returns the item's minimum size.
*/
- (CGSize)minSize
{
return _minSize;
}
/*!
Sets the item's minimum size.
@param aMinSize the new minimum size
*/
- (void)setMinSize:(CGSize)aMinSize
{
if (!aMinSize.height || !aMinSize.width)
return;
_minSize = CGSizeMakeCopy(aMinSize);
// Try to provide some sanity: Make maxSize >= minSize
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
}
/*!
Returns the item's maximum size.
*/
- (CGSize)maxSize
{
return _maxSize;
}
/*!
Sets the item's new maximum size.
@param aMaxSize the new maximum size
*/
- (void)setMaxSize:(CGSize)aMaxSize
{
if (!aMaxSize.height || !aMaxSize.width)
return;
_maxSize = CGSizeMakeCopy(aMaxSize);
// Try to provide some sanity: Make minSize <= maxSize
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
}
// Visibility Priority
/*!
Returns the item's visibility priority. The value will be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
*/
- (int)visibilityPriority
{
return _visibilityPriority;
}
/*!
Sets the item's visibility priority. The value must be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
@param aVisiblityPriority the priority
*/
- (void)setVisibilityPriority:(int)aVisibilityPriority
{
_visibilityPriority = aVisibilityPriority;
}
- (void)validate
{
var action = [self action],
target = [self target];
// View items do not do any target-action analysis.
if (_view)
{
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
return;
}
if (!action)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if (target && ![target respondsToSelector:action])
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
target = [CPApp targetForAction:action to:target from:self];
if (!target)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
else
{
if (!_isEnabled)
[self setEnabled:YES];
}
}
- (BOOL)autovalidates
{
return _autovalidates;
}
- (void)setAutovalidates:(BOOL)shouldAutovalidate
{
_autovalidates = !!shouldAutovalidate;
}
@end
var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
CPToolbarItemLabelKey = @"CPToolbarItemLabelKey",
CPToolbarItemPaletteLabelKey = @"CPToolbarItemPaletteLabelKey",
CPToolbarItemToolTipKey = @"CPToolbarItemToolTipKey",
CPToolbarItemTagKey = @"CPToolbarItemTagKey",
CPToolbarItemTargetKey = @"CPToolbarItemTargetKey",
CPToolbarItemActionKey = @"CPToolbarItemActionKey",
CPToolbarItemEnabledKey = @"CPToolbarItemEnabledKey",
CPToolbarItemImageKey = @"CPToolbarItemImageKey",
CPToolbarItemAlternateImageKey = @"CPToolbarItemAlternateImageKey",
CPToolbarItemViewKey = @"CPToolbarItemViewKey",
CPToolbarItemMinSizeKey = @"CPToolbarItemMinSizeKey",
CPToolbarItemMaxSizeKey = @"CPToolbarItemMaxSizeKey",
CPToolbarItemVisibilityPriorityKey = @"CPToolbarItemVisibilityPriorityKey",
CPToolbarItemAutovalidatesKey = @"CPToolbarItemAutovalidatesKey";
@implementation CPToolbarItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_itemIdentifier = [aCoder decodeObjectForKey:CPToolbarItemItemIdentifierKey];
_minSize = [aCoder decodeSizeForKey:CPToolbarItemMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:CPToolbarItemMaxSizeKey];
[self setLabel:[aCoder decodeObjectForKey:CPToolbarItemLabelKey]];
[self setPaletteLabel:[aCoder decodeObjectForKey:CPToolbarItemPaletteLabelKey]];
[self setToolTip:[aCoder decodeObjectForKey:CPToolbarItemToolTipKey]];
[self setTag:[aCoder decodeObjectForKey:CPToolbarItemTagKey]];
[self setTarget:[aCoder decodeObjectForKey:CPToolbarItemTargetKey]];
[self setAction:CPSelectorFromString([aCoder decodeObjectForKey:CPToolbarItemActionKey])];
[self setEnabled:[aCoder decodeBoolForKey:CPToolbarItemEnabledKey]];
[self setImage:[aCoder decodeObjectForKey:CPToolbarItemImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPToolbarItemAlternateImageKey]];
[self setView:[aCoder decodeObjectForKey:CPToolbarItemViewKey]];
[self setVisibilityPriority:[aCoder decodeIntForKey:CPToolbarItemVisibilityPriorityKey]];
[self setAutovalidates:[aCoder decodeBoolForKey:CPToolbarItemAutovalidatesKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_itemIdentifier forKey:CPToolbarItemItemIdentifierKey];
[aCoder encodeObject:[self label] forKey:CPToolbarItemLabelKey];
[aCoder encodeObject:[self paletteLabel] forKey:CPToolbarItemPaletteLabelKey];
[aCoder encodeObject:[self toolTip] forKey:CPToolbarItemToolTipKey];
[aCoder encodeObject:[self tag] forKey:CPToolbarItemTagKey];
[aCoder encodeObject:[self target] forKey:CPToolbarItemTargetKey];
[aCoder encodeObject:[self action] forKey:CPToolbarItemActionKey];
[aCoder encodeObject:[self isEnabled] forKey:CPToolbarItemEnabledKey];
[aCoder encodeObject:[self image] forKey:CPToolbarItemImageKey];
[aCoder encodeObject:[self alternateImage] forKey:CPToolbarItemAlternateImageKey];
[aCoder encodeObject:[self view] forKey:CPToolbarItemViewKey];
[aCoder encodeSize:[self minSize] forKey:CPToolbarItemMinSizeKey];
[aCoder encodeSize:[self maxSize] forKey:CPToolbarItemMaxSizeKey];
[aCoder encodeObject:[self visibilityPriority] forKey:CPToolbarItemVisibilityPriorityKey];
[aCoder encodeBool:[self autovalidates] forKey:CPToolbarItemAutovalidatesKey];
}
@end
@implementation CPToolbarItem (CPCopying)
- (id)copy
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy _setToolbar:_toolbar];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:[self image]];
[copy setAlternateImage:[self alternateImage]];
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
[copy setVisibilityPriority:[self visibilityPriority]];
[copy setAutovalidates:[self autovalidates]];
return copy;
}
@end
// Standard toolbar identifiers
@implementation CPToolbarItem (Standard)
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: return [_CPToolbarSeparatorItem new];
case CPToolbarSpaceItemIdentifier: return [_CPToolbarSpaceItem new];
case CPToolbarFlexibleSpaceItemIdentifier: return [_CPToolbarFlexibleSpaceItem new];
case CPToolbarShowColorsItemIdentifier: return [_CPToolbarShowColorsItem new];
case CPToolbarShowFontsItemIdentifier: return nil;
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
case CPToolbarPrintItemIdentifier: return nil;
}
return nil;
}
@end
/*@import "_CPToolbarFlexibleSpaceItem.j"
@import "_CPToolbarShowColorsItem.j"
@import "_CPToolbarSeparatorItem.j"
@import "_CPToolbarSpaceItem.j"
*/
+1 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPToolbarItem.j"
@import "_CPToolbarItem.j"
@implementation _CPToolbarSeparatorItem : CPToolbarItem
+1 -1
View File
@@ -21,7 +21,7 @@
*/
@import "CPApplication.j"
@import "CPToolbarItem.j"
@import "_CPToolbarItem.j"
@implementation _CPToolbarShowColorsItem : CPToolbarItem
+1 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPToolbarItem.j"
@import "_CPToolbarItem.j"
@implementation _CPToolbarSpaceItem : CPToolbarItem
+2 -2
View File
@@ -347,7 +347,7 @@
while ((index = [self indexOfObject:theObject inRange:theRange]) !== CPNotFound)
{
[self removeObjectAtIndex:index];
theRange = CPIntersectionRange(CPMakeRange(index, length - index), theRange);
theRange = CPIntersectionRange(CPMakeRange(index, self.length - index), theRange);
}
}
}
@@ -427,7 +427,7 @@
[CPException raise:CPInvalidArgumentException reason:"called valueForKey: on an array with a complex key (" + aKey + "). use valueForKeyPath:"];
if (aKey === "@count")
return length;
return self.length;
return [self valueForUndefinedKey:aKey];
}
Executable → Regular
+1 -995
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,5 +1,5 @@
@import "CPArray.j"
@import "_CPArray.j"
/*!
@@ -217,7 +217,7 @@
*/
- (void)removeObject:(id)anObject
{
[self removeObject:anObject inRange:CPMakeRange(0, length)];
[self removeObject:anObject inRange:CPMakeRange(0, self.length)];
}
/*!
@@ -232,7 +232,7 @@
while ((index = [self indexOfObject:anObject inRange:aRange]) != CPNotFound)
{
[self removeObjectAtIndex:index];
aRange = CPIntersectionRange(CPMakeRange(index, length - index), aRange);
aRange = CPIntersectionRange(CPMakeRange(index, self.length - index), aRange);
}
}
+1018
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -21,7 +21,7 @@
*/
@import "CPObject.j"
@import "CPSet.j"
@import "_CPConcreteMutableSet.j"
/*!
@class CPCountedSet
+3 -3
View File
@@ -22,9 +22,9 @@
#import "Ref.h"
@import <Foundation/CPDate.j>
@import <Foundation/CPString.j>
@import <Foundation/CPFormatter.j>
@import "CPDate.j"
@import "CPString.j"
@import "CPFormatter.j"
CPDateFormatterNoStyle = 0;
CPDateFormatterShortStyle = 1;
+30 -23
View File
@@ -322,7 +322,7 @@
*/
- (int)count
{
return _count;
return self._count;
}
/*!
@@ -330,7 +330,7 @@
*/
- (CPArray)allKeys
{
return [_keys copy];
return [self._keys copy];
}
/*!
@@ -338,11 +338,12 @@
*/
- (CPArray)allValues
{
var index = _keys.length,
var keys = self._keys,
index = keys.length,
values = [];
while (index--)
values.push(self.valueForKey(_keys[index]));
values.push(self.valueForKey(keys[index]));
return values;
}
@@ -357,7 +358,8 @@
*/
- (CPArray)allKeysForObject:(id)anObject
{
var count = _keys.length,
var keys = self._keys,
count = keys.length,
index = 0,
matchingKeys = [],
key = nil,
@@ -365,8 +367,8 @@
for (; index < count; ++index)
{
key = _keys[index];
value = _buckets[key];
key = keys[index];
value = self._buckets[key];
if (value.isa && anObject && anObject.isa && [value respondsToSelector:@selector(isEqual:)] && [value isEqual:anObject])
matchingKeys.push(key);
@@ -384,16 +386,18 @@
- (CPArray)keysOfEntriesWithOptions:(CPEnumerationOptions)options passingTest:(Function /*(id key, id obj, @ref BOOL stop)*/)predicate
{
var keys = self._keys;
if (options & CPEnumerationReverse)
{
var index = [_keys count] - 1,
var index = [keys count] - 1,
stop = -1,
increment = -1;
}
else
{
var index = 0,
stop = [_keys count],
stop = [keys count],
increment = 1;
}
@@ -405,8 +409,8 @@
for (; index !== stop; index += increment)
{
key = _keys[index];
value = _buckets[key];
key = keys[index];
value = self._buckets[key];
if (predicate(key, value, stopRef))
matchingKeys.push(key);
@@ -447,7 +451,7 @@
*/
- (CPEnumerator)keyEnumerator
{
return [_keys objectEnumerator];
return [self._keys objectEnumerator];
}
/*!
@@ -471,12 +475,13 @@
if (count !== [aDictionary count])
return NO;
var index = count;
var index = count,
keys = self._keys;
while (index--)
{
var currentKey = _keys[index],
lhsObject = _buckets[currentKey],
var currentKey = keys[index],
lhsObject = self._buckets[currentKey],
rhsObject = aDictionary._buckets[currentKey];
if (lhsObject === rhsObject)
@@ -532,7 +537,7 @@
*/
- (id)objectForKey:(id)aKey
{
var object = _buckets[aKey];
var object = self._buckets[aKey];
return (object === undefined) ? nil : object;
}
@@ -634,14 +639,14 @@
- (CPString)description
{
var string = "@{\n",
keys = _keys,
keys = self._keys,
index = 0,
count = _count;
count = self._count;
for (; index < count; ++index)
{
var key = keys[index],
value = valueForKey(key);
value = self.valueForKey(key);
string += "\t" + key + ": " + CPDescriptionOfObject(value).split('\n').join("\n\t") + ",\n";
}
@@ -658,12 +663,14 @@
- (void)enumerateKeysAndObjectsUsingBlock:(Function /*(id aKey, id anObject, @ref BOOL stop)*/)aFunction
{
var shouldStop = NO,
shouldStopRef = AT_REF(shouldStop);
shouldStopRef = AT_REF(shouldStop),
keys = self._keys,
count = self._count;
for (var index = 0; index < _count; index++)
for (var index = 0; index < count; index++)
{
var key = _keys[index],
value = valueForKey(key);
var key = keys[index],
value = self.valueForKey(key);
aFunction(key, value, shouldStopRef);
+2
View File
@@ -46,6 +46,8 @@ if (input == nil)
@implementation CPException : CPObject
{
id _userInfo;
CPString name;
CPString message;
}
/*
+1
View File
@@ -1 +1,2 @@
// placeholder. moved to Objective-J/CPLog.js
1; // Dummy row! To fool when reading from gcc who removes all comments and whitespaces and makes this file empty. Empty file == no file -> Error
+2 -2
View File
@@ -223,7 +223,7 @@ FIXME: Do we need this?
- (CPString)descriptionWithLocale:(CPDictionary)aDictionary
{
if (!aDictionary)
return toString();
return self.toString();
throw new Error("descriptionWithLocale: NOT YET IMPLEMENTED");
}
@@ -277,7 +277,7 @@ FIXME: Do we need this?
- (CPString)stringValue
{
return toString();
return self.toString();
}
- (unsigned char)unsignedCharValue
+3 -3
View File
@@ -22,9 +22,9 @@
#import "Ref.h"
@import <Foundation/CPString.j>
@import <Foundation/CPFormatter.j>
@import <Foundation/CPDecimalNumber.j>
@import "CPString.j"
@import "CPFormatter.j"
@import "CPDecimalNumber.j"
#define UPDATE_NUMBER_HANDLER_IF_NECESSARY() if (!_numberHandler) \
_numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:_roundingMode scale:_maximumFractionDigits raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
+3 -3
View File
@@ -154,7 +154,7 @@ CPLog(@"Got some class: %@", inst);
*/
+ (Class)superclass
{
return super_class;
return self.super_class;
}
/*!
@@ -292,7 +292,7 @@ CPLog(@"Got some class: %@", inst);
+ (CPString)description
{
return class_getName(isa);
return class_getName(self.isa);
}
// Sending Messages
@@ -484,7 +484,7 @@ CPLog(@"Got some class: %@", inst);
if (typeof self._UID === "undefined")
self._UID = objj_generateObjectUID();
return _UID + "";
return self._UID + "";
}
/*!
+1 -368
View File
@@ -19,374 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPDictionary.j"
@import "CPKeyValueCoding.j"
@import "CPObject.j"
@import "CPString.j"
/*!
An expression that always returns the same value.
*/
CPConstantValueExpressionType = 0;
/*!
An expression that always returns the parameter object itself.
*/
CPEvaluatedObjectExpressionType = 1;
/*!
An expression that always returns whatever value is associated with the key specified by variable in the bindings dictionary.
*/
CPVariableExpressionType = 2;
/*!
An expression that returns something that can be used as a key path.
*/
CPKeyPathExpressionType = 3;
/*!
An expression that returns the result of evaluating a function.
*/
CPFunctionExpressionType = 4;
/*!
An expression that defines an aggregate of CPExpression objects.
*/
CPAggregateExpressionType = 5;
/*!
An expression that filters a collection using a subpredicate.
*/
CPSubqueryExpressionType = 6;
/*!
An expression that creates a union of the results of two nested expressions.
*/
CPUnionSetExpressionType = 7;
/*!
An expression that creates an intersection of the results of two nested expressions.
*/
CPIntersectSetExpressionType = 8;
/*!
An expression that combines two nested expression results by set subtraction.
*/
CPMinusSetExpressionType = 9;
/*!
@ingroup foundation
@class CPExpression
@brief CPExpression is used to represent expressions in a predicate.
Comparison operations in an CPPredicate are based on two expressions, as represented by instances of the CPExpression class.
Expressions are created for constant values, key paths, and so on.
Generally, anywhere in the CPExpression class hierarchy where there is composite API and subtypes
that may only reasonably respond to a subset of that API, invoking a method that does not make sense
for that subtype will cause an exception to be thrown.
*/
@implementation CPExpression : CPObject
{
int _type;
}
// Initializing an Expression
/*!
Initializes the receiver with the specified expression type.
@param type The type of the new expression, as defined by CPExpressionType.
@return An initialized CPExpression object of the type type.
*/
- (id)initWithExpressionType:(int)type
{
_type = type;
return self;
}
//Creating an Expression for a Value
/*!
Returns a new expression that represents a given constant value.
@param value The constant value the new expression is to represent.
@return A new expression that represents the constant value.
*/
+ (CPExpression)expressionForConstantValue:(id)value
{
return [[_CPConstantValueExpression alloc] initWithValue:value];
}
/*!
Returns a new expression that represents the object being evaluated.
@return A new expression that represents the object being evaluated.
*/
+ (CPExpression)expressionForEvaluatedObject
{
return [_CPSelfExpression evaluatedObject];
}
/*!
Returns a new expression that extracts a value from the variable bindings dictionary for a given key.
@param string The key for the variable to extract from the variable bindings dictionary.
@return A new expression that extracts from the variable bindings dictionary the value for the key string.
*/
+ (CPExpression)expressionForVariable:(CPString)string
{
return [[_CPVariableExpression alloc] initWithVariable:string];
}
/*!
Returns a new expression that invokes valueForKeyPath: with a given key path.
@param keyPath The key path that the new expression should evaluate.
@return A new expression that invokes valueForKeyPath: with keyPath.
*/
+ (CPExpression)expressionForKeyPath:(CPString)keyPath
{
return [[_CPKeyPathExpression alloc] initWithKeyPath:keyPath];
}
/*!
Returns a new aggregate expression for a given collection.
@param collection A collection object (an instance of CPArray, CPSet, or CPDictionary) that contains further expressions.
@return A new expression that contains the expressions in collection.
*/
+ (CPExpression)expressionForAggregate:(CPArray)collection
{
return [[_CPAggregateExpression alloc] initWithAggregate:collection];
}
/*!
Returns a new CPExpression object that represent the union of a given set and collection.
@param left An expression that evaluates to a CPSet object.
@param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the union of left and right.
*/
+ (CPExpression)expressionForUnionSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPUnionSetExpressionType left:left right:right];
}
/*!
Returns a new CPExpression object that represent the intersection of a given set and collection.
@param left An expression that evaluates to a CPSet object.
@param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the intersection of left and right.
*/
+ (CPExpression)expressionForIntersectSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPIntersectSetExpressionType left:left right:right];
}
/*!
Returns a new CPExpression object that represent the subtraction of a given collection from a given set.
@param left An expression that evaluates to a CPSet object.
@param left An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the subtraction of right from left.
*/
+ (CPExpression)expressionForMinusSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPMinusSetExpressionType left:left right:right];
}
// Creating an Expression for a Function
/*!
Returns a new expression that will invoke one of the predefined functions.
@param function_name The name of the function to invoke.
@param parameters An array containing CPExpression objects that will be used as parameters during the invocation of selector.
@return A new expression that invokes the function name using the parameters in parameters.
For a selector taking no parameters, the array should be empty. For a selector taking one or more parameters,
the array should contain one CPExpression object which will evaluate to an instance of the appropriate type for each parameter.
If there is a mismatch between the number of parameters expected and the number you provide during evaluation,
an exception may be raised or missing parameters may simply be replaced by nil (which occurs depends on how many
parameters are provided, and whether you have over- or underflow).
The name parameter can be one of the following predefined functions:
@verbatim
name parameter array contents returns
-------------------------------------------------------------------------------------------------------------------------------------
sum: CPExpression instances representing numbers CPNumber
count: CPExpression instances representing numbers CPNumber
min: CPExpression instances representing numbers CPNumber
max: CPExpression instances representing numbers CPNumber
average: CPExpression instances representing numbers CPNumber
median: CPExpression instances representing numbers CPNumber
mode: CPExpression instances representing numbers CPArray (returned array will contain all occurrences of the mode)
stddev: CPExpression instances representing numbers CPNumber
add:to: CPExpression instances representing numbers CPNumber
from:subtract: two CPExpression instances representing numbers CPNumber
multiply:by: two CPExpression instances representing numbers CPNumber
divide:by: two CPExpression instances representing numbers CPNumber
modulus:by: two CPExpression instances representing numbers CPNumber
sqrt: one CPExpression instance representing numbers CPNumber
log: one CPExpression instance representing a number CPNumber
ln: one CPExpression instance representing a number CPNumber
raise:toPower: one CPExpression instance representing a number CPNumber
exp: one CPExpression instance representing a number CPNumber
floor: one CPExpression instance representing a number CPNumber
ceiling: one CPExpression instance representing a number CPNumber
abs: one CPExpression instance representing a number CPNumber
trunc: one CPExpression instance representing a number CPNumber
uppercase: one CPExpression instance representing a string CPString
lowercase: one CPExpression instance representing a string CPString
random: one CPExpression instance representing a number CPNumber (integer) such that 0 <= rand < param
now: none [CPDate now]
This method raises an exception immediately if the selector is invalid; it raises an exception at runtime if the parameters are incorrect.
@endverbatim
*/
+ (CPExpression)expressionForFunction:(CPString)function_name arguments:(CPArray)parameters
{
return [[_CPFunctionExpression alloc] initWithSelector:CPSelectorFromString(function_name) arguments:parameters];
}
/*!
Returns an expression which will return the result of invoking on a given target a selector with a given name using given arguments.
@param target A CPExpression object which will evaluate an object on which the selector identified by name may be invoked.
@param selectorName The name of the method to be invoked.
@param parameters An array containing CPExpression objects which can be evaluated to provide parameters for the method specified by name.
@return An expression which will return the result of invoking the selector named name on the result of evaluating the target expression with the parameters specified by evaluating the elements of parameters.
See the description of \c expressionForFunction:arguments: for examples of how to construct the parameter array.
*/
+ (CPExpression)expressionForFunction:(CPExpression)target selectorName:(CPString)selectorName arguments:(CPArray)parameters
{
return [[_CPFunctionExpression alloc] initWithTarget:target selector:CPSelectorFromString(selectorName) arguments:parameters];
}
/*!
Returns an expression that filters a collection by storing elements in the collection in a given variable and keeping the elements for which qualifier returns true.
@param expression A CPExpression that evaluates to a collection.
@param variable Used as a local variable, and will shadow any instances of variable in the bindings dictionary. The variable is removed or the old value replaced once evaluation completes.
@param predicate The predicate used to determine whether the element belongs in the result collection.
@return An expression that filters a collection by storing elements in the collection in the variable variable and keeping the elements for which qualifier returns true.
*/
+ (CPExpression)expressionForSubquery:(CPExpression)expression usingIteratorVariable:(CPString)variable predicate:(CPPredicate)predicate
{
return [[_CPSubqueryExpression alloc] initWithExpression:expression usingIteratorVariable:variable predicate:predicate];
}
// Getting Information About an Expression
/*!
Returns the expression type for the receiver.
@return The expression type for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (int)expressionType
{
return _type;
}
/*!
Returns the constant value of the receiver.
@return The constant value of the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (id)constantValue
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the variable for the receiver.
@return The variable for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)variable
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the key path for the receiver.
@return The key path for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)keyPath
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the function for the receiver.
@return The function for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)function
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the arguments for the receiver.
@return The arguments for the receiver—that is, the array of expressions that will be passed as parameters during invocation of the selector on the operand of a function expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPArray)arguments
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the collection of expressions in an aggregate expression, or the collection element of a subquery expression.
@return The collection of expressions in an aggregate expression, or the collection element of a subquery expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (id)collection
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the predicate in a subquery expression.
@return The predicate in a subquery expression..
This method raises an exception if it is not applicable to the receiver.
*/
- (CPPredicate)predicate
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the operand for the receiver.
@return The operand for the receiver—that is, the object on which the selector will be invoked.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)operand
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the left expression of a set expression.
@return The left expression of a set expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)leftExpression
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the right expression of a set expression.
@return The right expression of a set expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)rightExpression
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
- (CPExpression)_expressionWithSubstitutionVariables:(CPDictionary)variables
{
return self;
}
@end
@import "_CPExpression.j"
@import "_CPConstantValueExpression.j"
@import "_CPSelfExpression.j"
@import "_CPVariableExpression.j"
+4 -4
View File
@@ -225,7 +225,7 @@
while (count--)
{
if (![predicate evaluateWithObject:[self objectAtIndex:count]])
splice(count, 1);
self.splice(count, 1);
}
}
@@ -970,6 +970,6 @@ var CPRaiseParseError = function CPRaiseParseError(aScanner, target)
[CPException raise:CPInvalidArgumentException reason:@"unable to parse " + target + " at index " + [aScanner scanLocation]];
};
@import "CPCompoundPredicate.j"
@import "CPComparisonPredicate.j"
@import "CPExpression.j"
//@import "CPCompoundPredicate.j"
//@import "CPComparisonPredicate.j"
//@import "CPExpression.j"
+397
View File
@@ -0,0 +1,397 @@
/*
* CPExpression.j
*
* Created by cacaodev.
* Copyright 2010.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPDictionary.j"
@import "CPKeyValueCoding.j"
@import "CPObject.j"
@import "CPString.j"
/*!
An expression that always returns the same value.
*/
CPConstantValueExpressionType = 0;
/*!
An expression that always returns the parameter object itself.
*/
CPEvaluatedObjectExpressionType = 1;
/*!
An expression that always returns whatever value is associated with the key specified by variable in the bindings dictionary.
*/
CPVariableExpressionType = 2;
/*!
An expression that returns something that can be used as a key path.
*/
CPKeyPathExpressionType = 3;
/*!
An expression that returns the result of evaluating a function.
*/
CPFunctionExpressionType = 4;
/*!
An expression that defines an aggregate of CPExpression objects.
*/
CPAggregateExpressionType = 5;
/*!
An expression that filters a collection using a subpredicate.
*/
CPSubqueryExpressionType = 6;
/*!
An expression that creates a union of the results of two nested expressions.
*/
CPUnionSetExpressionType = 7;
/*!
An expression that creates an intersection of the results of two nested expressions.
*/
CPIntersectSetExpressionType = 8;
/*!
An expression that combines two nested expression results by set subtraction.
*/
CPMinusSetExpressionType = 9;
/*!
@ingroup foundation
@class CPExpression
@brief CPExpression is used to represent expressions in a predicate.
Comparison operations in an CPPredicate are based on two expressions, as represented by instances of the CPExpression class.
Expressions are created for constant values, key paths, and so on.
Generally, anywhere in the CPExpression class hierarchy where there is composite API and subtypes
that may only reasonably respond to a subset of that API, invoking a method that does not make sense
for that subtype will cause an exception to be thrown.
*/
@implementation CPExpression : CPObject
{
int _type;
}
// Initializing an Expression
/*!
Initializes the receiver with the specified expression type.
@param type The type of the new expression, as defined by CPExpressionType.
@return An initialized CPExpression object of the type type.
*/
- (id)initWithExpressionType:(int)type
{
_type = type;
return self;
}
//Creating an Expression for a Value
/*!
Returns a new expression that represents a given constant value.
@param value The constant value the new expression is to represent.
@return A new expression that represents the constant value.
*/
+ (CPExpression)expressionForConstantValue:(id)value
{
return [[_CPConstantValueExpression alloc] initWithValue:value];
}
/*!
Returns a new expression that represents the object being evaluated.
@return A new expression that represents the object being evaluated.
*/
+ (CPExpression)expressionForEvaluatedObject
{
return [_CPSelfExpression evaluatedObject];
}
/*!
Returns a new expression that extracts a value from the variable bindings dictionary for a given key.
@param string The key for the variable to extract from the variable bindings dictionary.
@return A new expression that extracts from the variable bindings dictionary the value for the key string.
*/
+ (CPExpression)expressionForVariable:(CPString)string
{
return [[_CPVariableExpression alloc] initWithVariable:string];
}
/*!
Returns a new expression that invokes valueForKeyPath: with a given key path.
@param keyPath The key path that the new expression should evaluate.
@return A new expression that invokes valueForKeyPath: with keyPath.
*/
+ (CPExpression)expressionForKeyPath:(CPString)keyPath
{
return [[_CPKeyPathExpression alloc] initWithKeyPath:keyPath];
}
/*!
Returns a new aggregate expression for a given collection.
@param collection A collection object (an instance of CPArray, CPSet, or CPDictionary) that contains further expressions.
@return A new expression that contains the expressions in collection.
*/
+ (CPExpression)expressionForAggregate:(CPArray)collection
{
return [[_CPAggregateExpression alloc] initWithAggregate:collection];
}
/*!
Returns a new CPExpression object that represent the union of a given set and collection.
@param left An expression that evaluates to a CPSet object.
@param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the union of left and right.
*/
+ (CPExpression)expressionForUnionSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPUnionSetExpressionType left:left right:right];
}
/*!
Returns a new CPExpression object that represent the intersection of a given set and collection.
@param left An expression that evaluates to a CPSet object.
@param right An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the intersection of left and right.
*/
+ (CPExpression)expressionForIntersectSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPIntersectSetExpressionType left:left right:right];
}
/*!
Returns a new CPExpression object that represent the subtraction of a given collection from a given set.
@param left An expression that evaluates to a CPSet object.
@param left An expression that evaluates to a collection object (an instance of CPArray, CPSet, or CPDictionary).
@return A new CPExpression object that represents the subtraction of right from left.
*/
+ (CPExpression)expressionForMinusSet:(CPExpression)left with:(CPExpression)right
{
return [[_CPSetExpression alloc] initWithType:CPMinusSetExpressionType left:left right:right];
}
// Creating an Expression for a Function
/*!
Returns a new expression that will invoke one of the predefined functions.
@param function_name The name of the function to invoke.
@param parameters An array containing CPExpression objects that will be used as parameters during the invocation of selector.
@return A new expression that invokes the function name using the parameters in parameters.
For a selector taking no parameters, the array should be empty. For a selector taking one or more parameters,
the array should contain one CPExpression object which will evaluate to an instance of the appropriate type for each parameter.
If there is a mismatch between the number of parameters expected and the number you provide during evaluation,
an exception may be raised or missing parameters may simply be replaced by nil (which occurs depends on how many
parameters are provided, and whether you have over- or underflow).
The name parameter can be one of the following predefined functions:
@verbatim
name parameter array contents returns
-------------------------------------------------------------------------------------------------------------------------------------
sum: CPExpression instances representing numbers CPNumber
count: CPExpression instances representing numbers CPNumber
min: CPExpression instances representing numbers CPNumber
max: CPExpression instances representing numbers CPNumber
average: CPExpression instances representing numbers CPNumber
median: CPExpression instances representing numbers CPNumber
mode: CPExpression instances representing numbers CPArray (returned array will contain all occurrences of the mode)
stddev: CPExpression instances representing numbers CPNumber
add:to: CPExpression instances representing numbers CPNumber
from:subtract: two CPExpression instances representing numbers CPNumber
multiply:by: two CPExpression instances representing numbers CPNumber
divide:by: two CPExpression instances representing numbers CPNumber
modulus:by: two CPExpression instances representing numbers CPNumber
sqrt: one CPExpression instance representing numbers CPNumber
log: one CPExpression instance representing a number CPNumber
ln: one CPExpression instance representing a number CPNumber
raise:toPower: one CPExpression instance representing a number CPNumber
exp: one CPExpression instance representing a number CPNumber
floor: one CPExpression instance representing a number CPNumber
ceiling: one CPExpression instance representing a number CPNumber
abs: one CPExpression instance representing a number CPNumber
trunc: one CPExpression instance representing a number CPNumber
uppercase: one CPExpression instance representing a string CPString
lowercase: one CPExpression instance representing a string CPString
random: one CPExpression instance representing a number CPNumber (integer) such that 0 <= rand < param
now: none [CPDate now]
This method raises an exception immediately if the selector is invalid; it raises an exception at runtime if the parameters are incorrect.
@endverbatim
*/
+ (CPExpression)expressionForFunction:(CPString)function_name arguments:(CPArray)parameters
{
return [[_CPFunctionExpression alloc] initWithSelector:CPSelectorFromString(function_name) arguments:parameters];
}
/*!
Returns an expression which will return the result of invoking on a given target a selector with a given name using given arguments.
@param target A CPExpression object which will evaluate an object on which the selector identified by name may be invoked.
@param selectorName The name of the method to be invoked.
@param parameters An array containing CPExpression objects which can be evaluated to provide parameters for the method specified by name.
@return An expression which will return the result of invoking the selector named name on the result of evaluating the target expression with the parameters specified by evaluating the elements of parameters.
See the description of \c expressionForFunction:arguments: for examples of how to construct the parameter array.
*/
+ (CPExpression)expressionForFunction:(CPExpression)target selectorName:(CPString)selectorName arguments:(CPArray)parameters
{
return [[_CPFunctionExpression alloc] initWithTarget:target selector:CPSelectorFromString(selectorName) arguments:parameters];
}
/*!
Returns an expression that filters a collection by storing elements in the collection in a given variable and keeping the elements for which qualifier returns true.
@param expression A CPExpression that evaluates to a collection.
@param variable Used as a local variable, and will shadow any instances of variable in the bindings dictionary. The variable is removed or the old value replaced once evaluation completes.
@param predicate The predicate used to determine whether the element belongs in the result collection.
@return An expression that filters a collection by storing elements in the collection in the variable variable and keeping the elements for which qualifier returns true.
*/
+ (CPExpression)expressionForSubquery:(CPExpression)expression usingIteratorVariable:(CPString)variable predicate:(CPPredicate)predicate
{
return [[_CPSubqueryExpression alloc] initWithExpression:expression usingIteratorVariable:variable predicate:predicate];
}
// Getting Information About an Expression
/*!
Returns the expression type for the receiver.
@return The expression type for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (int)expressionType
{
return _type;
}
/*!
Returns the constant value of the receiver.
@return The constant value of the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (id)constantValue
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the variable for the receiver.
@return The variable for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)variable
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the key path for the receiver.
@return The key path for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)keyPath
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the function for the receiver.
@return The function for the receiver.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPString)function
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the arguments for the receiver.
@return The arguments for the receiver—that is, the array of expressions that will be passed as parameters during invocation of the selector on the operand of a function expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPArray)arguments
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the collection of expressions in an aggregate expression, or the collection element of a subquery expression.
@return The collection of expressions in an aggregate expression, or the collection element of a subquery expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (id)collection
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the predicate in a subquery expression.
@return The predicate in a subquery expression..
This method raises an exception if it is not applicable to the receiver.
*/
- (CPPredicate)predicate
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the operand for the receiver.
@return The operand for the receiver—that is, the object on which the selector will be invoked.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)operand
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the left expression of a set expression.
@return The left expression of a set expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)leftExpression
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
/*!
Returns the right expression of a set expression.
@return The right expression of a set expression.
This method raises an exception if it is not applicable to the receiver.
*/
- (CPExpression)rightExpression
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
- (CPExpression)_expressionWithSubstitutionVariables:(CPDictionary)variables
{
return self;
}
@end
//@import "_CPConstantValueExpression.j"
//@import "_CPSelfExpression.j"
//@import "_CPVariableExpression.j"
//@import "_CPKeyPathExpression.j"
//@import "_CPFunctionExpression.j"
//@import "_CPAggregateExpression.j"
//@import "_CPSetExpression.j"
//@import "_CPSubqueryExpression.j"
@@ -26,6 +26,7 @@
@import "_CPFunctionExpression.j"
@import "CPKeyValueCoding.j"
@import "CPString.j"
@import "_CPConstantValueExpression.j"
@implementation _CPKeyPathExpression : _CPFunctionExpression
{
+2 -1
View File
@@ -27,6 +27,7 @@
@implementation CPProxy
{
Class isa;
}
+ (void)load
@@ -80,7 +81,7 @@
if (typeof self._UID === "undefined")
self._UID = objj_generateObjectUID();
return _UID;
return self._UID;
}
- (BOOL)isEqual:(id)anObject
+1 -1
View File
@@ -22,7 +22,7 @@
@import "CPException.j"
@import "CPObject.j"
@import "CPSet.j"
@import "CPMutableSet.j"
@import "_CPCollectionKVCOperators.j"
@implementation CPObject (CPSetKVO)
+2 -2
View File
@@ -7,7 +7,7 @@
this class only exists for source compatability.
*/
@import "CPSet.j"
@import "_CPSet.j"
@implementation CPMutableSet : CPSet
@@ -146,4 +146,4 @@
@end
@import "_CPConcreteMutableSet.j"
//@import "_CPConcreteMutableSet.j"
+1 -488
View File
@@ -24,491 +24,4 @@
*
*/
@import "CPArray.j"
@import "CPEnumerator.j"
@import "CPNumber.j"
@import "CPObject.j"
/*!
@class CPMutableSet
@ingroup Foundation
CPSet is a data structure for storing an an unordered collection of unique objects.
Sets have O(1) insertion/lookup/deletion time complexity.
*/
@implementation CPSet : CPObject
{
}
+ (id)alloc
{
if (self === [CPSet class] || self === [CPMutableSet class])
return [_CPPlaceholderSet alloc];
return [super alloc];
}
/*!
Creates and returns an empty set.
*/
+ (id)set
{
return [[self alloc] init];
}
/*!
Creates and returns a set containing a uniqued collection of those objects contained in a given array.
@param anArray array containing the objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
*/
+ (id)setWithArray:(CPArray)anArray
{
return [[self alloc] initWithArray:anArray];
}
/*!
Creates and returns a set that contains a single given object.
@param anObject The object to add to the new set.
*/
+ (id)setWithObject:(id)anObject
{
return [[self alloc] initWithObjects:anObject];
}
/*!
Creates and returns a set containing a specified number of objects from a given array of objects.
@param objects A array of objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
@param count The number of objects from objects to add to the new set.
*/
+ (id)setWithObjects:(id)objects count:(CPUInteger)count
{
return [[self alloc] initWithObjects:objects count:count];
}
/*!
Creates and returns a set containing the objects in a given argument list.
@param anObject The first object to add to the new set.
@param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
*/
+ (id)setWithObjects:(id)anObject, ...
{
var argumentsArray = Array.prototype.slice.apply(arguments);
argumentsArray[0] = [self alloc];
argumentsArray[1] = @selector(initWithObjects:);
return objj_msgSend.apply(this, argumentsArray);
}
/*!
Creates and returns a set containing the objects from another set.
@param aSet A set containing the objects to add to the new set.
*/
+ (id)setWithSet:(CPSet)set
{
return [[self alloc] initWithSet:set];
}
/*!
Creates and returns a set by adding anObject.
@param anObject to add to the new set.
*/
- (id)setByAddingObject:(id)anObject
{
return [[self class] setWithArray:[[self allObjects] arrayByAddingObject:anObject]];
}
/*!
Creates and returns a set by adding the objects from another set.
@param aSet to add objects to add to the new set.
*/
- (id)setByAddingObjectsFromSet:(CPSet)aSet
{
return [self setByAddingObjectsFromArray:[aSet allObjects]];
}
/*!
Creates and returns a set by adding the objects from an array.
@param anArray with objects to add to a new set.
*/
- (id)setByAddingObjectsFromArray:(CPArray)anArray
{
return [[self class] setWithArray:[[self allObjects] arrayByAddingObjectsFromArray:anArray]];
}
/*!
Basic initializer, returns an empty set.
*/
- (id)init
{
return [self initWithObjects:nil count:0];
}
/*!
Initializes a newly allocated set with the objects that are contained in a given array.
@param array An array of objects to add to the new set. If the same object appears more than once in array, it is represented only once in the returned set.
*/
- (id)initWithArray:(CPArray)anArray
{
return [self initWithObjects:anArray count:[anArray count]];
}
/*!
Initializes a newly allocated set with members taken from the specified list of objects.
@param anObject The first object to add to the new set.
@param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once in the list, it is represented only once in the returned set.
*/
- (id)initWithObjects:(id)anObject, ...
{
var index = 2,
count = arguments.length;
for (; index < count; ++index)
if (arguments[index] === nil)
break;
return [self initWithObjects:Array.prototype.slice.call(arguments, 2, index) count:index - 2];
}
/*!
Creates and returns a set containing the objects from an array.
@param anArray An array containing the objects to add to the new set.
@param aCount the number of objects in anArray.
*/
- (id)initWithObjects:(CPArray)objects count:(CPUInteger)aCount
{
if (self === _CPSharedPlaceholderSet)
return [[_CPConcreteMutableSet alloc] initWithObjects:objects count:aCount];
return [super init];
}
/*!
Initializes a newly allocated set and adds to it objects from another given set.
@param aSet a set containing objects to add to the new set.
*/
- (id)initWithSet:(CPSet)aSet
{
return [self initWithArray:[aSet allObjects]];
}
/*!
Initializes a newly allocated set and adds to it members of another given set. Only included for compatability.
@param aSet a set of objects to add to the new set.
@param shouldCopyItems a boolean value. If YES the objects would be copied, if NO the objects will not be copied.
*/
- (id)initWithSet:(CPSet)aSet copyItems:(BOOL)shouldCopyItems
{
if (shouldCopyItems)
return [aSet valueForKey:@"copy"];
return [self initWithSet:aSet];
}
/*!
Returns the number of members in the receiver.
*/
- (CPUInteger)count
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns an array containing the receivers members, or an empty array if the receiver has no members.
*/
- (CPArray)allObjects
{
var objects = [],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
objects.push(object);
return objects;
}
/*!
Returns one of the objects in the receiver, or nil if the receiver contains no objects.
*/
- (id)anyObject
{
return [[self objectEnumerator] nextObject];
}
/*!
Returns a Boolean value that indicates whether a given object is present in the receiver.
@param anObject The object for which to test membership of the receiver.
*/
- (BOOL)containsObject:(id)anObject
{
return [self member:anObject] !== nil;
}
/*!
Returns a set filtered using a given predicate.
@prarm aPredicate a CPPredicate object used to filter the objects in the set.
*/
- (CPSet)filteredSetUsingPredicate:(CPPredicate)aPredicate
{
var objects = [],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if ([aPredicate evaluateWithObject:object])
objects.push(object);
return [[[self class] alloc] initWithArray:objects];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the members of the receiver. The method must not take any arguments. It should not have the side effect of modifying the receiver. This value must not be NULL.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector
{
[self makeObjectsPerformSelector:aSelector withObjects:nil];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the receiver's members. The method must take a single argument of type id. The method should not, as a side effect, modify the receiver. The value must not be NULL.
@param anObject The object to pass as an argument to the method specified by aSelector.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject
{
[self makeObjectsPerformSelector:aSelector withObjects:[anObject]];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the receiver's members. The method must take a single argument of type id. The method should not, as a side effect, modify the receiver. The value must not be NULL.
@param objects The objects to pass as an argument to the method specified by aSelector.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector withObjects:(CPArray)objects
{
var object,
objectEnumerator = [self objectEnumerator],
argumentsArray = [nil, aSelector].concat(objects || []);
while ((object = [objectEnumerator nextObject]) !== nil)
{
argumentsArray[0] = object;
objj_msgSend.apply(this, argumentsArray);
}
}
/*!
Determines whether the receiver contains an object equal to a given object, and returns that object if it is present.
@param anObject The object for which to test for membership of the receiver.
*/
- (id)member:(id)anObject
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns an object enumerator (CPEnumerator) for the receiver.
*/
- (CPEnumerator)objectEnumerator
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Enumberates over the objects in a set using a given function.
@param aFunction a callback for each itteration, should be of the format: function(anObject).
*/
- (void)enumerateObjectsUsingBlock:(Function)aFunction
{
var object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (aFunction(object))
break;
}
// FIXME: stop is broken.
- (CPSet)objectsPassingTest:(Function)aFunction
{
var objects = [],
object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (aFunction(object))
objects.push(object);
return [[[self class] alloc] initWithArray:objects];
}
/*!
Returns a Boolean value that indicates whether every object in the receiver is also present in another given set.
@param set The set with which to compare the receiver.
*/
- (BOOL)isSubsetOfSet:(CPSet)aSet
{
var object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (![aSet containsObject:object])
return NO;
return YES;
}
/*!
Returns a Boolean value that indicates whether at least one object in the receiver is also present in another given set.
@param set The set with which to compare the receiver.
*/
- (BOOL)intersectsSet:(CPSet)aSet
{
if (self === aSet)
// The empty set intersects nothing
return [self count] > 0;
var object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if ([aSet containsObject:object])
return YES;
return NO;
}
/*!
Returns an array of the set's content sorted as specified by a given array of sort descriptors.
@param sortDescriptors an array of CPSortDescriptor objects.
*/
- (CPArray)sortedArrayUsingDescriptors:(CPArray)someSortDescriptors
{
return [[self allObjects] sortedArrayUsingDescriptors:someSortDescriptors];
}
/*!
Compares the receiver to another set.
@param set The set with which to compare the receiver.
*/
- (BOOL)isEqualToSet:(CPSet)aSet
{
return [self isEqual:aSet];
}
/*!
Returns YES if BOTH sets are a subset of the other.
@param aSet a set of objects
*/
- (BOOL)isEqual:(CPSet)aSet
{
// If both are subsets of each other, they are equal
return self === aSet ||
[aSet isKindOfClass:[CPSet class]] &&
([self count] === [aSet count] &&
[aSet isSubsetOfSet:self]);
}
- (CPString)description
{
var string = "{(\n",
objects = [self allObjects],
index = 0,
count = [objects count];
for (; index < count; ++index)
{
var object = objects[index];
string += "\t" + String(object).split('\n').join("\n\t") + "\n";
}
return string + ")}";
}
@end
@implementation CPSet (CPCopying)
- (id)copy
{
return [[self class] setWithSet:self];
}
- (id)mutableCopy
{
return [self copy];
}
@end
var CPSetObjectsKey = @"CPSetObjectsKey";
@implementation CPSet (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
return [self initWithArray:[aCoder decodeObjectForKey:CPSetObjectsKey]];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:[self allObjects] forKey:CPSetObjectsKey];
}
@end
@implementation CPSet (CPKeyValueCoding)
- (id)valueForKey:(CPString)aKey
{
if (aKey === "@count")
return [self count];
var valueSet = [CPSet set],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
{
var value = [object valueForKey:aKey];
[valueSet addObject:value];
}
return valueSet;
}
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
var object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
[object setValue:aValue forKey:aKey];
}
@end
var _CPSharedPlaceholderSet = nil;
@implementation _CPPlaceholderSet : CPSet
{
}
+ (id)alloc
{
if (!_CPSharedPlaceholderSet)
_CPSharedPlaceholderSet = [super alloc];
return _CPSharedPlaceholderSet;
}
@end
// We actually want _CPConcreteMutableSet, but this introduces the possibility of an invalid @import loop.
// This will be correctly solved when we move to true immutable/mutable pairs.
@import "CPMutableSet.j"
@import "_CPConcreteMutableSet.j"
+514
View File
@@ -0,0 +1,514 @@
/*
* CPSet.j
* Foundation
*
* Created by Bailey Carlson
* Extended by Ross Boucher
* Extended by Nabil Elisa
* Rewritten by Francisco Tolmasky
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
@import "CPArray.j"
@import "CPEnumerator.j"
@import "CPNumber.j"
@import "CPObject.j"
/*!
@class CPMutableSet
@ingroup Foundation
CPSet is a data structure for storing an an unordered collection of unique objects.
Sets have O(1) insertion/lookup/deletion time complexity.
*/
@implementation CPSet : CPObject
{
}
+ (id)alloc
{
if (self === [CPSet class] || self === [CPMutableSet class])
return [_CPPlaceholderSet alloc];
return [super alloc];
}
/*!
Creates and returns an empty set.
*/
+ (id)set
{
return [[self alloc] init];
}
/*!
Creates and returns a set containing a uniqued collection of those objects contained in a given array.
@param anArray array containing the objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
*/
+ (id)setWithArray:(CPArray)anArray
{
return [[self alloc] initWithArray:anArray];
}
/*!
Creates and returns a set that contains a single given object.
@param anObject The object to add to the new set.
*/
+ (id)setWithObject:(id)anObject
{
return [[self alloc] initWithObjects:anObject];
}
/*!
Creates and returns a set containing a specified number of objects from a given array of objects.
@param objects A array of objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
@param count The number of objects from objects to add to the new set.
*/
+ (id)setWithObjects:(id)objects count:(CPUInteger)count
{
return [[self alloc] initWithObjects:objects count:count];
}
/*!
Creates and returns a set containing the objects in a given argument list.
@param anObject The first object to add to the new set.
@param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
*/
+ (id)setWithObjects:(id)anObject, ...
{
var argumentsArray = Array.prototype.slice.apply(arguments);
argumentsArray[0] = [self alloc];
argumentsArray[1] = @selector(initWithObjects:);
return objj_msgSend.apply(this, argumentsArray);
}
/*!
Creates and returns a set containing the objects from another set.
@param aSet A set containing the objects to add to the new set.
*/
+ (id)setWithSet:(CPSet)set
{
return [[self alloc] initWithSet:set];
}
/*!
Creates and returns a set by adding anObject.
@param anObject to add to the new set.
*/
- (id)setByAddingObject:(id)anObject
{
return [[self class] setWithArray:[[self allObjects] arrayByAddingObject:anObject]];
}
/*!
Creates and returns a set by adding the objects from another set.
@param aSet to add objects to add to the new set.
*/
- (id)setByAddingObjectsFromSet:(CPSet)aSet
{
return [self setByAddingObjectsFromArray:[aSet allObjects]];
}
/*!
Creates and returns a set by adding the objects from an array.
@param anArray with objects to add to a new set.
*/
- (id)setByAddingObjectsFromArray:(CPArray)anArray
{
return [[self class] setWithArray:[[self allObjects] arrayByAddingObjectsFromArray:anArray]];
}
/*!
Basic initializer, returns an empty set.
*/
- (id)init
{
return [self initWithObjects:nil count:0];
}
/*!
Initializes a newly allocated set with the objects that are contained in a given array.
@param array An array of objects to add to the new set. If the same object appears more than once in array, it is represented only once in the returned set.
*/
- (id)initWithArray:(CPArray)anArray
{
return [self initWithObjects:anArray count:[anArray count]];
}
/*!
Initializes a newly allocated set with members taken from the specified list of objects.
@param anObject The first object to add to the new set.
@param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once in the list, it is represented only once in the returned set.
*/
- (id)initWithObjects:(id)anObject, ...
{
var index = 2,
count = arguments.length;
for (; index < count; ++index)
if (arguments[index] === nil)
break;
return [self initWithObjects:Array.prototype.slice.call(arguments, 2, index) count:index - 2];
}
/*!
Creates and returns a set containing the objects from an array.
@param anArray An array containing the objects to add to the new set.
@param aCount the number of objects in anArray.
*/
- (id)initWithObjects:(CPArray)objects count:(CPUInteger)aCount
{
if (self === _CPSharedPlaceholderSet)
return [[_CPConcreteMutableSet alloc] initWithObjects:objects count:aCount];
return [super init];
}
/*!
Initializes a newly allocated set and adds to it objects from another given set.
@param aSet a set containing objects to add to the new set.
*/
- (id)initWithSet:(CPSet)aSet
{
return [self initWithArray:[aSet allObjects]];
}
/*!
Initializes a newly allocated set and adds to it members of another given set. Only included for compatability.
@param aSet a set of objects to add to the new set.
@param shouldCopyItems a boolean value. If YES the objects would be copied, if NO the objects will not be copied.
*/
- (id)initWithSet:(CPSet)aSet copyItems:(BOOL)shouldCopyItems
{
if (shouldCopyItems)
return [aSet valueForKey:@"copy"];
return [self initWithSet:aSet];
}
/*!
Returns the number of members in the receiver.
*/
- (CPUInteger)count
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns an array containing the receivers members, or an empty array if the receiver has no members.
*/
- (CPArray)allObjects
{
var objects = [],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
objects.push(object);
return objects;
}
/*!
Returns one of the objects in the receiver, or nil if the receiver contains no objects.
*/
- (id)anyObject
{
return [[self objectEnumerator] nextObject];
}
/*!
Returns a Boolean value that indicates whether a given object is present in the receiver.
@param anObject The object for which to test membership of the receiver.
*/
- (BOOL)containsObject:(id)anObject
{
return [self member:anObject] !== nil;
}
/*!
Returns a set filtered using a given predicate.
@prarm aPredicate a CPPredicate object used to filter the objects in the set.
*/
- (CPSet)filteredSetUsingPredicate:(CPPredicate)aPredicate
{
var objects = [],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if ([aPredicate evaluateWithObject:object])
objects.push(object);
return [[[self class] alloc] initWithArray:objects];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the members of the receiver. The method must not take any arguments. It should not have the side effect of modifying the receiver. This value must not be NULL.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector
{
[self makeObjectsPerformSelector:aSelector withObjects:nil];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the receiver's members. The method must take a single argument of type id. The method should not, as a side effect, modify the receiver. The value must not be NULL.
@param anObject The object to pass as an argument to the method specified by aSelector.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject
{
[self makeObjectsPerformSelector:aSelector withObjects:[anObject]];
}
/*!
Sends to each object in the receiver a message specified by a given selector.
@param aSelector A selector that specifies the message to send to the receiver's members. The method must take a single argument of type id. The method should not, as a side effect, modify the receiver. The value must not be NULL.
@param objects The objects to pass as an argument to the method specified by aSelector.
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector withObjects:(CPArray)objects
{
var object,
objectEnumerator = [self objectEnumerator],
argumentsArray = [nil, aSelector].concat(objects || []);
while ((object = [objectEnumerator nextObject]) !== nil)
{
argumentsArray[0] = object;
objj_msgSend.apply(this, argumentsArray);
}
}
/*!
Determines whether the receiver contains an object equal to a given object, and returns that object if it is present.
@param anObject The object for which to test for membership of the receiver.
*/
- (id)member:(id)anObject
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns an object enumerator (CPEnumerator) for the receiver.
*/
- (CPEnumerator)objectEnumerator
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Enumberates over the objects in a set using a given function.
@param aFunction a callback for each itteration, should be of the format: function(anObject).
*/
- (void)enumerateObjectsUsingBlock:(Function)aFunction
{
var object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (aFunction(object))
break;
}
// FIXME: stop is broken.
- (CPSet)objectsPassingTest:(Function)aFunction
{
var objects = [],
object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (aFunction(object))
objects.push(object);
return [[[self class] alloc] initWithArray:objects];
}
/*!
Returns a Boolean value that indicates whether every object in the receiver is also present in another given set.
@param set The set with which to compare the receiver.
*/
- (BOOL)isSubsetOfSet:(CPSet)aSet
{
var object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if (![aSet containsObject:object])
return NO;
return YES;
}
/*!
Returns a Boolean value that indicates whether at least one object in the receiver is also present in another given set.
@param set The set with which to compare the receiver.
*/
- (BOOL)intersectsSet:(CPSet)aSet
{
if (self === aSet)
// The empty set intersects nothing
return [self count] > 0;
var object = nil,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
if ([aSet containsObject:object])
return YES;
return NO;
}
/*!
Returns an array of the set's content sorted as specified by a given array of sort descriptors.
@param sortDescriptors an array of CPSortDescriptor objects.
*/
- (CPArray)sortedArrayUsingDescriptors:(CPArray)someSortDescriptors
{
return [[self allObjects] sortedArrayUsingDescriptors:someSortDescriptors];
}
/*!
Compares the receiver to another set.
@param set The set with which to compare the receiver.
*/
- (BOOL)isEqualToSet:(CPSet)aSet
{
return [self isEqual:aSet];
}
/*!
Returns YES if BOTH sets are a subset of the other.
@param aSet a set of objects
*/
- (BOOL)isEqual:(CPSet)aSet
{
// If both are subsets of each other, they are equal
return self === aSet ||
[aSet isKindOfClass:[CPSet class]] &&
([self count] === [aSet count] &&
[aSet isSubsetOfSet:self]);
}
- (CPString)description
{
var string = "{(\n",
objects = [self allObjects],
index = 0,
count = [objects count];
for (; index < count; ++index)
{
var object = objects[index];
string += "\t" + String(object).split('\n').join("\n\t") + "\n";
}
return string + ")}";
}
@end
@implementation CPSet (CPCopying)
- (id)copy
{
return [[self class] setWithSet:self];
}
- (id)mutableCopy
{
return [self copy];
}
@end
var CPSetObjectsKey = @"CPSetObjectsKey";
@implementation CPSet (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
return [self initWithArray:[aCoder decodeObjectForKey:CPSetObjectsKey]];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:[self allObjects] forKey:CPSetObjectsKey];
}
@end
@implementation CPSet (CPKeyValueCoding)
- (id)valueForKey:(CPString)aKey
{
if (aKey === "@count")
return [self count];
var valueSet = [CPSet set],
object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
{
var value = [object valueForKey:aKey];
[valueSet addObject:value];
}
return valueSet;
}
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
var object,
objectEnumerator = [self objectEnumerator];
while ((object = [objectEnumerator nextObject]) !== nil)
[object setValue:aValue forKey:aKey];
}
@end
var _CPSharedPlaceholderSet = nil;
@implementation _CPPlaceholderSet : CPSet
{
}
+ (id)alloc
{
if (!_CPSharedPlaceholderSet)
_CPSharedPlaceholderSet = [super alloc];
return _CPSharedPlaceholderSet;
}
@end
// We actually want _CPConcreteMutableSet, but this introduces the possibility of an invalid @import loop.
// This will be correctly solved when we move to true immutable/mutable pairs.
//@import "CPMutableSet.j"
+27 -27
View File
@@ -194,7 +194,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (int)length
{
return length;
return self.length;
}
/*!
@@ -203,7 +203,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)characterAtIndex:(unsigned)anIndex
{
return charAt(anIndex);
return self.charAt(anIndex);
}
// Combining strings
@@ -246,15 +246,15 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)stringByPaddingToLength:(unsigned)aLength withString:(CPString)aString startingAtIndex:(unsigned)anIndex
{
if (length == aLength)
if (self.length == aLength)
return self;
if (aLength < length)
if (aLength < self.length)
return substr(0, aLength);
var string = self,
substring = aString.substring(anIndex),
difference = aLength - length;
difference = aLength - self.length;
while ((difference -= substring.length) >= 0)
string += substring;
@@ -279,7 +279,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPArray)componentsSeparatedByString:(CPString)aString
{
return split(aString);
return self.split(aString);
}
/*!
@@ -289,7 +289,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)substringFromIndex:(unsigned)anIndex
{
return substr(anIndex);
return self.substr(anIndex);
}
/*!
@@ -299,10 +299,10 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)substringWithRange:(CPRange)aRange
{
if (aRange.location < 0 || _CPMaxRange(aRange) > length)
if (aRange.location < 0 || _CPMaxRange(aRange) > self.length)
[CPException raise:CPRangeException reason:"aRange out of bounds"];
return substr(aRange.location, aRange.length);
return self.substr(aRange.location, aRange.length);
}
/*!
@@ -314,10 +314,10 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)substringToIndex:(unsigned)anIndex
{
if (anIndex > length)
if (anIndex > self.length)
[CPException raise:CPRangeException reason:"index out of bounds"];
return substring(0, anIndex);
return self.substring(0, anIndex);
}
// Finding characters and substrings
@@ -436,9 +436,9 @@ var CPStringUIDs = new CFMutableDictionary(),
- (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement options:(int)options range:(CPRange)searchRange
{
var start = substring(0, searchRange.location),
stringSegmentToSearch = substr(searchRange.location, searchRange.length),
end = substring(searchRange.location + searchRange.length, self.length),
var start = self.substring(0, searchRange.location),
stringSegmentToSearch = self.substr(searchRange.location, searchRange.length),
end = self.substring(searchRange.location + searchRange.length, self.length),
target = [target stringByEscapingRegexControlCharacters],
regExp;
@@ -459,7 +459,7 @@ var CPStringUIDs = new CFMutableDictionary(),
- (CPString)stringByReplacingCharactersInRange:(CPRange)range withString:(CPString)replacement
{
return '' + substring(0, range.location) + replacement + substring(range.location + range.length, self.length);
return '' + self.substring(0, range.location) + replacement + self.substring(range.location + range.length, self.length);
}
/*!
@@ -546,7 +546,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (BOOL)hasPrefix:(CPString)aString
{
return aString && aString != "" && indexOf(aString) == 0;
return aString && aString != "" && self.indexOf(aString) == 0;
}
/*!
@@ -556,7 +556,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (BOOL)hasSuffix:(CPString)aString
{
return aString && aString != "" && length >= aString.length && lastIndexOf(aString) == (length - aString.length);
return aString && aString != "" && self.length >= aString.length && self.lastIndexOf(aString) == (self.length - aString.length);
}
- (BOOL)isEqual:(id)anObject
@@ -657,7 +657,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)lowercaseString
{
return toLowerCase();
return self.toLowerCase();
}
/*!
@@ -665,7 +665,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)uppercaseString
{
return toUpperCase();
return self.toUpperCase();
}
/*!
@@ -710,13 +710,13 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPArray)pathComponents
{
if (length === 0)
if (self.length === 0)
return [""];
if (self === "/")
return ["/"];
var result = split('/');
var result = self.split('/');
if (result[0] === "")
result[0] = "/";
@@ -787,10 +787,10 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)pathExtension
{
if (lastIndexOf('.') === CPNotFound)
if (self.lastIndexOf('.') === CPNotFound)
return "";
return substr(lastIndexOf('.') + 1);
return self.substr(self.lastIndexOf('.') + 1);
}
/*!
@@ -830,7 +830,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)stringByAppendingPathExtension:(CPString)ext
{
if (ext.indexOf('/') >= 0 || length === 0 || self === "/") // Can't handle these
if (ext.indexOf('/') >= 0 || self.length === 0 || self === "/") // Can't handle these
return self;
var components = [self pathComponents],
@@ -852,7 +852,7 @@ var CPStringUIDs = new CFMutableDictionary(),
*/
- (CPString)stringByDeletingLastPathComponent
{
if (length === 0)
if (self.length === 0)
return "";
else if (self === "/")
return "/";
@@ -880,10 +880,10 @@ var CPStringUIDs = new CFMutableDictionary(),
if (extension === "")
return self;
else if (lastIndexOf('.') < 1)
else if (self.lastIndexOf('.') < 1)
return self;
return substr(0, [self length] - (extension.length + 1));
return self.substr(0, [self length] - (extension.length + 1));
}
- (CPString)stringByStandardizingPath
+2 -2
View File
@@ -94,7 +94,7 @@ var CPURLConnectionDelegate = nil;
@param anError not used
@return the data at the URL or \c nil if there was an error
*/
+ (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:({CPURLResponse})aURLResponse
+ (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:(/*{*/CPURLResponse/*}*/)aURLResponse
{
try
{
@@ -277,7 +277,7 @@ var CPURLConnectionDelegate = nil;
@implementation CPURLConnection (Deprecated)
+ (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:({CPURLResponse})aURLResponse error:(id)anError
+ (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:(/*{*/CPURLResponse/*}*/)aURLResponse error:(id)anError
{
_CPReportLenientDeprecation(self, _cmd, @selector(sendSynchronousRequest:returningResponse:));
+9 -4
View File
@@ -43,10 +43,10 @@ var transformerMap = [CPDictionary dictionary];
if (self !== [CPValueTransformer class])
return;
[CPValueTransformer setValueTransformer:[[CPNegateBooleanTransformer alloc] init] forName:CPNegateBooleanTransformerName];
[CPValueTransformer setValueTransformer:[[CPIsNilTransformer alloc] init] forName:CPIsNilTransformerName];
[CPValueTransformer setValueTransformer:[[CPIsNotNilTransformer alloc] init] forName:CPIsNotNilTransformerName];
[CPValueTransformer setValueTransformer:[[CPUnarchiveFromDataTransformer alloc] init] forName:CPUnarchiveFromDataTransformerName];
// [CPValueTransformer setValueTransformer:[[CPNegateBooleanTransformer alloc] init] forName:CPNegateBooleanTransformerName];
// [CPValueTransformer setValueTransformer:[[CPIsNilTransformer alloc] init] forName:CPIsNilTransformerName];
// [CPValueTransformer setValueTransformer:[[CPIsNotNilTransformer alloc] init] forName:CPIsNotNilTransformerName];
// [CPValueTransformer setValueTransformer:[[CPUnarchiveFromDataTransformer alloc] init] forName:CPUnarchiveFromDataTransformerName];
}
+ (void)setValueTransformer:(CPValueTransformer)transformer forName:(CPString)aName
@@ -192,3 +192,8 @@ CPIsNilTransformerName = @"CPIsNil";
CPIsNotNilTransformerName = @"CPIsNotNil";
CPUnarchiveFromDataTransformerName = @"CPUnarchiveFromData";
CPKeyedUnarchiveFromDataTransformerName = @"CPKeyedUnarchiveFromData";
[CPValueTransformer setValueTransformer:[[CPNegateBooleanTransformer alloc] init] forName:CPNegateBooleanTransformerName];
[CPValueTransformer setValueTransformer:[[CPIsNilTransformer alloc] init] forName:CPIsNilTransformerName];
[CPValueTransformer setValueTransformer:[[CPIsNotNilTransformer alloc] init] forName:CPIsNotNilTransformerName];
[CPValueTransformer setValueTransformer:[[CPUnarchiveFromDataTransformer alloc] init] forName:CPUnarchiveFromDataTransformerName];
+2
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPObject.j"
@implementation _CPCollectionKVCOperator : CPObject
+ (id)performOperation:(CPString)operator withCollection:(id)aCollection propertyPath:(CPString)propertyPath
+9
View File
@@ -106,6 +106,15 @@ function addClassToBundle(aClass, aBundle)
CFBundlesForClasses[aClass.name] = aBundle;
}
function resetBundle()
{
CFBundlesForURLStrings = { };
CFBundlesForClasses = { };
//CFCacheBuster = new Date().getTime(),
CFTotalBytesLoaded = 0;
CPApplicationSizeInBytes = 0;
}
CFBundle.bundleForClass = function(/*Class*/ aClass)
{
return CFBundlesForClasses[aClass.name] || CFBundle.mainBundle();
+26
View File
@@ -300,6 +300,32 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure)
if (aURL.pathExtension() === "plist")
request.overrideMimeType("text/xml");
#if COMMONJS
if (aURL.pathExtension() === "j")
{
var aFilePath = aURL.toString().substring(5),
OS = require("os"),
gccFlags = require("objective-j").currentCompilerFlags(),
gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk,
fileContents = "";
while (chunk = gcc.stdout.read())
fileContents += chunk;
if (fileContents.length > 0)
{
request._nativeRequest.responseText = fileContents;
onsuccess({request: request});
}
else
{
onfailure({request: request});
}
return;
}
#endif
if (exports.asyncLoader)
{
request.onsuccess = Asynchronous(onsuccess);
+4 -3
View File
@@ -94,7 +94,7 @@ exports.run = function(args)
var arg0 = argv.shift();
var mainFilePath = FILE.canonical(arg0);
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print, window);
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
if (typeof main === "function")
main([arg0].concat(argv));
@@ -149,13 +149,14 @@ exports.repl = function()
};
// creates a narwhal factory function in the objj module scope
exports.make_narwhal_factory = function(path)
exports.make_narwhal_factory = function(path, basePath, filenameTranslateDictionary)
{
return function(require, exports, module, system, print)
{
Executable.setCommonJSParameters("require", "exports", "module", "system", "print", "window");
Executable.setCommonJSArguments(require, exports, module, system, print, window);
Executable.fileImporterForURL(FILE.dirname(path))(path, YES);
filenameTranslateDictionary && Executable.setFilenameTranslateDictionary(filenameTranslateDictionary);
Executable.fileImporterForURL(basePath ? basePath : FILE.dirname(path))(path, YES);
}
};
@@ -1,13 +1,14 @@
var FILE = require("file"),
OS = require("os"),
ObjectiveJ = require("objective-j");
ObjectiveJ = require("objective-j"),
JAKE = require("jake");
require("objective-j/rhino/regexp-rhino-patch");
ObjectiveJ.Preprocessor.Flags.Preprocess = 1 << 10;
ObjectiveJ.Preprocessor.Flags.Compress = 1 << 11;
ObjectiveJ.Preprocessor.Flags.CheckSyntax = 1 << 12;
ObjectiveJ.ObjJAcornCompiler.Flags.Preprocess = 1 << 10;
ObjectiveJ.ObjJAcornCompiler.Flags.Compress = 1 << 11;
ObjectiveJ.ObjJAcornCompiler.Flags.CheckSyntax = 1 << 12;
var compressors = {
ss : { id : "minify/shrinksafe" }
@@ -36,48 +37,71 @@ function compressor(code)
function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags, asPlainJavascript)
{
var shouldObjjPreprocess = objjcFlags & ObjectiveJ.Preprocessor.Flags.Preprocess,
shouldCheckSyntax = objjcFlags & ObjectiveJ.Preprocessor.Flags.CheckSyntax,
shouldCompress = objjcFlags & ObjectiveJ.Preprocessor.Flags.Compress,
var shouldObjjPreprocess = objjcFlags & ObjectiveJ.ObjJAcornCompiler.Flags.Preprocess,
shouldCheckSyntax = objjcFlags & ObjectiveJ.ObjJAcornCompiler.Flags.CheckSyntax,
shouldCompress = objjcFlags & ObjectiveJ.ObjJAcornCompiler.Flags.Compress,
fileContents = "",
executable,
code;
if (OS.popen("which gcc").stdout.read().length === 0)
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
else
{
// GCC preprocess the file.
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk = "";
while (chunk = gcc.stdout.read())
fileContents += chunk;
}
if (!shouldObjjPreprocess)
{
if (OS.popen("which gcc").stdout.read().length === 0)
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
else
{
// GCC preprocess the file.
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk = "";
while (chunk = gcc.stdout.read())
fileContents += chunk;
}
return fileContents;
}
// Preprocess contents into fragments.
// FIXME: should calculate relative path, etc.
try
{
executable = ObjectiveJ.preprocess(fileContents, FILE.basename(aFilePath), objjcFlags);
var sources = new JAKE.FileList("**/*.j"),
translateFilenameToPath = {},
otherwayTranslateFilenameToPath = {};
// Create a filename to filename path dictionary. (For example: CPArray.j -> CPArray/CPArray.j)
sources.forEach(function(/*String*/ aFilename)
{
translateFilenameToPath[FILE.basename(aFilename)] = aFilename;
otherwayTranslateFilenameToPath[aFilename] = FILE.basename(aFilename);
}, this);
var translatedFilename = translateFilenameToPath[aFilePath] ? translateFilenameToPath[aFilePath] : aFilePath,
otherwayTranslatedFilename = otherwayTranslateFilenameToPath[aFilePath] ? otherwayTranslateFilenameToPath[aFilePath] : aFilePath,
theTranslatedFilename = otherwayTranslatedFilename ? otherwayTranslatedFilename : translatedFilename,
absolutePath = FILE.absolute(theTranslatedFilename),
basePath = absolutePath.substring(0, absolutePath.length - theTranslatedFilename.length);
// This ugly fix to make Cappuccino compile with rhino can be removed when the compiler is not loading classes into the runtime
var rhinoUglyFix = false;
if (system.engine === "rhino")
{
if (typeof document == "undefined") {
document = { createElement: function(x) { return { innerText: ""}}};
rhinoUglyFix = true;
}
}
ObjectiveJ.setCurrentCompilerFlags(objjcFlags);
ObjectiveJ.make_narwhal_factory(absolutePath, basePath, translateFilenameToPath)(require, {}, module, system, print);
executable = new ObjectiveJ.FileExecutable(FILE.basename(aFilePath));
if (rhinoUglyFix)
delete document;
}
catch (anException)
{print(anException);
var lines = fileContents.split("\n"),
PAD = 3,
lineNumber = anException.lineNumber || anException.line,
errorInfo = "Syntax error in " + aFilePath +
" on preprocessed line number " + lineNumber + "\n\n" +
"\t" + lines.slice(Math.max(0, lineNumber - 1 - PAD), lineNumber + PAD).join("\n\t");
print(errorInfo);
throw errorInfo;
}
{}
if (shouldCompress)
{
@@ -100,7 +124,7 @@ function resolveFlags(args)
count = args.length,
gccFlags = [],
objjcFlags = ObjectiveJ.Preprocessor.Flags.Preprocess | ObjectiveJ.Preprocessor.Flags.CheckSyntax;
objjcFlags = ObjectiveJ.ObjJAcornCompiler.Flags.Preprocess | ObjectiveJ.ObjJAcornCompiler.Flags.CheckSyntax;
for (; index < count; ++index)
{
@@ -128,19 +152,19 @@ function resolveFlags(args)
}
else if (argument.indexOf("-E") === 0)
objjcFlags &= ~ObjectiveJ.Preprocessor.Flags.Preprocess;
objjcFlags &= ~ObjectiveJ.ObjJAcornCompiler.Flags.Preprocess;
else if (argument.indexOf("-S") === 0)
objjcFlags &= ~ObjectiveJ.Preprocessor.Flags.CheckSyntax;
objjcFlags &= ~ObjectiveJ.ObjJAcornCompiler.Flags.CheckSyntax;
else if (argument.indexOf("-T") === 0)
objjcFlags |= ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures;
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures;
else if (argument.indexOf("-g") === 0)
objjcFlags |= ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols;
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.IncludeDebugSymbols;
else if (argument.indexOf("-O") === 0)
objjcFlags |= ObjectiveJ.Preprocessor.Flags.Compress;
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.Compress;
else
filePaths.push(argument);
@@ -191,14 +215,14 @@ exports.main = function(args)
if (argv[0] === "-T" || argv[0] === "--includeTypeSignatures")
{
objjcFlags |= ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures;
objjcFlags |= ObjectiveJ.ObjJAcornCompiler.Flags.IncludeTypeSignatures;
argv.shift();
continue;
}
if (argv[0] === "--help" || argv[0].substr(0, 1) == '-')
{
print("Usage: " + args[0] + " [options] [--] file...");
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("");
@@ -789,7 +789,13 @@ BundleTask.prototype.defineStaticTask = function()
fileStream.write("e;");
fileStream.close();
});
// Make sure all classes are removed and all FileExecutables are removed.
ObjectiveJ.Executable.resetCachedFileExecutableSearchers();
ObjectiveJ.StaticResource.resetRootResources();
ObjectiveJ.FileExecutable.resetFileExecutables();
objj_resetRegisterClasses();
});
this.enhance([staticPath]);
}, this);
@@ -832,7 +838,18 @@ BundleTask.prototype.defineSourceTasks = function()
environmentCompilerFlags = anEnvironment.compilerFlags().join(" ") + " " + compilerFlags,
flattensSources = this.flattensSources(),
basePath = directoryInCommon(environmentSources),
basePathLength = basePath.length;
basePathLength = basePath.length,
translateFilenameToPath = {},
otherwayTranslateFilenameToPath = {};
// Create a filename to filename path dictionary. (For example: CPArray.j -> CPArray/CPArray.j)
environmentSources.forEach(function(/*String*/ aFilename)
{
translateFilenameToPath[flattensSources ? FILE.basename(aFilename) : aFilename] = aFilename;
otherwayTranslateFilenameToPath[aFilename] = flattensSources ? FILE.basename(aFilename) : aFilename;
}, this);
var e = {};
environmentSources.forEach(function(/*String*/ aFilename)
{
@@ -844,7 +861,17 @@ BundleTask.prototype.defineSourceTasks = function()
filedir (compiledEnvironmentSource, [aFilename], function()
{
var compile
// This ugly fix to make Cappuccino compile with rhino can be removed when the compiler is not loading classes into the runtime
var rhinoUglyFix = false;
if (system.engine === "rhino")
{
if (typeof document == "undefined") {
document = { createElement: function(x) { return { innerText: ""}}};
rhinoUglyFix = true;
}
}
var compile;
// if this file doesn't exist or isn't a .j file, don't preprocess it.
if (FILE.extension(aFilename) !== ".j")
{
@@ -853,21 +880,38 @@ BundleTask.prototype.defineSourceTasks = function()
}
else
{
var translatedFilename = translateFilenameToPath[aFilename] ? translateFilenameToPath[aFilename] : aFilename,
otherwayTranslatedFilename = otherwayTranslateFilenameToPath[aFilename] ? otherwayTranslateFilenameToPath[aFilename] : aFilename,
theTranslatedFilename = otherwayTranslatedFilename ? otherwayTranslatedFilename : translatedFilename,
absolutePath = FILE.absolute(theTranslatedFilename),
basePath = absolutePath.substring(0, absolutePath.length - theTranslatedFilename.length);
ObjectiveJ.setCurrentCompilerFlags(environmentCompilerFlags);
ObjectiveJ.make_narwhal_factory(absolutePath, basePath, translateFilenameToPath)(require, e, module, system, print);
TERM.stream.write("Compiling [\0blue(" + anEnvironment + "\0)] \0purple(" + aFilename + "\0)").flush();
var compiled = require("objective-j/compiler").compile(aFilename, environmentCompilerFlags);
var otherwayTranslatedFilename = otherwayTranslateFilenameToPath[aFilename] ? otherwayTranslateFilenameToPath[aFilename] : aFilename,
translatedFilename = translateFilenameToPath[aFilename] ? translateFilenameToPath[aFilename] : aFilename,
executer = new ObjectiveJ.FileExecutable(otherwayTranslatedFilename);
var compiled = executer.toMarkedString();
}
if (rhinoUglyFix)
delete document;
TERM.stream.print(Array(Math.round(compiled.length / 1024) + 3).join("."));
FILE.write(compiledEnvironmentSource, compiled, { charset:"UTF-8" });
});
filedir (staticPath, [compiledEnvironmentSource]);
replacedFiles.push(flattensSources ? FILE.basename(aFilename) : relativePath);
}, this);
this._replacedFiles[anEnvironment] = replacedFiles;
}, this);
}, this);
}
exports.BundleTask = BundleTask;
+64 -6
View File
@@ -26,16 +26,19 @@ var ExecutableUnloadedFileDependencies = 0,
ExecutableLoadedFileDependencies = 2,
AnonymousExecutableCount = 0;
function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String*/ aURL, /*Function*/ aFunction)
function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String*/ aURL, /*Function*/ aFunction, /*ObjJCompiler*/aCompiler, /*Dictionary*/ aFilenameTranslateDictionary)
{
if (arguments.length === 0)
return this;
this._code = aCode;
this._function = aFunction || NULL;
this._function = aFunction || null;
this._URL = makeAbsoluteURL(aURL || new CFURL("(Anonymous" + (AnonymousExecutableCount++) + ")"));
this._compiler = aCompiler || null;
this._fileDependencies = fileDependencies;
this._filenameTranslateDictionary = aFilenameTranslateDictionary;
if (fileDependencies.length)
{
@@ -48,7 +51,8 @@ function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String
if (this._function)
return;
this.setCode(aCode);
if (!aCompiler)
this.setCode(aCode);
}
exports.Executable = Executable;
@@ -114,6 +118,17 @@ Executable.commonJSArguments = function()
return this._commonJSArguments || [];
};
Executable.setFilenameTranslateDictionary = function(dict)
{
this._filenameTranslateDictionary = dict;
};
Executable.filenameTranslateDictionary = function()
{
return this._filenameTranslateDictionary || {};
};
Executable.prototype.toMarkedString = function()
{
var markedString = "@STATIC;1.0;",
@@ -135,6 +150,26 @@ Executable.prototype.execute = function()
#if EXECUTION_LOGGING
CPLog("EXECUTION: " + this.URL());
#endif
if (this._compiler)
{
var fileDependencies = this.fileDependencies(),
index = 0,
count = fileDependencies.length;
for (; index < count; ++index)
{
var fileDependency = fileDependencies[index],
isQuoted = fileDependency.isLocal(),
URL = fileDependency.URL();
this.fileExecuter()(URL, isQuoted);
}
this.setCode(this._compiler.compilePass2());
this._compiler = null;
}
var oldContextBundle = CONTEXT_BUNDLE;
// FIXME: Should we have stored this?
@@ -410,10 +445,30 @@ DISPLAY_NAME(Executable.fileImporterForURL);
var cachedFileExecutableSearchers = { },
cachedFileExecutableSearchResults = { };
function countProp(x) {
var count = 0;
for (var k in x) {
if (x.hasOwnProperty(k)) {
++count;
}
}
return count;
}
Executable.resetCachedFileExecutableSearchers = function()
{
cachedFileExecutableSearchers = { };
cachedFileExecutableSearchResults = { };
cachedFileImporters = { };
cachedFileExecuters = { };
fileDependencyMarkers = { };
}
Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
{
var referenceURLString = referenceURL.absoluteString(),
cachedFileExecutableSearcher = cachedFileExecutableSearchers[referenceURLString],
aFilenameTranslateDictionary = Executable.filenameTranslateDictionary ? Executable.filenameTranslateDictionary() : null;
cachedSearchResults = { };
if (!cachedFileExecutableSearcher)
@@ -433,7 +488,7 @@ Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
if (!isAbsoluteURL)
aURL = new CFURL(aURL, referenceURL);
StaticResource.resolveResourceAtURL(aURL, NO, completed);
StaticResource.resolveResourceAtURL(aURL, NO, completed, aFilenameTranslateDictionary);
}
else
StaticResource.resolveResourceAtURLSearchingIncludeURLs(aURL, completed);
@@ -441,11 +496,14 @@ Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
function completed(/*StaticResource*/ aStaticResource)
{
if (!aStaticResource)
throw new Error("Could not load file at " + aURL);
{
var compilingFileUrl = ObjJAcornCompiler ? ObjJAcornCompiler.currentCompileFile : null;
throw new Error("Could not load file at " + aURL + (compilingFileUrl ? " when compiling " + compilingFileUrl : ""));
}
cachedFileExecutableSearchResults[cacheUID] = aStaticResource;
success(new FileExecutable(aStaticResource.URL()));
success(new FileExecutable(aStaticResource.URL(), aFilenameTranslateDictionary));
}
};
+10 -6
View File
@@ -22,7 +22,7 @@
var FileExecutablesForURLStrings = { };
function FileExecutable(/*CFURL|String*/ aURL)
function FileExecutable(/*CFURL|String*/ aURL, /*Dictionary*/ aFilenameTranslateDictionary)
{
aURL = makeAbsoluteURL(aURL);
@@ -40,14 +40,12 @@ function FileExecutable(/*CFURL|String*/ aURL)
if (fileContents.match(/^@STATIC;/))
executable = decompile(fileContents, aURL);
else if (extension === "j" || !extension)
executable = exports.preprocess(fileContents, aURL, Preprocessor.Flags.IncludeDebugSymbols);
else if ((extension === "j" || !extension) && !fileContents.match(/^{/))
executable = exports.ObjJAcornCompiler.compileFileDependencies(fileContents, aURL, ObjJAcornCompiler.Flags.IncludeDebugSymbols);
else
executable = new Executable(fileContents, [], aURL);
Executable.apply(this, [executable.code(), executable.fileDependencies(), aURL, executable._function]);
Executable.apply(this, [executable.code(), executable.fileDependencies(), aURL, executable._function, executable._compiler, aFilenameTranslateDictionary]);
this._hasExecuted = NO;
}
@@ -70,6 +68,12 @@ FileExecutable.allFileExecutables = function()
}
#endif
FileExecutable.resetFileExecutables = function()
{
FileExecutablesForURLStrings = { };
FunctionCache = { };
}
FileExecutable.prototype.execute = function(/*BOOL*/ shouldForce)
{
if (this._hasExecuted && !shouldForce)
+3
View File
@@ -43,6 +43,9 @@
#include "CFBundle.js"
#include "StaticResource.js"
#include "Preprocessor.js"
#include "acorn.js"
#include "acornwalk.js"
#include "ObjJAcornCompiler.js"
#include "FileDependency.js"
#include "Executable.js"
#include "FileExecutable.js"
+736
View File
@@ -0,0 +1,736 @@
/*
* ObjJAcornCompiler.js
* Objective-J
*
* Created by Martin Carlberg.
* Copyright 2013, Martin Carlberg.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
var Scope = function(prev, base)
{
this.vars = Object.create(null);
if (base) for (var key in base) this[key] = base[key];
this.prev = prev;
if (prev) this.compiler = prev.compiler;
}
Scope.prototype.compiler = function()
{
return this.compiler;
}
Scope.prototype.currentClassName = function()
{
return this.classDef ? this.classDef.className : this.prev ? this.prev.currentClassName() : null;
}
Scope.prototype.getIvarForCurrentClass = function(/* String */ ivarName)
{
if (this.ivars)
{
var ivar = this.ivars[ivarName];
if (ivar)
return ivar;
}
var prev = this.prev;
// Stop at the class declaration
if (prev && !this.classDef)
return prev.getIvarForCurrentClass(ivarName);
return null;
}
Scope.prototype.getLvar = function(/* String */ lvarName)
{
if (this.vars)
{
var lvar = this.vars[lvarName];
if (lvar)
return lvar;
}
var prev = this.prev;
// Stop at the method declaration
if (prev && !this.methodtype)
return prev.getLvar(lvarName);
return null;
}
Scope.prototype.currentMethodType = function()
{
return this.methodType ? this.methodType : this.prev ? this.prev.currentMethodType() : null;
}
Scope.prototype.copyAddedSelfToIvarsToParent = function()
{
if (this.prev && this.addedSelfToIvars) for (var key in this.addedSelfToIvars)
{
var addedSelfToIvar = this.addedSelfToIvars[key],
scopeAddedSelfToIvar = (this.prev.addedSelfToIvars || (this.prev.addedSelfToIvars = Object.create(null)))[key] || (this.prev.addedSelfToIvars[key] = []);
scopeAddedSelfToIvar.push.apply(scopeAddedSelfToIvar, addedSelfToIvar); // Append at end in parent scope
}
}
var currentCompilerFlags = "";
var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*/ flags, /*unsigned*/ pass)
{
this.source = aString;
this.URL = new CFURL(aURL);
this.pass = pass;
this.jsBuffer = new StringBuffer();
this.imBuffer = null;
this.cmBuffer = null;
this.warnings = [];
try {
this.tokens = exports.acorn.parse(aString);
}
catch (e) {
if (e.lineStart)
{
var message = this.prettifyMessage(e, "ERROR");
#ifdef BROWSER
console.log(message);
#else
print(message);
#endif
}
throw e;
}
this.dependencies = [];
this.flags = flags | ObjJAcornCompiler.Flags.IncludeDebugSymbols;
this.classDefs = Object.create(null);
this.lastPos = 0;
compile(this.tokens, new Scope(null ,{ compiler: this }), pass === 2 ? pass2 : pass1);
}
exports.ObjJAcornCompiler = ObjJAcornCompiler;
exports.ObjJAcornCompiler.compileToExecutable = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*/ flags)
{
ObjJAcornCompiler.currentCompileFile = aURL;
return new ObjJAcornCompiler(aString, aURL, flags, 2).executable();
}
exports.ObjJAcornCompiler.compileToIMBuffer = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*/ flags)
{
return new ObjJAcornCompiler(aString, aURL, flags, 2).IMBuffer();
}
exports.ObjJAcornCompiler.compileFileDependencies = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*/ flags)
{
ObjJAcornCompiler.currentCompileFile = aURL;
return new ObjJAcornCompiler(aString, aURL, flags, 1).executable();
}
ObjJAcornCompiler.prototype.compilePass2 = function()
{
ObjJAcornCompiler.currentCompileFile = this.URL;
this.pass = 2;
this.jsBuffer = new StringBuffer();
this.warnings = [];
compile(this.tokens, new Scope(null ,{ compiler: this }), pass2);
for (var i = 0; i < this.warnings.length; i++)
{
var message = this.prettifyMessage(this.warnings[i], "WARNING");
#ifdef BROWSER
console.log(message);
#else
print(message);
#endif
}
return this.jsBuffer.toString();
}
var currentCompilerFlags = "";
exports.setCurrentCompilerFlags = function(/*String*/ compilerFlags)
{
currentCompilerFlags = compilerFlags;
}
exports.currentCompilerFlags = function(/*String*/ compilerFlags)
{
return currentCompilerFlags;
}
ObjJAcornCompiler.Flags = { };
ObjJAcornCompiler.Flags.IncludeDebugSymbols = 1 << 0;
ObjJAcornCompiler.Flags.IncludeTypeSignatures = 1 << 1;
ObjJAcornCompiler.prototype.addWarning = function(/* Warning */ aWarning)
{
this.warnings.push(aWarning);
}
ObjJAcornCompiler.prototype.getIvarForClass = function(/* String */ ivarName, /* Scope */ scope)
{
var ivar = scope.getIvarForCurrentClass(ivarName);
if (ivar)
return ivar;
var c = this.getClassDef(scope.currentClassName());
while (c)
{
var ivars = c.ivars;
if (ivars)
{
var ivarDef = ivars[ivarName];
if (ivarDef)
return ivarDef;
}
c = this.getClassDef(c.superClassName);
}
}
ObjJAcornCompiler.prototype.getClassDef = function(/* String */ aClassName)
{
if (!aClassName) return null;
var c = this.classDefs[aClassName];
if (c) return c;
if (objj_getClass)
{
var aClass = objj_getClass(aClassName);
if (aClass)
{
var ivars = class_copyIvarList(aClass),
ivarSize = ivars.length,
myIvars = Object.create(null),
superClass = aClass.super_class;
for (var i = 0; i < ivarSize; i++)
{
var ivar = ivars[i];
myIvars[ivar.name] = {"type": ivar.type, "name": ivar.name};
}
c = {"className": aClassName, "ivars": myIvars};
if (superClass)
c.superClassName = superClass.name;
this.classDefs[aClassName] = c;
return c;
}
}
return null;
// classDef = {"className": className, "superClassName": superClassName, "ivars": Object.create(null), "methods": Object.create(null)};
}
ObjJAcornCompiler.prototype.executable = function()
{
if (!this._executable)
this._executable = new Executable(this.jsBuffer ? this.jsBuffer.toString() : null, this.dependencies, this.URL, null, this);
return this._executable;
}
ObjJAcornCompiler.prototype.IMBuffer = function()
{
return this.imBuffer;
}
ObjJAcornCompiler.prototype.JSBuffer = function()
{
return this.jsBuffer;
}
ObjJAcornCompiler.prototype.prettifyMessage = function(/* Message */ aMessage, /* String */ messageType)
{
var line = this.source.substring(aMessage.lineStart, aMessage.lineEnd),
message = "\n" + line;
message += (new Array(aMessage.column + 1)).join(" ");
message += (new Array(Math.min(1, line.length) + 1)).join("^") + "\n";
message += messageType + " line " + aMessage.line + " in " + this.URL + ": " + aMessage.message;
return message;
}
ObjJAcornCompiler.prototype.error_message = function(errorMessage, astNode)
{
return errorMessage + " <Context File: "+ this.URL +
(this.currentClass ? " Class: "+this.currentClass : "") +
(this.currentSelector ? " Method: "+this.currentSelector : "") +">";
}
function createMessage(/* String */ aMessage, /* SpiderMonkey AST node */ node, /* String */ code)
{
var message = exports.acorn.getLineInfo(code, node.start);
message.message = aMessage;
return message;
}
function compile(node, state, visitor) {
function c(node, st, override) {
visitor[override || node.type](node, st, c);
}
c(node, state);
};
var pass1 = exports.acorn.walk.make({
ImportStatement: function(node, st, c) {
var urlString = node.filename.value;
st.compiler.dependencies.push(new FileDependency(new CFURL(urlString), node.localfilepath));
}
});
var pass2 = exports.acorn.walk.make({
Program: function(node, st, c) {
for (var i = 0; i < node.body.length; ++i) {
c(node.body[i], st, "Statement");
}
CONCAT(st.compiler.jsBuffer,st.compiler.source.substring(st.compiler.lastPos, node.end));
},
Function: function(node, scope, c) {
var inner = new Scope(scope);
for (var i = 0; i < node.params.length; ++i)
inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
if (node.id) {
var decl = node.type == "FunctionDeclaration";
(decl ? scope : inner).vars[node.id.name] =
{type: decl ? "function" : "function name", node: node.id};
CONCAT(scope.compiler.jsBuffer,scope.compiler.source.substring(scope.compiler.lastPos, node.start));
CONCAT(scope.compiler.jsBuffer, node.id.name);
CONCAT(scope.compiler.jsBuffer, " = function");
scope.compiler.lastPos = node.id.end;
}
c(node.body, inner, "ScopeBody");
inner.copyAddedSelfToIvarsToParent();
},
TryStatement: function(node, scope, c) {
c(node.block, scope, "Statement");
for (var i = 0; i < node.handlers.length; ++i) {
var handler = node.handlers[i], inner = new Scope(scope);
inner.vars[handler.param.name] = {type: "catch clause", node: handler.param};
c(handler.body, inner, "ScopeBody");
inner.copyAddedSelfToIvarsToParent();
}
if (node.finalizer) c(node.finalizer, scope, "Statement");
},
VariableDeclaration: function(node, scope, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i],
identifier = decl.id.name;
scope.vars[identifier] = {type: "var", node: decl.id};
if (decl.init) c(decl.init, scope, "Expression");
if (scope.addedSelfToIvars) {
var addedSelfToIvar = scope.addedSelfToIvars[identifier];
if (addedSelfToIvar) {
var buffer = scope.compiler.jsBuffer.atoms;
for (var i = 0; i < addedSelfToIvar.length; i++) {
var dict = addedSelfToIvar[i];
buffer[dict.index] = "";
scope.compiler.addWarning(createMessage("Local declaration of '" + identifier + "' hides instance variable", dict.node, scope.compiler.source));
}
scope.addedSelfToIvars[identifier] = [];
}
}
}
},
MemberExpression: function(node, st, c) {
c(node.object, st, "Expression");
st.secondMemberExpression = !node.computed;
c(node.property, st, "Expression");
st.secondMemberExpression = false;
},
ImportStatement: function(node, st, c) {
var buffer = st.compiler.jsBuffer;
if (!buffer) return;
CONCAT(buffer,st.compiler.source.substring(st.compiler.lastPos, node.start));
CONCAT(buffer, "objj_executeFile(\"");
CONCAT(buffer, node.filename.value);
CONCAT(buffer, node.localfilepath ? "\", YES);" : "\", NO);");
st.compiler.lastPos = node.end;
},
ClassDeclarationStatement: function(node, st, c) {
var classDef,
saveJSBuffer = st.compiler.jsBuffer,
className = node.classname.name,
classScope = new Scope(st);
st.compiler.imBuffer = new StringBuffer();
st.compiler.cmBuffer = new StringBuffer();
st.compiler.classBodyBuffer = new StringBuffer(); // TODO: Check if this is needed
CONCAT(saveJSBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
// First we declare the class
if (node.superclassname)
{
if (st.compiler.getClassDef(className))
throw new SyntaxError(st.compiler.error_message("Duplicate class " + className, node.classname));
if (!st.compiler.getClassDef(node.superclassname.name))
throw new SyntaxError(st.compiler.error_message("Can't find superclass " + node.superclassname.name, node.superclassname));
classDef = {"className": className, "superClassName": node.superclassname.name, "ivars": Object.create(null), "methods": Object.create(null)};
st.compiler.classDefs[className] = classDef;
CONCAT(saveJSBuffer, "{var the_class = objj_allocateClassPair(" + node.superclassname.name + ", \"" + className + "\"),\nmeta_class = the_class.isa;");
}
else if (node.categoryname)
{
classDef = st.compiler.getClassDef(className);
if (!classDef)
throw new SyntaxError(st.compiler.error_message("Class " + className + " not found ", node.classname));
CONCAT(saveJSBuffer, "{\nvar the_class = objj_getClass(\"" + className + "\")\n");
CONCAT(saveJSBuffer, "if(!the_class) throw new SyntaxError(\"*** Could not find definition for class \\\"" + className + "\\\"\");\n");
CONCAT(saveJSBuffer, "var meta_class = the_class.isa;");
}
else
{
classDef = {"className": className, "superClassName": null, "ivars": Object.create(null), "methods": Object.create(null)};
st.compiler.classDefs[className] = classDef;
CONCAT(saveJSBuffer, "{var the_class = objj_allocateClassPair(Nil, \"" + className + "\"),\nmeta_class = the_class.isa;");
}
classScope.classDef = classDef;
st.compiler.currentSuperClass = "objj_getClass(\"" + className + "\").super_class";
st.compiler.currentSuperMetaClass = "objj_getMetaClass(\"" + className + "\").super_class";
var firstIvarDeclaration = true,
hasAccessors = false;
// Then we add all ivars
if (node.ivardeclarations) for (var i = 0; i < node.ivardeclarations.length; ++i)
{
var ivarDecl = node.ivardeclarations[i],
ivarType = ivarDecl.ivartype ? ivarDecl.ivartype.name : null,
ivarName = ivarDecl.id.name,
ivar = {"type": ivarType, "name": ivarName};
if (firstIvarDeclaration)
{
firstIvarDeclaration = false;
CONCAT(saveJSBuffer, "class_addIvars(the_class, [");
}
else
CONCAT(saveJSBuffer, ", ");
if (st.compiler.flags & ObjJAcornCompiler.Flags.IncludeTypeSignatures)
CONCAT(saveJSBuffer, "new objj_ivar(\"" + ivarName + "\", \"" + ivarType + "\")");
else
CONCAT(saveJSBuffer, "new objj_ivar(\"" + ivarName + "\")");
if (ivarDecl.outlet)
ivar.outlet = true;
classDef.ivars[ivarName] = ivar;
if (!classScope.ivars)
classScope.ivars = Object.create(null);
classScope.ivars[ivarName] = {type: "ivar", name: ivarName, node: ivarDecl.id, ivar: ivar};
if (!hasAccessors && ivarDecl.accessors)
hasAccessors = true;
}
if (!firstIvarDeclaration)
CONCAT(saveJSBuffer, "]);");
// If we have accessors add get and set methods for them
if (hasAccessors)
{
var getterSetterBuffer = new StringBuffer();
// Add the class declaration to compile accessors correctly
CONCAT(getterSetterBuffer, st.compiler.source.substring(node.start, node.endOfIvars));
CONCAT(getterSetterBuffer, "\n");
for (var i = 0; i < node.ivardeclarations.length; ++i)
{
var ivarDecl = node.ivardeclarations[i],
ivarType = ivarDecl.ivartype ? ivarDecl.ivartype.name : null,
ivarName = ivarDecl.id.name,
accessors = ivarDecl.accessors;
if (!accessors)
continue;
var property = (accessors.property && accessors.property.name) || ivarName,
getterName = (accessors.getter && accessors.getter.name) || property,
getterCode = "- (" + (ivarType ? ivarType : "id") + ")" + getterName + "\n{\nreturn " + ivarName + ";\n}\n";
CONCAT(getterSetterBuffer, getterCode);
if (accessors.readonly)
continue;
var setterName = accessors.setter ? accessors.setter.name : null;
if (!setterName)
{
var start = property.charAt(0) == '_' ? 1 : 0;
setterName = (start ? "_" : "") + "set" + property.substr(start, 1).toUpperCase() + property.substring(start + 1) + ":";
}
var setterCode = "- (void)" + setterName + "(" + (ivarType ? ivarType : "id") + ")newValue\n{\n";
if (accessors.copy)
setterCode += "if (" + ivarName + " !== newValue)\n" + ivarName + " = [newValue copy];\n}\n";
else
setterCode += ivarName + " = newValue;\n}\n";
CONCAT(getterSetterBuffer, setterCode);
}
CONCAT(getterSetterBuffer, "\n@end");
// Remove all @accessors or we will get a recursive loop in infinity
var b = getterSetterBuffer.toString().replace(/@accessors(\(.*\))?/g, "");
var imBuffer = ObjJAcornCompiler.compileToIMBuffer(b, "Accessors", st.compiler.flags);
// Add the accessors methods first to instance method buffer.
// This will allow manually added set and get methods to override the compiler generated
CONCAT(st.compiler.imBuffer, imBuffer);
}
if (node.body.length > 0)
{
st.compiler.lastPos = node.body[0].start;
// And last add methods and other statements
for (var i = 0; i < node.body.length; ++i) {
var body = node.body[i];
c(body, classScope, "Statement");
}
CONCAT(saveJSBuffer, st.compiler.source.substring(st.compiler.lastPos, body.end));
}
// We must make a new class object for our class definition if it's not a category
if (!node.categoryname) {
CONCAT(saveJSBuffer, "objj_registerClassPair(the_class);\n");
}
// Add instance methods
if (IS_NOT_EMPTY(st.compiler.imBuffer))
{
CONCAT(saveJSBuffer, "class_addMethods(the_class, [");
saveJSBuffer.atoms.push.apply(saveJSBuffer.atoms, st.compiler.imBuffer.atoms); // FIXME: Move this append to StringBuffer
CONCAT(saveJSBuffer, "]);\n");
}
// Add class methods
if (IS_NOT_EMPTY(st.compiler.cmBuffer))
{
CONCAT(saveJSBuffer, "class_addMethods(meta_class, [");
saveJSBuffer.atoms.push.apply(saveJSBuffer.atoms, st.compiler.cmBuffer.atoms); // FIXME: Move this append to StringBuffer
CONCAT(saveJSBuffer, "]);\n");
}
CONCAT(saveJSBuffer, "}");
st.compiler.jsBuffer = saveJSBuffer;
// Skip the "@end"
st.compiler.lastPos = node.end;
},
MethodDeclarationStatement: function(node, st, c) {
var saveJSBuffer = st.compiler.jsBuffer,
methodScope = new Scope(st),
selectors = node.selectors,
arguments = node.arguments,
types = [node.returntype ? node.returntype.name : "id"],
selector = selectors[0].name; // There is always at least one selector
CONCAT(saveJSBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
st.compiler.jsBuffer = node.methodtype === '-' ? st.compiler.imBuffer : st.compiler.cmBuffer;
// Put together the selector. Maybe this should be done in the parser...
for (var i = 0; i < arguments.length; i++) {
if (i === 0)
selector += ":";
else
selector += (selectors[i] ? selectors[i].name : "") + ":";
}
if (IS_NOT_EMPTY(st.compiler.jsBuffer)) // Add comma separator if this is not first method in this buffer
CONCAT(st.compiler.jsBuffer, ", ");
CONCAT(st.compiler.jsBuffer, "new objj_method(sel_getUid(\"");
CONCAT(st.compiler.jsBuffer, selector);
CONCAT(st.compiler.jsBuffer, "\"), function");
// this.currentSelector = selector;
if (st.compiler.flags & ObjJAcornCompiler.Flags.IncludeDebugSymbols)
{
CONCAT(st.compiler.jsBuffer, " $" + st.currentClassName() + "__" + selector.replace(/:/g, "_"));
}
CONCAT(st.compiler.jsBuffer, "(self, _cmd");
methodScope.methodType = node.methodtype;
if (arguments) for (var i = 0; i < arguments.length; i++)
{
var argument = arguments[i],
argumentName = argument.identifier.name;
CONCAT(st.compiler.jsBuffer, ", ");
CONCAT(st.compiler.jsBuffer, argumentName);
types.push(argument.type ? argument.type.name : null);
methodScope.vars[argumentName] = {type: "method argument", node: argument};
}
CONCAT(st.compiler.jsBuffer, ")");
st.compiler.lastPos = node.startOfBody;
c(node.body, methodScope, "Statement");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.body.end));
CONCAT(st.compiler.jsBuffer, "\n");
if (st.compiler.flags & ObjJAcornCompiler.Flags.IncludeDebugSymbols)
CONCAT(st.compiler.jsBuffer, ","+JSON.stringify(types));
CONCAT(st.compiler.jsBuffer, ")");
st.compiler.jsBuffer = saveJSBuffer;
st.compiler.lastPos = node.end;
},
MessageSendExpression: function(node, st, c) {
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
st.compiler.lastPos = node.object ? node.object.start : node.arguments.length ? node.arguments[0].start : node.end;
if (node.superObject)
{
CONCAT(st.compiler.jsBuffer, "objj_msgSendSuper(");
CONCAT(st.compiler.jsBuffer, "{ receiver:self, super_class:" + (st.currentMethodType() === "+" ? st.compiler.currentSuperMetaClass : st.compiler.currentSuperClass ) + " }");
}
else
{
CONCAT(st.compiler.jsBuffer, "objj_msgSend(");
c(node.object, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.object.end));
}
var selectors = node.selectors,
arguments = node.arguments,
selector = selectors[0].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 < arguments.length; i++)
if (i === 0)
selector += ":";
else
selector += (selectors[i] ? selectors[i].name : "") + ":";
CONCAT(st.compiler.jsBuffer, ", \"");
CONCAT(st.compiler.jsBuffer, selector); // FIXME: sel_getUid(selector + "") ? This FIXME is from the old preprocessor compiler
CONCAT(st.compiler.jsBuffer, "\"");
if (node.arguments) for (var i = 0; i < node.arguments.length; i++)
{
var argument = node.arguments[i];
CONCAT(st.compiler.jsBuffer, ", ");
st.compiler.lastPos = argument.start;
c(argument, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, argument.end));
st.compiler.lastPos = argument.end;
}
// TODO: Move this 'if' with body up inside the node.argument 'if'
if (node.parameters) for (var i = 0; i < node.parameters.length; ++i)
{
var parameter = node.parameters[i];
CONCAT(st.compiler.jsBuffer, ", ");
st.compiler.lastPos = parameter.start;
c(parameter, st, "Expression");
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, parameter.end));
st.compiler.lastPos = parameter.end;
}
CONCAT(st.compiler.jsBuffer, ")");
st.compiler.lastPos = node.end;
},
Identifier: function(node, st, c) {
if (st.currentMethodType() === "-" && !st.secondMemberExpression)
{
var identifier = node.name,
lvar = st.getLvar(identifier),
ivar = st.compiler.getIvarForClass(identifier, st);
if (ivar)
{
if (lvar)
st.compiler.addWarning(createMessage("Local declaration of '" + identifier + "' hides instance variable", node, st.compiler.source));
else
{
var nodeStart = node.start,
compiler = st.compiler;
do { // The Spider Monkey AST tree includes any parentheses in start and end properties so we have to make sure we skip those
CONCAT(compiler.jsBuffer, compiler.source.substring(compiler.lastPos, nodeStart));
compiler.lastPos = nodeStart;
} while (compiler.source.substr(nodeStart++, 1) === "(")
// Save the index in where the "self." string is stored and the node.
// These will be used if we find a variable declaration that is hoisting this identifier.
((st.addedSelfToIvars || (st.addedSelfToIvars = Object.create(null)))[identifier] || (st.addedSelfToIvars[identifier] = [])).push({node: node, index: compiler.jsBuffer.atoms.length});
CONCAT(compiler.jsBuffer, "self.");
}
}
}
},
SelectorLiteralExpression: function(node, st, c) {
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
CONCAT(st.compiler.jsBuffer, "sel_getUid(\"");
CONCAT(st.compiler.jsBuffer, node.selector);
CONCAT(st.compiler.jsBuffer, "\")");
st.compiler.lastPos = node.end;
},
Literal: function(node, st, c) {
if (node.raw && node.raw.charAt(0) === "@")
{
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
st.compiler.lastPos = node.start + 1;
}
},
ObjectExpression: function(node, st, c) {
for (var i = 0; i < node.properties.length; ++i)
{
var prop = node.properties[i];
if (prop.key.raw && prop.key.raw.charAt(0) === "@")
{
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, prop.key.start));
st.compiler.lastPos = prop.key.start + 1;
}
c(prop.value, st, "Expression");
}
},
PreprocessStatement: function(node, st, c) {
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
st.compiler.lastPos = node.start;
CONCAT(st.compiler.jsBuffer, "//");
}
});
+21
View File
@@ -484,6 +484,18 @@ GLOBAL(objj_registerClassPair) = function(/*Class*/ aClass)
DISPLAY_NAME(objj_registerClassPair);
GLOBAL(objj_resetRegisterClasses) = function()
{
for (var key in REGISTERED_CLASSES)
delete global[key];
REGISTERED_CLASSES = {};
resetBundle();
}
DISPLAY_NAME(objj_resetRegisterClasses);
// Instantiating Classes
GLOBAL(class_createInstance) = function(/*Class*/ aClass)
@@ -574,6 +586,15 @@ GLOBAL(objj_getClass) = function(/*String*/ aName)
{
var theClass = REGISTERED_CLASSES[aName];
/*if (!theClass)
{
for (var key in REGISTERED_CLASSES)
{
print("regClass: " + key + ", regClass.isa: " + REGISTERED_CLASSES[key].isa);
}
print("");
}*/
if (!theClass)
{
// class handler callback???
+41 -7
View File
@@ -1,7 +1,7 @@
var rootResources = { };
function StaticResource(/*CFURL*/ aURL, /*StaticResource*/ aParent, /*BOOL*/ isDirectory, /*BOOL*/ isResolved)
function StaticResource(/*CFURL*/ aURL, /*StaticResource*/ aParent, /*BOOL*/ isDirectory, /*BOOL*/ isResolved, /*Dictionary*/ aFilenameTranslateDictionary)
{
this._parent = aParent;
this._eventDispatcher = new EventDispatcher(this);
@@ -11,6 +11,7 @@ function StaticResource(/*CFURL*/ aURL, /*StaticResource*/ aParent, /*BOOL*/ isD
this._name = name;
this._URL = aURL; //new CFURL(aName, aParent && aParent.URL().asDirectoryPathURL());
this._isResolved = !!isResolved;
this._filenameTranslateDictionary = aFilenameTranslateDictionary;
if (isDirectory)
this._URL = this._URL.asDirectoryPathURL();
@@ -36,6 +37,26 @@ StaticResource.rootResources = function()
return rootResources;
};
function countProp(x) {
var count = 0;
for (var k in x) {
if (x.hasOwnProperty(k)) {
++count;
}
}
return count;
}
StaticResource.resetRootResources = function()
{
rootResources = {};
};
StaticResource.prototype.filenameTranslateDictionary = function()
{
return this._filenameTranslateDictionary || {};
};
exports.StaticResource = StaticResource;
function resolveStaticResource(/*StaticResource*/ aResource)
@@ -76,7 +97,20 @@ StaticResource.prototype.resolve = function()
resolveStaticResource(self);
}
new FileRequest(this.URL(), onsuccess, onfailure);
var url = this.URL(),
aFilenameTranslateDictionary = this.filenameTranslateDictionary();
if (aFilenameTranslateDictionary)
{
var urlString = url.toString(),
lastPathComponent = url.lastPathComponent(),
basePath = urlString.substring(0, urlString.length - lastPathComponent.length),
translatedName = aFilenameTranslateDictionary[lastPathComponent];
if (translatedName && urlString.slice(-translatedName.length) !== translatedName)
url = new CFURL(basePath + translatedName); // FIXME: do an add component to url or something better....
}
new FileRequest(url, onsuccess, onfailure);
}
};
@@ -163,11 +197,11 @@ StaticResource.prototype.resourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*
return StaticResource.resourceAtURL(new CFURL(aURL, this.URL()), resolveAsDirectoriesIfNecessary);
};
StaticResource.resolveResourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*/ isDirectory, /*Function*/ aCallback)
StaticResource.resolveResourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*/ isDirectory, /*Function*/ aCallback, /*Dictionary*/ aFilenameTranslateDictionary)
{
aURL = makeAbsoluteURL(aURL).absoluteURL();
resolveResourceComponents(rootResourceForAbsoluteURL(aURL), isDirectory, aURL.pathComponents(), 0, aCallback);
resolveResourceComponents(rootResourceForAbsoluteURL(aURL), isDirectory, aURL.pathComponents(), 0, aCallback, aFilenameTranslateDictionary);
};
StaticResource.prototype.resolveResourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*/ isDirectory, /*Function*/ aCallback)
@@ -175,7 +209,7 @@ StaticResource.prototype.resolveResourceAtURL = function(/*CFURL|String*/ aURL,
StaticResource.resolveResourceAtURL(new CFURL(aURL, this.URL()).absoluteURL(), isDirectory, aCallback);
};
function resolveResourceComponents(/*StaticResource*/ aResource, /*BOOL*/ isDirectory, /*Array*/ components, /*Integer*/ index, /*Function*/ aCallback)
function resolveResourceComponents(/*StaticResource*/ aResource, /*BOOL*/ isDirectory, /*Array*/ components, /*Integer*/ index, /*Function*/ aCallback, /*Dictionry*/ aFilenameTranslateDictionary)
{
var count = components.length;
@@ -187,7 +221,7 @@ function resolveResourceComponents(/*StaticResource*/ aResource, /*BOOL*/ isDire
// If the child doesn't exist, create and resolve it.
if (!child)
{
child = new StaticResource(new CFURL(name, aResource.URL()), aResource, index + 1 < count || isDirectory , NO);
child = new StaticResource(new CFURL(name, aResource.URL()), aResource, index + 1 < count || isDirectory , NO, aFilenameTranslateDictionary);
child.resolve();
}
@@ -196,7 +230,7 @@ function resolveResourceComponents(/*StaticResource*/ aResource, /*BOOL*/ isDire
return child.addEventListener("resolve", function()
{
// Continue resolving once this is done.
resolveResourceComponents(aResource, isDirectory, components, index, aCallback);
resolveResourceComponents(aResource, isDirectory, components, index, aCallback, aFilenameTranslateDictionary);
});
// If we've already determined that this file doesn't exist...
+2149
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Please note that some subdirectories of the CodeMirror distribution
include their own LICENSE files, and are released under different
licences.
+256
View File
@@ -0,0 +1,256 @@
// AST walker module for Mozilla Parser API compatible trees
if (!exports.acorn) {
exports.acorn = {};
exports.acorn.walk = {};
}
(function(exports) {
"use strict";
// A simple walk is one where you simply specify callbacks to be
// called on specific nodes. The last two arguments are optional. A
// simple use would be
//
// walk.simple(myTree, {
// Expression: function(node) { ... }
// });
//
// to do something with all expressions. All Parser API node types
// can be used to identify node types, as well as Expression,
// Statement, and ScopeBody, which denote categories of nodes.
//
// The base argument can be used to pass a custom (recursive)
// walker, and state can be used to give this walked an initial
// state.
exports.simple = function(node, visitors, base, state) {
if (!base) base = exports;
function c(node, st, override) {
var type = override || node.type, found = visitors[type];
if (found) found(node, st);
base[type](node, st, c);
}
c(node, state);
};
// A recursive walk is one where your functions override the default
// walkers. They can modify and replace the state parameter that's
// threaded through the walk, and can opt how and whether to walk
// their child nodes (by calling their third argument on these
// nodes).
exports.recursive = function(node, state, funcs, base) {
var visitor = exports.make(funcs, base);
function c(node, st, override) {
visitor[override || node.type](node, st, c);
}
c(node, state);
};
// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
exports.make = function(funcs, base) {
if (!base) base = exports;
var visitor = {};
for (var type in base) visitor[type] = base[type];
for (var type in funcs) visitor[type] = funcs[type];
return visitor;
};
function skipThrough(node, st, c) { c(node, st); }
function ignore(node, st, c) {}
// Node walkers.
exports.Program = exports.BlockStatement = function(node, st, c) {
for (var i = 0; i < node.body.length; ++i) {
c(node.body[i], st, "Statement");
}
};
exports.Statement = skipThrough;
exports.EmptyStatement = ignore;
exports.ExpressionStatement = function(node, st, c) {
c(node.expression, st, "Expression");
};
exports.IfStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Statement");
if (node.alternate) c(node.alternate, st, "Statement");
};
exports.LabeledStatement = function(node, st, c) {
c(node.body, st, "Statement");
};
exports.BreakStatement = exports.ContinueStatement = ignore;
exports.WithStatement = function(node, st, c) {
c(node.object, st, "Expression");
c(node.body, st, "Statement");
};
exports.SwitchStatement = function(node, st, c) {
c(node.discriminant, st, "Expression");
for (var i = 0; i < node.cases.length; ++i) {
var cs = node.cases[i];
if (cs.test) c(cs.test, st, "Expression");
for (var j = 0; j < cs.consequent.length; ++j)
c(cs.consequent[j], st, "Statement");
}
};
exports.ReturnStatement = function(node, st, c) {
if (node.argument) c(node.argument, st, "Expression");
};
exports.ThrowStatement = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.TryStatement = function(node, st, c) {
c(node.block, st, "Statement");
for (var i = 0; i < node.handlers.length; ++i)
c(node.handlers[i].body, st, "ScopeBody");
if (node.finalizer) c(node.finalizer, st, "Statement");
};
exports.WhileStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.body, st, "Statement");
};
exports.DoWhileStatement = function(node, st, c) {
c(node.body, st, "Statement");
c(node.test, st, "Expression");
};
exports.ForStatement = function(node, st, c) {
if (node.init) c(node.init, st, "ForInit");
if (node.test) c(node.test, st, "Expression");
if (node.update) c(node.update, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInStatement = function(node, st, c) {
c(node.left, st, "ForInit");
c(node.right, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInit = function(node, st, c) {
if (node.type == "VariableDeclaration") c(node, st);
else c(node, st, "Expression");
};
exports.DebuggerStatement = ignore;
exports.FunctionDeclaration = function(node, st, c) {
c(node, st, "Function");
};
exports.VariableDeclaration = function(node, st, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
if (decl.init) c(decl.init, st, "Expression");
}
};
exports.Function = function(node, st, c) {
c(node.body, st, "ScopeBody");
};
exports.ScopeBody = function(node, st, c) {
c(node, st, "Statement");
};
exports.Expression = skipThrough;
exports.ThisExpression = ignore;
exports.ArrayExpression = function(node, st, c) {
for (var i = 0; i < node.elements.length; ++i) {
var elt = node.elements[i];
if (elt) c(elt, st, "Expression");
}
};
exports.ObjectExpression = function(node, st, c) {
for (var i = 0; i < node.properties.length; ++i)
c(node.properties[i].value, st, "Expression");
};
exports.FunctionExpression = exports.FunctionDeclaration;
exports.SequenceExpression = function(node, st, c) {
for (var i = 0; i < node.expressions.length; ++i)
c(node.expressions[i], st, "Expression");
};
exports.UnaryExpression = exports.UpdateExpression = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.BinaryExpression = exports.AssignmentExpression = exports.LogicalExpression = function(node, st, c) {
c(node.left, st, "Expression");
c(node.right, st, "Expression");
};
exports.ConditionalExpression = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Expression");
c(node.alternate, st, "Expression");
};
exports.NewExpression = exports.CallExpression = function(node, st, c) {
c(node.callee, st, "Expression");
if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
c(node.arguments[i], st, "Expression");
};
exports.MemberExpression = function(node, st, c) {
c(node.object, st, "Expression");
if (node.computed) c(node.property, st, "Expression");
};
exports.Identifier = exports.Literal = ignore;
exports.ClassDeclarationStatement = function(node, st, c) {
if (node.ivardeclarations) for (var i = 0; i < node.ivardeclarations.length; ++i) {
c(node.ivardeclarations[i], st, "IvarDeclaration");
}
for (var i = 0; i < node.body.length; ++i) {
c(node.body[i], st, "Statement");
}
}
exports.ImportStatement = ignore;
exports.IvarDeclaration = ignore;
exports.MethodDeclarationStatement = ignore;
exports.PreprocessStatement = ignore;
exports.MethodDeclarationStatement = function(node, st, c) {
c(node.body, st, "Statement");
}
exports.MessageSendExpression = function(node, st, c) {
if (!node.superObject) c(node.object, st, "Expression");
if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
c(node.arguments[i], st, "Expression");
if (node.parameters) for (var i = 0; i < node.parameters.length; ++i)
c(node.parameters[i], st, "Expression");
}
exports.SelectorLiteralExpression = ignore;
// A custom walker that keeps track of the scope chain and the
// variables defined in it.
function makeScope(prev) {
return {vars: Object.create(null), prev: prev};
}
exports.scopeVisitor = exports.make({
Function: function(node, scope, c) {
var inner = makeScope(scope);
for (var i = 0; i < node.params.length; ++i)
inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
if (node.id) {
var decl = node.type == "FunctionDeclaration";
(decl ? scope : inner).vars[node.id.name] =
{type: decl ? "function" : "function name", node: node.id};
}
c(node.body, inner, "ScopeBody");
},
TryStatement: function(node, scope, c) {
c(node.block, scope, "Statement");
for (var i = 0; i < node.handlers.length; ++i) {
var handler = node.handlers[i], inner = makeScope(scope);
inner.vars[handler.param.name] = {type: "catch clause", node: handler.param};
c(handler.body, inner, "ScopeBody");
}
if (node.finalizer) c(node.finalizer, scope, "Statement");
},
VariableDeclaration: function(node, scope, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
scope.vars[decl.id.name] = {type: "var", node: decl.id};
if (decl.init) c(decl.init, scope, "Expression");
}
}
});
})(typeof exports == "undefined" ? acorn.walk = {} : exports.acorn.walk);
+2 -1
View File
@@ -1,5 +1,6 @@
@import <AppKit/CPApplication.j>
@import <AppKit/CPWindow.j>
@import <AppKit/_CPStandardWindowView.j>
var globalResults = [];
@@ -67,7 +68,7 @@ var globalResults = [];
app = [CPApplication sharedApplication];
// fake the window.location.hash
app.window = {location: {hash: "#var1=1/var2=2"}};
window.location = {hash: "#var1=1/var2=2"};
[app setDelegate:[[MyAppDelegate alloc] init]];
aWindow = [[CPWindow alloc] init];
+2 -1
View File
@@ -1,4 +1,5 @@
@import <Foundation/CPArray.j>
@import <AppKit/CPArrayController.j>
@import <AppKit/CPTextField.j>
@@ -428,7 +429,7 @@
{
[self _initTestRemoveObjects_SimpleArray];
[self _testRemoveObjects_MultipleSelectedObjects_AvoidingEmptySelection];
}/
}
- (void)testRemoveObjects_MultipleSelectedObjects_AvoidingEmptySelection_ContentBinding
{
+3 -3
View File
@@ -4,7 +4,7 @@
{
CPOutlineView outlineView;
CPTableColumn tableColumn;
TestDataSource dataSource;
TestOutlineDataSource dataSource;
}
- (void)setUp
@@ -17,7 +17,7 @@
[outlineView setAllowsMultipleSelection:YES];
dataSource = [TestDataSource new];
dataSource = [TestOutlineDataSource new];
[dataSource setEntries:[".1", ".1.1", ".1.2", ".1.2.1", ".1.2.2", ".2", ".3", ".3.1"]];
[outlineView setDataSource:dataSource];
@@ -188,7 +188,7 @@
@end
@implementation TestDataSource : CPObject
@implementation TestOutlineDataSource : CPObject
{
CPArray entries @accessors;
}
+14 -11
View File
@@ -1,4 +1,5 @@
@import <AppKit/AppKit.j>
@import <Foundation/CPExpression.j>
@implementation CPPredicateEditorTest : OJTestCase
{
@@ -13,35 +14,35 @@
- (void)testTemplatesMerging
{
var le1 = [CPExpression expressionForKeyPath:@"keypath1"],
le2 = [CPExpression expressionForKeyPath:@"keypath2"],
le3 = [CPExpression expressionForKeyPath:@"keypath3"];
le2 = [CPExpression expressionForKeyPath:@"keypath2"],
le3 = [CPExpression expressionForKeyPath:@"keypath3"];
var lexps1 = [le1, le2],
var lexps1 = [le1, le2],
lexps2 = [le2, le3];
var ops1 = [CPBeginsWithPredicateOperatorType, CPEndsWithPredicateOperatorType],
ops2 = [CPGreaterThanPredicateOperatorType, CPEqualToPredicateOperatorType];
var t1 = [[CPPredicateEditorRowTemplate alloc] initWithLeftExpressions:lexps1 rightExpressionAttributeType:CPStringAttributeType modifier:0 operators:ops1 options:0],
t2 = [[CPPredicateEditorRowTemplate alloc] initWithLeftExpressions:lexps2 rightExpressionAttributeType:CPInteger16AttributeType modifier:0 operators:ops2 options:0];
var errorFormat = @"The left criterion %@ should have children with the following templates:\n%@\nbut was:\n%@";
[_editor setRowTemplates:[t1, t2]];
var trees = _editor._rootTrees;
var count = [trees count];
// We are expecting 3 criterion on the left.
[self assertTrue:(count == 3) message:"We should have 3 criterion on the left, was " + count];
[self assertTrue:(count == 3) message:"We should have 3 criterion on the left, was " + count];
for (var i = 0; i < count; i++)
{
var aTree = [trees objectAtIndex:i],
title = [aTree title],
templates = [[aTree children] valueForKey:@"template"],
expected;
if ([title isEqualToString:@"keypath1"])
expected = [t1, t1];
else if ([title isEqualToString:@"keypath2"])
@@ -50,5 +51,7 @@
expected = [t2, t2];
[self assertTrue:[templates isEqualToArray:expected] message:[CPString stringWithFormat:errorFormat, title, [expected description], [templates description]]];
}
}
}
@end
+2
View File
@@ -26,3 +26,5 @@
[_searchField setRecentSearches:searches]
[self assertTrue:[[_searchField recentSearches] count] == 3 message:@"After setRecentSearches array doesn't include results"];
}
@end
+1 -1
View File
@@ -1,4 +1,4 @@
@import <AppKit/CPTokenField.j>
@import <AppKit/AppKit.j>
[CPApplication sharedApplication];
+1
View File
@@ -1,5 +1,6 @@
@import <AppKit/CPWindow.j>
@import <AppKit/_CPBorderlessWindowView.j>
[CPApplication sharedApplication];
@@ -174,5 +174,5 @@
@end
@import "TableViewDataSource.j"
//@import "TableViewDataSource.j"
@@ -23,6 +23,7 @@
*/
@import "Bookmark.j"
@import "MyDocument.j"
@implementation MyDocument (TableView)
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "MyDocument.j"
@import "TableViewDataSource.j"
/*!
Bindings test exercising the functionality seen in the Cocoa example "WithAndWithoutBindings" part 1. Part 1 does in fact not use bindings and serves only as a base line test case.
@@ -90,4 +90,4 @@
[self assert:@"http://www.cappuccino.org" equals:[theDocument.selectedBookmarkURLField stringValue]];
}
@end
@end
@@ -22,7 +22,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@implementation Bookmark : CPObject
@implementation Bookmark2 : CPObject
{
CPString title @accessors;
CPDate creationDate @accessors;
@@ -22,9 +22,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "Bookmark.j"
@import "Bookmark2.j"
@implementation MyDocument : CPDocument
@implementation MyDocument2 : CPDocument
{
CPString name @accessors;
CPString collectionDescription @accessors;
@@ -389,7 +389,7 @@
<string>title</string>
<string>URL</string>
</object>
<string key="NSObjectClassName">Bookmark</string>
<string key="NSObjectClassName">Bookmark2</string>
<bool key="NSEditable">YES</bool>
<object class="_NSManagedProxy" key="_NSManagedProxy"/>
<bool key="NSAvoidsEmptySelection">YES</bool>
@@ -22,7 +22,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "Bookmark.j"
@import "Bookmark2.j"
// In 02 this is a subclass of CPArrayController.
@implementation MyArrayController : CPArrayController
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "MyDocument.j"
@import "MyDocument2.j"
@import "StringToURLTransformer.j"
/*!
@@ -39,7 +39,7 @@
- (void)test
{
var theDocument = [MyDocument new],
var theDocument = [MyDocument2 new],
cib = [CPBundle loadCibFile:[[CPBundle bundleForClass:WithBindingsTest] pathForResource:"02_WithBindings.cib"] externalNameTable:[CPDictionary dictionaryWithObject:theDocument forKey:CPCibOwner]];
[theDocument windowControllerDidLoadCib:self];
@@ -90,4 +90,4 @@
[self assert:@"http://www.cappuccino.org" equals:[theDocument.selectedBookmarkURLField stringValue]];
}
@end
@end
+3 -3
View File
@@ -15,7 +15,7 @@ var ELEMENTS = 100,
- (void)setUp
{
var descriptors = [
descriptors = [
[CPSortDescriptor sortDescriptorWithKey:"a" ascending:NO],
[CPSortDescriptor sortDescriptorWithKey:"b" ascending:YES]
];
@@ -227,7 +227,7 @@ var ELEMENTS = 100,
{
var count = [descriptors count];
sort(function(lhs, rhs)
self.sort(function(lhs, rhs)
{
var i = 0,
result = CPOrderedSame;
@@ -251,7 +251,7 @@ var ELEMENTS = 100,
- (CPArray)_native_sortUsingSelector:(SEL)aSelector
{
sort(function(lhs, rhs)
self.sort(function(lhs, rhs)
{
return [lhs performSelector:aSelector withObject:rhs];
});
+1 -1
View File
@@ -600,4 +600,4 @@ function testAttributeAtIndexWithValue(aString, anIndex, aKey, aValue, aSelf)
function printRangeEntry(entry)
{
print("range: " + CPStringFromRange(entry.range) + " " + [entry.attributes description]);
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
@import <Foundation/CPInvocationOperation.j>
@implementation SomeObject : CPObject
@implementation SomeObject2 : CPObject
{
CPString result @accessors;
}
@@ -17,7 +17,7 @@
- (void)testRunInvocation
{
var so = [[SomeObject alloc] init],
var so = [[SomeObject2 alloc] init],
io = [[CPInvocationOperation alloc] initWithTarget:so selector:@selector(setAString:) object:@"Hello World"];
[io start];
+2 -2
View File
@@ -328,7 +328,7 @@ var COUNTER;
[self assert:[two valueForKeyPath:"@max.intValue"] equals:8];
[self assert:[two valueForKeyPath:"@min.intValue"] equals:0];
var a = [A new];
var a = [AA new];
[a setValue:one forKey:"b"];
[self assert:[a valueForKeyPath:"b.@count"] equals:8];
[self assert:[a valueForKeyPath:"b.@sum.intValue"] equals:8];
@@ -347,7 +347,7 @@ var COUNTER;
@end
@implementation A : CPObject
@implementation AA : CPObject
{
id b;
}
+2 -2
View File
@@ -431,7 +431,7 @@
- (void)testDependentKeysPaths
{
var object = [[TestObject alloc] init];
var object = [[TestObject2 alloc] init];
[object addObserver:self forKeyPath:@"key" options:0 context:@"testDependentKeysPaths"];
@@ -880,7 +880,7 @@
}
@end
@implementation TestObject : CPObject
@implementation TestObject2 : CPObject
{
CPString key @accessors;
CPString affectingKey @accessors;
+5 -5
View File
@@ -480,8 +480,8 @@ var accessIVARS = YES;
- (void)testValueForKeyPath
{
var department = [Department departmentWithName:@"Engineering"],
employee = [Employee employeeWithName:@"Klaas Pieter" department:department];
var department = [Department2 departmentWithName:@"Engineering"],
employee = [Employee2 employeeWithName:@"Klaas Pieter" department:department];
[self assert:department equals:[employee valueForKey:@"department"]];
[self assert:@"Engineering" equals:[employee valueForKeyPath:@"department.name"]];
@@ -489,10 +489,10 @@ var accessIVARS = YES;
@end
@implementation Employee : CPObject
@implementation Employee2 : CPObject
{
CPString _name @accessors(property=name);
Department _department @accessors(property=department);
Department2 _department @accessors(property=department);
}
+ (id)employeeWithName:(CPString)theName department:(Department)theDepartment
@@ -513,7 +513,7 @@ var accessIVARS = YES;
@end
@implementation Department : CPObject
@implementation Department2 : CPObject
{
CPString _name @accessors(property=name);
}
+6 -6
View File
@@ -1,6 +1,6 @@
@import <Foundation/CPOperation.j>
@implementation TestOperation : CPOperation
@implementation TestOperation2 : CPOperation
{
CPString name @accessors;
CPString value @accessors;
@@ -13,7 +13,7 @@
@end
@implementation TestObserver : CPObject
@implementation TestObserver2 : CPObject
{
CPArray changedKeyPaths @accessors;
}
@@ -106,7 +106,7 @@
- (void)testCompletionFunction
{
var to = [[TestOperation alloc] init];
var to = [[TestOperation2 alloc] init];
[to setCompletionFunction:function() {[to setValue:@"something"];}];
[to start];
@@ -118,9 +118,9 @@
- (void)testKVO
{
var to = [[TestOperation alloc] init],
to2 = [[TestOperation alloc] init],
obs = [[TestObserver alloc] init];
var to = [[TestOperation2 alloc] init],
to2 = [[TestOperation2 alloc] init],
obs = [[TestObserver2 alloc] init];
[to addObserver:obs
forKeyPath:@"isCancelled"
+16 -16
View File
@@ -2,14 +2,14 @@
- (void)testThatSubclassTollFreeDoesAllowForSubclassingDictionary
{
var target = [[MyDict alloc] init];
var target = [[MyDict2 alloc] init];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assert:0 equals:[target count]];
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingString
{
var target = [[MyString alloc] initWithString:@"adsf"];
var target = [[MyString2 alloc] initWithString:@"adsf"];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assert:4 equals:[target length]];
@@ -20,42 +20,42 @@
- (void)testThatSubclassTollFreeDoesAllowForSubclassingNumber
{
var target = [[MyNum alloc] init];
var target = [[MyNum2 alloc] init];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assertFalse:[target isEqualToNumber:5]];
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingException
{
var target = [[MyException alloc] init];
var target = [[MyException2 alloc] init];
[OJAssert assert:@"a" equals:[target newMessage]];
// there are no internal properties to test here.. so no need to jimmyrig it.
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingArray
{
var target = [[MyArray alloc] initWithObjects:@"a"];
var target = [[MyArray2 alloc] initWithObjects:@"a"];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assert:1 equals:[target count]];
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingDate
{
var target = [[MyDate alloc] init];
var target = [[MyDate2 alloc] init];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assertTrue:[target timeIntervalSince1970] > 0];
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingData
{
var target = [[MyData alloc] initWithRawString:@"b"];
var target = [[MyData2 alloc] initWithRawString:@"b"];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assert:@"b" equals:[target rawString]];
}
- (void)testThatSubclassTollFreeDoesAllowForSubclassingURL
{
var target = [[MyURL alloc] initWithString:@"http://www.google.com"];
var target = [[MyURL2 alloc] initWithString:@"http://www.google.com"];
[OJAssert assert:@"a" equals:[target newMessage]];
[OJAssert assert:@"http://www.google.com" equals:[target absoluteString]];
}
@@ -65,7 +65,7 @@
@import <Foundation/CPDictionary.j>
@implementation MyDict : CPDictionary
@implementation MyDict2 : CPDictionary
- (id)newMessage
{
@@ -74,7 +74,7 @@
@end
@implementation MyNum : CPNumber
@implementation MyNum2 : CPNumber
- (id)newMessage
{
@@ -83,7 +83,7 @@
@end
@implementation MyString : CPString
@implementation MyString2 : CPString
- (id)newMessage
{
@@ -92,7 +92,7 @@
@end
@implementation MyException : CPException
@implementation MyException2 : CPException
- (id)newMessage
{
@@ -101,7 +101,7 @@
@end
@implementation MyArray : CPArray
@implementation MyArray2 : CPArray
{
CPArray _storage;
}
@@ -133,7 +133,7 @@
@end
@implementation MyDate : CPDate
@implementation MyDate2 : CPDate
- (id)newMessage
{
@@ -142,7 +142,7 @@
@end
@implementation MyData : CPData
@implementation MyData2 : CPData
- (id)newMessage
{
@@ -151,7 +151,7 @@
@end
@implementation MyURL : CPURL
@implementation MyURL2 : CPURL
- (id)newMessage
{
@@ -184,7 +184,7 @@ CPLogRegister(CPLogConsole);
return self;
}
- (BOOL)validatePrice:(id)value error:({CPError})error
- (BOOL)validatePrice:(id)value error:(/*{*/CPError/*}*/)error
{
if ([value intValue] >= 0)
return YES;
@@ -262,7 +262,7 @@ var rowHeights = [ ];
return YES;
}
- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id < CPDraggingInfo >)theInfo proposedItem:(id)theItem proposedChildIndex:(int)theIndex
- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id /*< CPDraggingInfo >*/)theInfo proposedItem:(id)theItem proposedChildIndex:(int)theIndex
{
CPLog.debug(@"validate item: %@ at index: %i", theItem, theIndex);
@@ -274,7 +274,7 @@ var rowHeights = [ ];
return CPDragOperationEvery;
}
- (BOOL)outlineView:(CPOutlineView)outlineView acceptDrop:(id < CPDraggingInfo >)theInfo item:(id)theItem childIndex:(int)theIndex
- (BOOL)outlineView:(CPOutlineView)outlineView acceptDrop:(id /*< CPDraggingInfo >*/)theInfo item:(id)theItem childIndex:(int)theIndex
{
if (theItem === nil)
theItem = [self menu];
+1
View File
@@ -37,6 +37,7 @@
@implementation RootClassWithForwardingTarget
{
Class isa;
}
+ (void)initialize
@@ -41,6 +41,31 @@
self.ivar1 = ivar1;
}
- (void)returnShadowingLocalVariable
{
var ivar1 = 2;
return ivar1;
}
- (void)returnShadowingHoistedLocalVariable
{
return ivar1;
var ivar1;
}
- (void)returnFunctionWithShadowingFunctionParameter
{
return function(ivar1) { return ivar1 };
}
- (void)returnFunctionWithShadowingHoistedLocalVariable
{
return function() { return ivar1; }
var ivar1;
}
@end
@implementation IvarTest : OJTestCase
@@ -60,33 +85,34 @@
[self assert:5 equals:testClass.ivar1];
}
- (void)testWithStatementInMethod
// I'm turning this test off as we move to the new compiler.
// We have to figure out how this should work. - Martin
/*- (void)testWithStatementInMethod
{
[self assert:nil equals:testClass.ivar1];
[testClass setIvar1DespiteAWithStatement:5];
[self assert:5 equals:testClass.ivar1];
[testClass doNothingToIvar1BecauseOfWithStatement:10];
[self assert:5 equals:testClass.ivar1];
}
}*/
- (void)testEvalInMethod
// I'm turning this test off as we move to the new compiler.
// We have to figure out how this should work. - Martin
/*- (void)testEvalInMethod
{
[self assert:nil equals:testClass.ivar1];
[testClass setIvar1UsingEval:5];
[self assert:5 equals:testClass.ivar1];
[testClass doNothingToIvar1UsingEval:10];
[self assert:5 equals:testClass.ivar1];
}
/*
TODO Reactivate this test after issue #498 is resolved.
}*/
- (void)testIvarShadowing
{
[self assert:nil equals:testClass.ivar1];
[testClass setIvar1UsingAShadowingLocalVariable:5];
[self assert:5 equals:testClass.ivar1];
}*/
}
- (void)testAccessorGeneration
{
@@ -117,4 +143,37 @@ TODO Reactivate this test after issue #498 is resolved.
[self assert:nil equals:testClass.ivar3];
}
- (void)testShadowingLocalVariable
{
[self assert:nil equals:testClass.ivar1];
testClass.ivar1 = 99;
var x = [testClass returnShadowingLocalVariable];
[self assert:2 equals:x];
}
- (void)testShadowingHoistedLocalVariable
{
[self assert:nil equals:testClass.ivar1];
testClass.ivar1 = 99;
var x = [testClass returnShadowingHoistedLocalVariable];
[self assert:"undefined" equals:typeof x];
}
- (void)testFunctionWithShadowingFunctionParameter
{
[self assert:nil equals:testClass.ivar1];
testClass.ivar1 = 99;
var f = [testClass returnFunctionWithShadowingFunctionParameter];
[self assert:8 equals:f(8)];
}
- (void)testFunctionWithShadowingHoistedLocalVariable
{
[self assert:nil equals:testClass.ivar1];
testClass.ivar1 = 99;
var f = [testClass returnFunctionWithShadowingHoistedLocalVariable];
[self assert:"undefined" equals:typeof f()];
}
@end
@@ -12,13 +12,13 @@
@implementation AppController (WebPolicyDelegate)
- (void)webView:(WebView *)aWebView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)aRequest newFrameName:(NSString *)aFrameName decisionListener:(id < WebPolicyDecisionListener >)aListener
- (void)webView:(WebView *)aWebView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)aRequest newFrameName:(NSString *)aFrameName decisionListener:(id /*< WebPolicyDecisionListener >*/)aListener
{
[[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
[aListener ignore];
}
- (void)webView:(WebView *)aWebView decidePolicyForNavigationAction:(NSDictionary *)aDictionary request:(NSURLRequest *)aRequest frame:(WebFrame *)aWebFrame decisionListener:(id <WebPolicyDecisionListener>)aDecisionListener
- (void)webView:(WebView *)aWebView decidePolicyForNavigationAction:(NSDictionary *)aDictionary request:(NSURLRequest *)aRequest frame:(WebFrame *)aWebFrame decisionListener:(id /*<WebPolicyDecisionListener>*/)aDecisionListener
{
NSURL * requestURL = [aRequest URL];
+3 -3
View File
@@ -124,12 +124,12 @@ var DefaultDictionary = nil,
- (void)save
{
var path = [self path];
var aPath = [self path];
if (!path)
if (!aPath)
return;
CFPropertyList.writePropertyListToFile(dictionary, path);
CFPropertyList.writePropertyListToFile(dictionary, aPath);
}
@end
+1 -1
View File
@@ -159,4 +159,4 @@ ConverterConversionException = @"ConverterConversionException";
@end
@import "Converter+Mac.j"
//@import "Converter+Mac.j"
+7
View File
@@ -1,4 +1,11 @@
@import <Foundation/CPExpression.j>
@import <Foundation/_CPKeyPathExpression.j>
@import <Foundation/_CPSetExpression.j>
@import <Foundation/_CPSelfExpression.j>
@import <Foundation/_CPConstantValueExpression.j>
@import <Foundation/_CPFunctionExpression.j>
@import <Foundation/_CPVariableExpression.j>
@import <Foundation/_CPAggregateExpression.j>
@implementation NSKeyPathExpression : _CPKeyPathExpression
{
+1
View File
@@ -29,6 +29,7 @@
@import "Nib2CibKeyedUnarchiver.j"
@import "Converter.j"
@import "Converter+Mac.j"
var FILE = require("file"),
OS = require("os"),