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