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