API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPObject.j
Go to the documentation of this file.
1 /*
2  * CPObject.j
3  * Foundation
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
64 @implementation CPObject
65 {
66  Class isa;
67 }
68 
69 + (void)load
70 {
71 }
72 
73 + (void)initialize
74 {
75 // CPLog("calling initialize "+self.name);
76 }
77 
82 + (id)new
83 {
84  return [[self alloc] init];
85 }
86 
90 + (id)alloc
91 {
92 // CPLog("calling alloc on " + self.name + ".");
93  return class_createInstance(self);
94 }
95 
96 + (id)allocWithCoder:(CPCoder)aCoder
97 {
98  return [self alloc];
99 }
100 
105 - (id)init
106 {
107  return self;
108 }
109 
114 - (id)copy
115 {
116  return self;
117 }
118 
124 {
125  return [self copy];
126 }
127 
131 - (void)dealloc
132 {
133 }
134 
135 // Identifying classes
139 + (Class)class
140 {
141  return self;
142 }
143 
147 - (Class)class
148 {
149  return isa;
150 }
151 
155 + (Class)superclass
156 {
157  return super_class;
158 }
159 
164 + (BOOL)isSubclassOfClass:(Class)aClass
165 {
166  var theClass = self;
167 
168  for (; theClass; theClass = theClass.super_class)
169  if (theClass === aClass)
170  return YES;
171 
172  return NO;
173 }
174 
179 - (BOOL)isKindOfClass:(Class)aClass
180 {
181  return [isa isSubclassOfClass:aClass];
182 }
183 
184 + (BOOL)isKindOfClass:(Class)aClass
185 {
186  return [self isSubclassOfClass:aClass];
187 }
188 
193 - (BOOL)isMemberOfClass:(Class)aClass
194 {
195  return self.isa === aClass;
196 }
197 
198 + (BOOL)isMemberOfClass:(Class)aClass
199 {
200  return self === aClass;
201 }
202 
207 - (BOOL)isProxy
208 {
209  return NO;
210 }
211 
212 // Testing class functionality
218 + (BOOL)instancesRespondToSelector:(SEL)aSelector
219 {
220  return !!class_getInstanceMethod(self, aSelector);
221 }
222 
228 - (BOOL)respondsToSelector:(SEL)aSelector
229 {
230  // isa is isa.isa in class case.
231  return !!class_getInstanceMethod(isa, aSelector);
232 }
233 
239 - (BOOL)implementsSelector:(SEL)aSelector
240 {
241  var methods = class_copyMethodList(isa),
242  count = methods.length;
243 
244  while (count--)
245  if (method_getName(methods[count]) === aSelector)
246  return YES;
247 
248  return NO;
249 }
250 
251 // Obtaining method information
252 
258 - (IMP)methodForSelector:(SEL)aSelector
259 {
260  return class_getMethodImplementation(isa, aSelector);
261 }
262 
268 + (IMP)instanceMethodForSelector:(SEL)aSelector
269 {
270  return class_getMethodImplementation(self, aSelector);
271 }
272 
278 - (CPMethodSignature)methodSignatureForSelector:(SEL)aSelector
279 {
280  // FIXME: We need to implement method signatures.
281  return nil;
282 }
283 
284 // Describing objects
289 {
290  return "<" + class_getName(isa) + " 0x" + [CPString stringWithHash:[self UID]] + ">";
291 }
292 
294 {
295  return class_getName(isa);
296 }
297 
298 // Sending Messages
304 - (id)performSelector:(SEL)aSelector
305 {
306  return objj_msgSend(self, aSelector);
307 }
308 
315 - (id)performSelector:(SEL)aSelector withObject:(id)anObject
316 {
317  return objj_msgSend(self, aSelector, anObject);
318 }
319 
327 - (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject
328 {
329  return objj_msgSend(self, aSelector, anObject, anotherObject);
330 }
331 
338 - (id)performSelector:(SEL)aSelector withObjects:(id)anObject, ...
339 {
340  var params = [self, aSelector].concat(Array.prototype.slice.apply(arguments, [3]));
341  return objj_msgSend.apply(this, params);
342 }
343 
344 - (id)forwardingTargetForSelector:(SEL)aSelector
345 {
346  return nil;
347 }
348 
349 // Forwarding Messages
356 - (void)forwardInvocation:(CPInvocation)anInvocation
357 {
358  [self doesNotRecognizeSelector:[anInvocation selector]];
359 }
360 
361 // Error Handling
367 - (void)doesNotRecognizeSelector:(SEL)aSelector
368 {
369  [CPException raise:CPInvalidArgumentException reason:
370  (class_isMetaClass(isa) ? "+" : "-") + " [" + [self className] + " " + aSelector + "] unrecognized selector sent to " +
371  (class_isMetaClass(isa) ? "class " + class_getName(isa) : "instance 0x" + [CPString stringWithHash:[self UID]])];
372 }
373 
374 // Archiving
383 - (id)awakeAfterUsingCoder:(CPCoder)aCoder
384 {
385  return self;
386 }
387 
393 {
394  return [self classForCoder];
395 }
396 
402 {
403  return [self class];
404 }
405 
411 - (id)replacementObjectForArchiver:(CPArchiver)anArchiver
412 {
413  return [self replacementObjectForCoder:anArchiver];
414 }
415 
421 - (id)replacementObjectForKeyedArchiver:(CPKeyedArchiver)anArchiver
422 {
423  return [self replacementObjectForCoder:anArchiver];
424 }
425 
431 - (id)replacementObjectForCoder:(CPCoder)aCoder
432 {
433  return self;
434 }
435 
440 + (void)setVersion:(int)aVersion
441 {
442  class_setVersion(self, aVersion);
443 }
444 
448 + (int)version
449 {
450  return class_getVersion(self);
451 }
452 
453 // Scripting (?)
458 {
459  // FIXME: Why doesn't this work in KVO???
460  // return class_getName([self class]);
461  return isa.name;
462 }
463 
464 // Extras
470 {
471  return self;
472 }
473 
477 - (unsigned)hash
478 {
479  return [self UID];
480 }
481 
483 {
484  if (typeof self._UID === "undefined")
485  self._UID = objj_generateObjectUID();
486 
487  return _UID + "";
488 }
489 
494 - (BOOL)isEqual:(id)anObject
495 {
496  return self === anObject || [self UID] === [anObject UID];
497 }
498 
503 - (id)retain
504 {
505  return self;
506 }
507 
511 - (void)release
512 {
513 }
514 
518 - (id)self
519 {
520  return self;
521 }
522 
526 - (Class)superclass
527 {
528  return isa.super_class;
529 }
530 
531 @end
532 
533 function CPDescriptionOfObject(anObject)
534 {
535  if (anObject.isa)
536  {
537  if ([anObject isKindOfClass:CPString])
538  return '@"' + [anObject description] + '"';
539  return [anObject description];
540  }
541 
542  if (typeof(anObject) !== "object")
543  return String(anObject);
544 
545  var desc = "JSObject\n{\n";
546 
547  for (var property in anObject)
548  {
549  if (anObject.hasOwnProperty(property))
550  desc += " " + property + ": " + CPDescriptionOfObject(anObject[property]) + "\n";
551  }
552  desc += "}";
553 
554  return desc.split('\n').join("\n\t");
555 }