OSDN Git Service

3a5bcb31688c1336960e0078351871357cc3a727
[pf3gnuchains/gcc-fork.git] / libobjc / Object.m
1 /* The implementation of class Object for Objective-C.
2    Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14 License for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 <http://www.gnu.org/licenses/>.  */
24
25 #include "objc-private/common.h"
26 #include <stdarg.h>
27 #include <errno.h>
28 #include "objc/Object.h"
29 #include "objc/Protocol.h"
30 #include "objc/objc-api.h"
31
32 @implementation Object
33
34 + initialize
35 {
36   return self;
37 }
38
39 - init
40 {
41   return self;
42 }
43
44 + new
45 {
46   return [[self alloc] init];
47 }
48
49 + alloc
50 {
51   return class_create_instance(self);
52 }
53
54 - free
55 {
56   return object_dispose(self);
57 }
58
59 - copy
60 {
61   return [[self shallowCopy] deepen];
62 }
63
64 - shallowCopy
65 {
66   return object_copy(self);
67 }
68
69 - deepen
70 {
71   return self;
72 }
73
74 - deepCopy
75 {
76   return [self copy];
77 }
78
79 - (Class)class
80 {
81   return object_get_class(self);
82 }
83
84 - (Class)superClass
85 {
86   return object_get_super_class(self);
87 }
88
89 - (MetaClass)metaClass
90 {
91   return object_get_meta_class(self);
92 }
93
94 - (const char *)name
95 {
96   return object_get_class_name(self);
97 }
98
99 - self
100 {
101   return self;
102 }
103
104 - (unsigned int)hash
105 {
106   return (size_t)self;
107 }
108
109 - (BOOL)isEqual:anObject
110 {
111   return self==anObject;
112 }
113
114 - (int)compare:(id)anotherObject;
115 {
116   if ([self isEqual:anotherObject])
117     return 0;
118   // Ordering objects by their address is pretty useless, 
119   // so subclasses should override this is some useful way.
120   else if ((id)self > anotherObject)
121     return 1;
122   else 
123     return -1;
124 }
125
126 - (BOOL)isMetaClass
127 {
128   return NO;
129 }
130
131 - (BOOL)isClass
132 {
133   return object_is_class(self);
134 }
135
136 - (BOOL)isInstance
137 {
138   return object_is_instance(self);
139 }
140
141 - (BOOL)isKindOf:(Class)aClassObject
142 {
143   Class class;
144
145   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
146     if (class==aClassObject)
147       return YES;
148   return NO;
149 }
150
151 - (BOOL)isMemberOf:(Class)aClassObject
152 {
153   return self->isa==aClassObject;
154 }
155
156 - (BOOL)isKindOfClassNamed:(const char *)aClassName
157 {
158   Class class;
159
160   if (aClassName!=NULL)
161     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
162       if (!strcmp(class_get_class_name(class), aClassName))
163         return YES;
164   return NO;
165 }
166
167 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
168 {
169   return ((aClassName!=NULL)
170           &&!strcmp(class_get_class_name(self->isa), aClassName));
171 }
172
173 + (BOOL)instancesRespondTo:(SEL)aSel
174 {
175   return class_get_instance_method(self, aSel)!=METHOD_NULL;
176 }
177
178 - (BOOL)respondsTo:(SEL)aSel
179 {
180   return ((object_is_instance(self)
181            ?class_get_instance_method(self->isa, aSel)
182            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
183 }
184
185 + (IMP)instanceMethodFor:(SEL)aSel
186 {
187   return method_get_imp(class_get_instance_method(self, aSel));
188 }
189
190 // Indicates if the receiving class or instance conforms to the given protocol
191 // not usually overridden by subclasses
192 //
193 // Modified 9/5/94 to always search the class object's protocol list, rather
194 // than the meta class.
195
196 + (BOOL) conformsTo: (Protocol*)aProtocol
197 {
198   size_t i;
199   struct objc_protocol_list* proto_list;
200   id parent;
201
202   for (proto_list = ((Class)self)->protocols;
203        proto_list; proto_list = proto_list->next)
204     {
205       for (i=0; i < proto_list->count; i++)
206       {
207         if ([proto_list->list[i] conformsTo: aProtocol])
208           return YES;
209       }
210     }
211
212   if ((parent = [self superClass]))
213     return [parent conformsTo: aProtocol];
214   else
215     return NO;
216 }
217
218 - (BOOL) conformsTo: (Protocol*)aProtocol
219 {
220   return [[self class] conformsTo:aProtocol];
221 }
222
223 - (IMP)methodFor:(SEL)aSel
224 {
225   return (method_get_imp(object_is_instance(self)
226                          ?class_get_instance_method(self->isa, aSel)
227                          :class_get_class_method(self->isa, aSel)));
228 }
229
230 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
231 {
232   return ((struct objc_method_description *)
233            class_get_instance_method(self, aSel));
234 }
235
236 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
237 {
238   return ((struct objc_method_description *)
239            (object_is_instance(self)
240             ?class_get_instance_method(self->isa, aSel)
241             :class_get_class_method(self->isa, aSel)));
242 }
243
244 - perform:(SEL)aSel
245 {
246   IMP msg = objc_msg_lookup(self, aSel);
247   if (!msg)
248     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
249   return (*msg)(self, aSel);
250 }
251
252 - perform:(SEL)aSel with:anObject
253 {
254   IMP msg = objc_msg_lookup(self, aSel);
255   if (!msg)
256     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
257   return (*msg)(self, aSel, anObject);
258 }
259
260 - perform:(SEL)aSel with:anObject1 with:anObject2
261 {
262   IMP msg = objc_msg_lookup(self, aSel);
263   if (!msg)
264     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
265   return (*msg)(self, aSel, anObject1, anObject2);
266 }
267
268 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
269 {
270   (void) argFrame; /* UNUSED */
271   return (retval_t)[self doesNotRecognize: aSel];
272 }
273
274 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
275 {
276   return objc_msg_sendv(self, aSel, argFrame);
277 }
278
279 + poseAs:(Class)aClassObject
280 {
281   return class_pose_as(self, aClassObject);
282 }
283
284 - (Class)transmuteClassTo:(Class)aClassObject
285 {
286   if (object_is_instance(self))
287     if (class_is_class(aClassObject))
288       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
289         if ([self isKindOf:aClassObject])
290           {
291             Class old_isa = isa;
292             isa = aClassObject;
293             return old_isa;
294           }
295   return nil;
296 }
297
298 - subclassResponsibility:(SEL)aSel
299 {
300   return [self error:"subclass should override %s", sel_get_name(aSel)];
301 }
302
303 - notImplemented:(SEL)aSel
304 {
305   return [self error:"method %s not implemented", sel_get_name(aSel)];
306 }
307
308 - shouldNotImplement:(SEL)aSel
309 {
310   return [self error:"%s should not implement %s", 
311                      object_get_class_name(self), sel_get_name(aSel)];
312 }
313
314 - doesNotRecognize:(SEL)aSel
315 {
316   return [self error:"%s does not recognize %s",
317                      object_get_class_name(self), sel_get_name(aSel)];
318 }
319
320 - error:(const char *)aString, ...
321 {
322 #define FMT "error: %s (%s)\n%s\n"
323   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
324             +((aString!=NULL)?strlen((char*)aString):0)+8)];
325   va_list ap;
326
327   sprintf(fmt, FMT, object_get_class_name(self),
328                     object_is_instance(self)?"instance":"class",
329                     (aString!=NULL)?aString:"");
330   va_start(ap, aString);
331   objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
332   va_end(ap);
333   return nil;
334 #undef FMT
335 }
336
337 + (int)version
338 {
339   return class_get_version(self);
340 }
341
342 + setVersion:(int)aVersion
343 {
344   class_set_version(self, aVersion);
345   return self;
346 }
347 @end
348
349 /* The following methods were deprecated in GCC 4.6.0 and will be
350    removed in the next GCC release.
351 */
352
353 @implementation Object (Deprecated)
354
355 + (int)streamVersion: (TypedStream*)aStream
356 {
357   if (aStream->mode == OBJC_READONLY)
358     return objc_get_stream_class_version (aStream, self);
359   else
360     return class_get_version (self);
361 }
362
363 // These are used to write or read the instance variables 
364 // declared in this particular part of the object.  Subclasses
365 // should extend these, by calling [super read/write: aStream]
366 // before doing their own archiving.  These methods are private, in
367 // the sense that they should only be called from subclasses.
368
369 - read: (TypedStream*)aStream
370 {
371   (void) aStream; /* UNUSED */
372   // [super read: aStream];  
373   return self;
374 }
375
376 - write: (TypedStream*)aStream
377 {
378   (void) aStream; /* UNUSED */
379   // [super write: aStream];
380   return self;
381 }
382
383 - awake
384 {
385   // [super awake];
386   return self;
387 }
388
389 @end