ClassClass.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel */
40 /* */
41 /* Primitive Class Class */
42 /* */
43 /******************************************************************************/
44 
45 #include <stdarg.h>
46 #include <string.h>
47 #include "RexxCore.h"
48 #include "StringClass.hpp"
49 #include "ListClass.hpp"
50 #include "TableClass.hpp"
51 #include "DirectoryClass.hpp"
52 #include "ArrayClass.hpp"
53 #include "SupplierClass.hpp"
54 #include "ClassClass.hpp"
55 #include "MethodClass.hpp"
56 #include "RexxActivity.hpp"
57 #include "ActivityManager.hpp"
58 #include "ProtectedObject.hpp"
59 #include "WeakReferenceClass.hpp"
60 #include "PackageClass.hpp"
61 
62 
63 // singleton class instance
65 
66 
67 void RexxClass::live(size_t liveMark)
68 /******************************************************************************/
69 /* Function: Normal garbage collection live marking */
70 /******************************************************************************/
71 {
72  memory_mark(this->objectVariables);
73  memory_mark(this->id);
77  memory_mark(this->baseClass);
78  memory_mark(this->metaClass);
83  memory_mark(this->subClasses);
84  memory_mark(this->package);
85 }
86 
87 void RexxClass::liveGeneral(int reason)
88 /******************************************************************************/
89 /* Function: Generalized object marking */
90 /******************************************************************************/
91 {
92  // Inspired by ooRexx5, but the approach is different...
93  // Instead of assigning package = TheRexxPackage when reason == PREPARINGIMAGE (unsupported by ooRexx4)
94  // I mark the RexxClass instance as belonging to the RexxPackage, and will return TheRexxPackage when asking its package.
95  if (reason == SAVINGIMAGE) this->setInRexxPackage();
96 
97  memory_mark_general(this->objectVariables);
98  memory_mark_general(this->id);
110 }
111 
113 /******************************************************************************/
114 /* Function: Flatten an object */
115 /******************************************************************************/
116 {
117  ;
118 }
119 
121 /******************************************************************************/
122 /* Function: unflaatten an object */
123 /******************************************************************************/
124 {
125  return this;
126 }
127 
129 /******************************************************************************/
130 /* Function: Make a proxy object */
131 /******************************************************************************/
132 {
133 
134  /* Following code is pulled from */
135  /* object_primitive, to get class id*/
136  /* as a string object. */
137  /* get the class id */
138  return new_proxy(this->id->getStringData());
139 }
140 
141 
142 /**
143  * Hash a class object. Because behaviors don't always get set
144  * up properly with this, we'll always use the primitive one for
145  * class objects.
146  *
147  * @return A "hashed hash" that can be used by the map collections.
148  */
150 {
151  // always, always, always return the hash value, which will be the
152  // hash value of our id string. This is important, since we need to
153  // have a hash value that will be the same before and after the image save
154  return getHashValue();
155 }
156 
157 
158 /**
159  * Get the primitive hash value of this String object.
160  *
161  * @return The calculated string hash for the string.
162  */
164 {
165  // always, always, always return the hash value, which will be the
166  // hash value of our id string. This is important, since we need to
167  // have a hash value that will be the same before and after the image save
168  return id->getHashValue();
169 }
170 
171 
173  RexxObject *other) /* other comparison object */
174 /******************************************************************************/
175 /* Function: Compare two classes */
176 /******************************************************************************/
177 {
178  return this->equal(other); /* this is direct object equality */
179 }
180 
182  RexxObject *other) /* other comparison object */
183 /******************************************************************************/
184 /* Function: Compare two class objects as a strict compare (==) */
185 /******************************************************************************/
186 {
187  /* If a non-copied (Primitive) */
188  /*behaviour Then we can directly */
189  /*call primitive method */
190  if (this->behaviour->isPrimitive())
191  {
192  /* can compare at primitive level */
193  return this->equal(other) == TheTrueObject;
194  }
195  else
196  {
197  ProtectedObject r;
198  /* other wise giveuser version a */
199  /*chance */
200  this->sendMessage(OREF_STRICT_EQUAL, other, r);
201  if ((RexxObject *)r == OREF_NULL)
202  {
204  }
205  return((RexxObject *)r)->truthValue(Error_Logical_value_method);
206  }
207 }
208 
210  RexxObject *other) /* other comparison object */
211 /******************************************************************************/
212 /* Function: Compare two classes */
213 /******************************************************************************/
214 {
215  requiredArgument(other, OREF_positional, ARG_ONE); /* must have the other argument */
216  /* this is direct object equality */
217 
218  /* comparing string/int/numstr to */
219  /* string/int/numstr? */
220  if ((this == TheStringClass || this == TheIntegerClass || this == TheNumberStringClass) &&
221  (other == (RexxObject *)TheStringClass || other == (RexxObject *)TheIntegerClass || other == (RexxObject *)TheNumberStringClass))
222  {
223  return TheTrueObject; /* YES, then equal.... */
224  }
225  else /* other wise, do a direct compare */
226  {
227  return((this == other) ? TheTrueObject: TheFalseObject);
228  }
229 }
230 
232  RexxObject *other) /* other comparison object */
233 /******************************************************************************/
234 /* Function: Compare two classes */
235 /******************************************************************************/
236 {
237  requiredArgument(other, OREF_positional, ARG_ONE); /* must have the other argument */
238  /* this is direct object equality */
239 
240  /* comparing string/int/numstr to */
241  /* string/int/numstr? */
242  if ((this == TheStringClass || this == TheIntegerClass || this == TheNumberStringClass) &&
243  (other == (RexxObject *)TheStringClass || other == (RexxObject *)TheIntegerClass || other == (RexxObject *)TheNumberStringClass))
244  {
245  return TheFalseObject; /* YES, then equal.... */
246  }
247  else /* other wise, do a direct compare */
248  {
249  return((this != other) ? TheTrueObject: TheFalseObject);
250  }
251 }
252 
254 /*****************************************************************************/
255 /* Function: To check if class_info MIXIN has been set */
256 /*****************************************************************************/
257 {
258  /* return true/false indicator */
259  return this->isMixinClass() ? TheTrueObject : TheFalseObject;
260 }
261 
262 /**
263  * Test if a class can be used as a metaclass
264  *
265  * @return True if this is a metaclass, False if not.
266  */
268 {
269  return booleanObject(isMetaClass());
270 }
271 
272 
273 /**
274  * Test if this class is marked as abstract
275  *
276  * @return True if this is abstract, false if not
277  */
279 {
280  return booleanObject(isAbstract());
281 }
282 
283 
285 /*****************************************************************************/
286 /* Function: Return the ID for the class */
287 /*****************************************************************************/
288 {
289  return this->id;
290 }
291 
293 /*****************************************************************************/
294 /* Function: Set a class as a Rexx defined class */
295 /*****************************************************************************/
296 {
297  this->classFlags |= REXX_DEFINED; /* flag the class */
298  return OREF_NULL;
299 }
300 
302 /*****************************************************************************/
303 /* Function: Return the classes base class */
304 /*****************************************************************************/
305 {
306  return this->baseClass; /* return the base class for this */
307 }
308 
310 /*****************************************************************************/
311 /* Function: return the classes metaclass */
312 /*****************************************************************************/
313 {
314  if (this->isPrimitiveClass()) /* primitive class? */
315  {
316  return TheClassClass; /* this is always .class */
317  }
318  else /* return first member of the list */
319  {
320  return(RexxClass *)this->metaClass->get(1);
321  }
322 }
323 
325  RexxBehaviour *b) /* new instance behaviour */
326 /*****************************************************************************/
327 /* Function: Give a class a new instance behaviour */
328 /*****************************************************************************/
329 {
330  OrefSet(this, this->instanceBehaviour, b);
331 }
332 
334 /*****************************************************************************/
335 /* Function: Return the first superclass in the superclass list */
336 /*****************************************************************************/
337 {
338  // object has no superclasses
339  if (this == TheObjectClass)
340  {
341  return (RexxClass *)TheNilObject;
342  }
343  // get the first item from the immediate list.
344  return (RexxClass *)this->instanceSuperClasses->get(1);
345 }
346 
347 
349 /*****************************************************************************/
350 /* Function: Return an array of the superclasses */
351 /*****************************************************************************/
352 {
353  /* return a copy of the list */
354  return (RexxArray *)this->instanceSuperClasses->copy();
355 }
356 
357 
359 /*****************************************************************************/
360 /* Function: Return an array of the subclasses */
361 /*****************************************************************************/
362 {
363  // remove any gc classes from the list now, and return the array
364  return subClasses->weakReferenceArray();
365 }
366 
368 /*****************************************************************************/
369 /* Function: Add a subclass to a class */
370 /*****************************************************************************/
371 {
372  // wrap a weak reference around the subclass
373  WeakReference *ref = new WeakReference(subClass);
374  // add this to the front of the subclass list
375  subClasses->addFirst((RexxObject *)ref);
376 }
377 
379  RexxTable *newMethods) /* methods to add */
380 /*****************************************************************************/
381 /* Function: Add a table of methods to a primitive class behaviour */
382 /*****************************************************************************/
383 {
384  /* loop through the list of methods */
385  for (HashLink i = newMethods->first(); newMethods->available(i); i = newMethods->next(i))
386  {
387  /* get the method name */
388  RexxString *method_name = (RexxString *)newMethods->index(i);
389  /* add this method to the classes */
390  /* class behaviour */
391 
392  // if this is the Nil object, that's an override. Make it OREF_NULL.
393  RexxObject *_method = (RexxMethod *)newMethods->value(i);
394  if (_method == TheNilObject)
395  {
396  _method = OREF_NULL;
397  }
398 
399  this->behaviour->define(method_name, OREF_NULL);
400  }
401 }
402 
404 /******************************************************************************/
405 /* Function: retrieve a classes default name value */
406 /******************************************************************************/
407 {
408  RexxString *defaultname = this->id; /* use the id directly */
409  /* prefix with "The" */
410  defaultname = defaultname->concatToCstring("The ");
411  ProtectedObject p(defaultname);
412  /* add on "class" */
413  defaultname = defaultname->concatWithCstring(" class");
414  return defaultname; /* return that value */
415 }
416 
418 /*****************************************************************************/
419 /* Function: Return the instance behaviour's method dictionary */
420 /*****************************************************************************/
421 {
422  /* get the method dictionary */
423  RexxTable *methodTable = this->instanceBehaviour->getMethodDictionary();
424  if (methodTable == OREF_NULL) /* no methods defined yet? */
425  {
426  return new_table(); /* create a new method table */
427  }
428  else
429  {
430  /* just copy the method dictionary */
431  return(RexxTable *)methodTable->copy();
432  }
433 }
434 
436 /*****************************************************************************/
437 /* Function: Return the class behaviour's method dictionary */
438 /*****************************************************************************/
439 {
440  /* get the method dictionary */
441  RexxTable *methodTable = this->behaviour->getMethodDictionary();
442  if (methodTable == OREF_NULL) /* no methods defined yet? */
443  {
444  return new_table(); /* create a new method table */
445  }
446  else
447  {
448  /* just copy the method dictionary */
449  return(RexxTable *)methodTable->copy();
450  }
451 }
452 
453 
454 /**
455  * Initialize a base Rexx class.
456  *
457  * @param restricted Whether we should turn the RexxRestricted flag on at this time.
458  * Some classes get additional customization after initial
459  * creation, so we delay setting this attribute until the
460  * class is fully constructed.
461  */
462 void RexxClass::subClassable(bool restricted)
463 {
464  /* get a copy of the class instance */
465  /* behaviour mdict before the merge */
466  /* with OBJECT. This unmerged mdict */
467  /* is kept in this class's */
468  /* class_instance_mdict field. */
470  /* Add OBJECT to the behaviour scope */
471  /* table */
473  if (this != TheObjectClass) /* if this isn't the OBJECT class */
474  {
475  /* Add OBJECT to the behaviour scope */
476  /* table */
478  /* and merge this class's instance */
479  /* behaviour with that of OBJECT's */
481  }
482  /* add self to the scope table */
483  this->instanceBehaviour->addScope(this);
484  /* get a copy of the class behaviour */
485  /* mdict before the merge with the */
486  /* CLASS instance behaviour. This */
487  /* unmerged mdict is kept in the */
488  /* class_mdict field */
490  /* The merge of the mdict's is order */
491  /* specific. By processing OBJECT */
492  /* first then CLASS and then the */
493  /* rest of the subclassable classes */
494  /* the mdict's will be set up */
495  /* correctly. */
496  /* In this way merging the CLASS */
497  /* behaviour will only be the CLASS */
498  /* instance methods when OBJECT is */
499  /* processed, but will be CLASS's */
500  /* and OBJECT's after CLASS is */
501  /* processed */
503  /* now add the scope levels to this */
504  /* class behaviour */
505  /* If this isn't OBJECT put OBJECT */
506  /* in first */
507  if (this != TheObjectClass)
508  {
510  }
511  /* if this is OBJECT - merge the */
512  /* object instance methods with the */
513  /* object class methods */
514  else
515  {
517  /* and put them into the class mdict */
518  /* so all the classes will inherit */
520  }
521  /* if this isn't CLASS put CLASS in */
522  /* next */
523  if (this != TheClassClass)
524  {
526  }
527  this->behaviour->addScope(this); /* put self into the scope table */
528  /* That finishes the class behaviour */
529  /* initialization. */
530  /* Now fill in the state data */
531 
532  if (TheObjectClass != this )
533  {
534  /* set up the new metaclass list */
535  OrefSet(this, this->metaClass, new_array(TheClassClass));
536  /* the metaclass mdict list */
537  OrefSet(this, this->metaClassMethodDictionary, new_array(TheClassClass->instanceMethodDictionary->copy()));
538  /* and the metaclass scopes list */
539  OrefSet(this, this->metaClassScopes, (RexxIdentityTable *)TheClassClass->behaviour->getScopes()->copy());
540  }
541 
542  /* The Baseclass for non-mixin classes*/
543  /* is self */
544  OrefSet(this, this->baseClass, this);
545  /* The class superclasses list for */
546  /* OBJECT is an empty list. */
547  OrefSet(this, this->classSuperClasses, new_array((size_t)0));
548  /* as is the instance superclasses */
549  /* list. */
550  OrefSet(this, this->instanceSuperClasses, new_array((size_t)0));
551  // create the subclasses list
552  OrefSet(this, this->subClasses, new_list());
553  if (this != TheObjectClass) /* not .object? */
554  {
555  /* add object to the list */
557  /* The instance superclasses for all */
558  /* except OBJECT is OBJECT */
560  /* and for OBJECT we need to add all */
561  /* the other classes */
562  /* except integer and numberstring */
563  if (this != TheIntegerClass && this != TheNumberStringClass)
564  {
565  TheObjectClass->addSubClass(this);
566  }
567  }
568  /* and point the instance behaviour */
569  /* back to this class */
570  this->instanceBehaviour->setOwningClass(this);
571  /* and the class behaviour to CLASS */
573  /* these are primitive classes */
574  this->classFlags |= PRIMITIVE_CLASS;
575 
576  if (this == TheClassClass) /* mark CLASS as a meta class */
577  {
578  this->setMetaClass();
579  }
580 }
581 
582 
583 /**
584  * Initialize a base Rexx class that inherits from a primitive
585  * class other than Object.
586  *
587  * @param superClass The immediate superclass of the created
588  * class.
589  * @param restricted Whether we should turn the RexxRestricted flag on at this time.
590  * Some classes get additional customization after initial
591  * creation, so we delay setting this attribute until the
592  * class is fully constructed.
593  */
594 void RexxClass::subClassable(RexxClass *superClass, bool restricted)
595 {
596  // get a copy of the class instance behaviour mdict before the merge
597  // with OBJECT. This unmerged mdict is kept in this class's
598  // class_instance_mdict field.
600 
601  // set up the superclass/subclass relationships
602  OrefSet(this, this->classSuperClasses, new_array(superClass));
603  OrefSet(this, this->instanceSuperClasses, new_array(superClass));
604  // create the subclasses list
605  OrefSet(this, this->subClasses, new_list());
606  // and add this as a subclass to our superclass
607  superClass->addSubClass(this);
608 
609  // create the merged method dictionary for the instancebehavior
610  // and update all of the scopes.
612 
613  /* add self to the scope table */
614  this->instanceBehaviour->addScope(this);
615 
616  // get a copy of the class behaviour mdict before the merge with the
617  // CLASS instance behaviour. This unmerged mdict is kept in the
618  // class_mdict field
620  // The merge of the mdict's is order specific. By processing OBJECT
621  // first then CLASS and then the rest of the subclassable classes
622  // the mdict's will be set up correctly.In this way merging the CLASS
623  // behaviour will only be the CLASS instance methods when OBJECT is
624  // processed, but will be CLASS's and OBJECT's after CLASS is
625  // processed */
627  // now add the scope levels to this class behaviour
629  // add the class scope levels
631  // and finally the new class.
632  this->behaviour->addScope(this);
633 
634  // now fill in some state data for the class object.
635  // set up the new metaclass list
636  OrefSet(this, this->metaClass, new_array(TheClassClass));
637  // the metaclass mdict list
638  OrefSet(this, this->metaClassMethodDictionary, new_array(TheClassClass->instanceMethodDictionary->copy()));
639  // and the metaclass scopes list
640  OrefSet(this, this->metaClassScopes, (RexxIdentityTable *)TheClassClass->behaviour->getScopes()->copy());
641 
642  // The Baseclass for non-mixin classes is self
643  OrefSet(this, this->baseClass, this);
644  // and point the instance behaviour back to this class
645  this->instanceBehaviour->setOwningClass(this);
646  // and the class behaviour to CLASS
648  // these are primitive classes
649  this->classFlags |= PRIMITIVE_CLASS;
650 }
651 
652 
654  RexxString * method_name, /*define method name */
655  RexxMethod *method_object) /* returned method object */
656 /*****************************************************************************/
657 /* Function: Define an instance method on this class object */
658 /*****************************************************************************/
659 {
660 #if 0
661  /* check if this is a rexx class */
662  if ( this->isRexxDefined())
663  {
664  /* report as a nomethod condition */
666  }
667 #endif
668  /* make sure there is at least one */
669  /* parameter */
670  method_name = stringArgument(method_name, OREF_positional, ARG_ONE)->upper();
671  ProtectedObject p_method_name(method_name);
672  ProtectedObject p_method_object(method_object);
673  if ( OREF_NULL == method_object) /* 2nd arg omitted? */
674  {
675  /* Yes, remove all message with this */
676  /* name from our instanceMdict */
677  /* (method lookup) */
678  /* done by defining the method */
679  /* to be .nil at this class level, so*/
680  /* when message lookup is attempted */
681  /* we get .nil, telling us not found */
682  method_object = (RexxMethod *)TheNilObject;
683  }
684  /* not a method type already? */
685  /* and not TheNilObject */
686  else if (TheNilObject != method_object && !isOfClass(Method, method_object))
687  {
688  /* make one from a string */
689  method_object = RexxMethod::newMethodObject(method_name, method_object, IntegerTwo, OREF_NULL);
690  }
691  if (TheNilObject != method_object) /* if the method is not TheNilObject */
692  {
693  /* set the scope of the method to self*/
694  method_object = method_object->newScope(this);
695  /* Installing UNINIT? */
696  if (method_name->strCompare(CHAR_UNINIT))
697  {
698  this->setHasUninitDefined(); /* and turn on uninit if so */
699  }
700  }
701  p_method_object = method_object;
702 
703  /* make a copy of the instance */
704  /* behaviour so any previous objects */
705  /* aren't enhanced */
706  //JLF OrefSet(this, this->instanceBehaviour, (RexxBehaviour *)this->instanceBehaviour->copy());
707  /* add method to the instance mdict */
708  this->instanceMethodDictionary->stringPut((RexxObject *)method_object, method_name);
709  /* any subclasses that we have need */
710  /* to redo their instance behaviour */
711  /* this also updates our own */
712  this->updateInstanceSubClasses(); /* behaviour table */
713 
714  // .nil not updated when defining a method on the class Object.
715  // probably because the class of .nil is the special class RexxNilObject...
716  // Use the same technique than in setup.cpp: call defMethod
717  if (this == TheObjectClass)
718  {
719  TheNilObject->defMethod(method_name, method_object);
720  }
721 
722  return OREF_NULL; /* returns nothing */
723 }
724 
726  RexxTable * newMethods) /* new table of methods to define */
727 /*****************************************************************************/
728 /* Function: Define instance methods on this class object */
729 /*****************************************************************************/
730 {
731  RexxString * index; /* method name */
732  /* loop thru the methods setting the */
733  /* method scopes to SELF and then */
734  /* adding them to SELF's instance */
735  /* mdict */
736  for (HashLink i = newMethods->first(); (index = (RexxString *)newMethods->index(i)) != OREF_NULL; i = newMethods->next(i))
737  {
738  /* get the method */
739  RexxMethod *newMethod = (RexxMethod *)newMethods->value(i);
740  if (isOfClass(Method, newMethod)) /* if this is a method object */
741  {
742  newMethod->setScope(this); /* change the scope */
743  }
744  /* add method to the instance mdict */
745  this->instanceMethodDictionary->stringPut(newMethod, index);
746  /* Installing UNINIT? */
747  if (index->strCompare(CHAR_UNINIT))
748  {
749  this->setHasUninitDefined(); /* and turn on uninit if so */
750  }
751  }
752  /* create the instance behaviour from */
753  /* the instance superclass list */
757 
758  return OREF_NULL; /* returns nothing */
759 }
760 
761 /**
762  * special method to allow a class method to be added
763  * to a primitive class during image build.
764  * New JLF : also used for ::EXTENSION
765  *
766  * @param method_name
767  * The name of the new method.
768  * @param newMethod The method object to add
769  *
770  * @return always returns OREF_NULL
771  */
773 {
774  // validate the arguments
775  method_name = stringArgument(method_name, OREF_positional, ARG_ONE)->upper();
776  ProtectedObject p(method_name);
777  requiredArgument(newMethod, OREF_positional, ARG_TWO);
778  newMethod->newScope(this); // change the scope to the class // JLF newScope instead of setScope
779  /* now add this to the behaviour */
780  this->behaviour->getMethodDictionary()->stringPut(newMethod, method_name);
781  this->classMethodDictionary->stringAdd(newMethod, method_name);
782 
783  // propagate to all subclasses (JLF : don't know why it was not done, maybe not needed during image build ?)
784  RexxArray *subclass_list = this->getSubClasses();
785  ProtectedObject p2(subclass_list);
786  size_t subclass_list_size = subclass_list->size();
787  for (size_t i = 1; i <= subclass_list_size; i++)
788  {
789  RexxClass *subclass = (RexxClass *)subclass_list->get(i);
790  if (subclass == NULL) continue;
791  subclass->defineClassMethod(method_name, newMethod);
792  }
793 
794  return OREF_NULL; /* returns nothing */
795 }
796 
797 /**
798  * Remove a class method from a class and all of its class methods.
799  *
800  * @param method_name
801  * The target method name.
802  */
804 {
805  // remove from our behaviour
806  this->behaviour->deleteMethod(method_name);
807 
808  // propagate to all subclasses
809  RexxArray *subclass_list = getSubClasses();
810  ProtectedObject p(subclass_list);
811  size_t subclass_list_size = subclass_list->size();
812  for (size_t i = 1; i <= subclass_list_size; i++)
813  {
814  RexxClass *subclass = (RexxClass *)subclass_list->get(i);
815  if (subclass == NULL) continue;
816  subclass->removeClassMethod(method_name);
817  }
818 }
819 
820 
822  RexxString *method_name) /* deleted method name */
823 /*****************************************************************************/
824 /* Function: Delete an instance method on this class object */
825 /*****************************************************************************/
826 {
827  if (this->isRexxDefined()) /* check if this is a rexx class */
828  {
829  /* report as a nomethod condition */
831  }
832  /* and that it can be a string */
833  method_name = stringArgument(method_name, OREF_positional, ARG_ONE)->upper();
834  ProtectedObject p(method_name);
835  /* make a copy of the instance */
836  /* behaviour so any previous objects */
837  /* aren't enhanced */
838  //JLF OrefSet(this, this->instanceBehaviour, (RexxBehaviour *)this->instanceBehaviour->copy());
839  /* if there is a method to remove */
840  /* from the instance mdict */
841  /* remove it */
842  if (OREF_NULL != this->instanceMethodDictionary->remove(method_name))
843  {
844  /* and update our instance behaviour */
845  this->updateInstanceSubClasses(); /* along with our subclasses */
846  }
847  return OREF_NULL; /* returns nothing */
848 }
849 
851  RexxString *method_name)
852 /*****************************************************************************/
853 /* Function: Return the method object for the method name */
854 /*****************************************************************************/
855 {
856  /* make sure we have a proper name */
857  method_name = stringArgument(method_name, OREF_positional, ARG_ONE)->upper();
858  ProtectedObject p(method_name);
859  RexxMethod *method_object = (RexxMethod *)this->instanceBehaviour->getMethodDictionary()->stringGet(method_name);
860  /* check if it is in the mdict */
861  if ( OREF_NULL == method_object)
862  {
863  /* if not return an error */
864  reportException(Error_No_method_name, this, method_name);
865  }
866  return method_object; /* if it was - return the value */
867 }
868 
870  RexxClass *class_object) /* target class object */
871 /*****************************************************************************/
872 /* Function: If no qualification parameter entered */
873 /* return all the methods that an instance of this class */
874 /* will inherit */
875 /* If TheNilObject is the qualification parameter */
876 /* return just the methods introduced at this class scope */
877 /* For any other qualification parameter */
878 /* return just the methods introduced at that class scope */
879 /*****************************************************************************/
880 {
881  /* if no parameter specified */
882  /* return my behaviour mdict as a */
883  /* supplier object */
884  if (class_object == OREF_NULL)
885  {
887  }
888  /* if TheNilObject specified */
889  /* return my instance mdict as a */
890  /* supplier object */
891  if (class_object == TheNilObject)
892  {
893  return this->instanceMethodDictionary->supplier();
894  }
895  /* if not one of the above */
896  /* check if it is a superclass */
897  if (this->behaviour->checkScope(class_object))
898  {
899  /* let the class specified return */
900  /* it's own methods */
901  ProtectedObject r;
902  class_object->sendMessage(OREF_METHODS, TheNilObject, r);
903  return(RexxSupplier *)(RexxObject *)r;
904  }
905  /* or just return a null supplier */
906  return(RexxSupplier *)TheNullArray->supplier();
907 }
908 
910 /******************************************************************************/
911 /* Function: Update my behaviours and call each subclass to do the same */
912 /******************************************************************************/
913 {
914  /* start out the class mdict with */
915  /* a clear mdict and scopes tables */
917  this->behaviour->setScopes(OREF_NULL);
918  /* create the instance behaviour from*/
919  /* the instance superclass list */
923  // This time, we update the class behaviour
924  // after building the instance behaviour
925  // because the added methods may have an
926  // impact on metaclasses.
927  this->createClassBehaviour(this->behaviour);
928 
929  RexxArray *subClassList = this->getSubClasses(); /* get the subclasses list */
930  ProtectedObject p(subClassList);
931  /* loop thru the subclass doing the */
932  /* same for each of them */
933  size_t subClassList_size = subClassList->size();
934  for (size_t index = 1; index <= subClassList_size; index++)
935  {
936  /* get the next subclass */
937  RexxClass * subclass = (RexxClass *)subClassList->get(index);
938  if (subclass == NULL) continue;
939  /* and recursively update them */
941  }
942 }
943 
945 /******************************************************************************/
946 /* Function: Update my instance behaviour and have the subclasses do the same */
947 /******************************************************************************/
948 {
949  /* create the instance behaviour from*/
950  /* the instance superclass list */
954  RexxArray *subClassList = this->getSubClasses(); /* get the subclasses list */
955  ProtectedObject p(subClassList);
956  /* loop thru the subclass doing the */
957  /* same for each of them */
958  size_t subclass_list_size = subClassList->size();
959  for (size_t index = 1; index <= subclass_list_size /*subClassList->size()*/; index++)
960  {
961  /* get the next subclass */
962  RexxClass *subclass = (RexxClass *)subClassList->get(index);
963  if (subclass == NULL) continue;
964  /* recursively update these */
966  }
967 }
968 
970  RexxBehaviour *target_class_behaviour)
971 /*****************************************************************************/
972 /* Funcion: To call the superclasses and have them update this classes */
973 /* class behaviour mdict and scopes table */
974 /*****************************************************************************/
975 {
976  RexxClass * superclass; /* superclass being called */
977  RexxClass * metaclass; /* metaclass to use */
978 
979 
980  /* Call each of the superclasses in */
981  /* this superclass list starting from*/
982  /* the last to the first */
983  for (HashLink index = this->classSuperClasses->size(); index > 0; index--)
984  {
985  /* get the next superclass */
986  superclass = (RexxClass *)this->classSuperClasses->get(index);
987  /* if there is a superclass and */
988  /* it hasn't been added into this */
989  /* behaviour yet, call and have it */
990  /* add itself */
991  if (superclass != TheNilObject && !target_class_behaviour->checkScope(superclass))
992  {
993  superclass->createClassBehaviour(target_class_behaviour);
994  }
995  }
996  /* If this class mdict has not been */
997  /* merged into this target behaviour */
998  if (!target_class_behaviour->checkScope(this))
999  {
1000  if (TheObjectClass != this) /* if this isn't OBJECT */
1001  {
1002  // we only process the first item in the metaclass list, since it
1003  // will properly pull in the scopes for all of the rest, in the correct order.
1004  metaclass = (RexxClass *)this->metaClass->get(1);
1005  /* add which ever metaclasses have */
1006  /* not been added yet */
1007  if (metaclass != TheNilObject && !target_class_behaviour->checkScope(metaclass))
1008  {
1009  /* merge in the meta class mdict */
1010  target_class_behaviour->methodDictionaryMerge(metaclass->instanceBehaviour->getMethodDictionary());
1011  // now we need to merge in the scopes. For each metaclass, starting
1012  // from the bottom of the hierarchy down, merge in each of the scope
1013  // values.
1014  RexxArray *addedScopes = metaclass->behaviour->getScopes()->allAt(TheNilObject);
1015  ProtectedObject p(addedScopes);
1016 
1017  // these need to be processed in reverse order
1018  for (size_t i = addedScopes->size(); i > 0; i--)
1019  {
1020  RexxClass *scope = (RexxClass *)addedScopes->get(i);
1021  target_class_behaviour->mergeScope(scope);
1022  }
1023  }
1024  }
1025  /* only merge the mdict for CLASS */
1026  /* if this is a capable of being a */
1027  /* metaclass */
1028  if ((this != TheClassClass) || (this == TheClassClass && this->isMetaClass()))
1029  {
1030  /* Merge this class mdict with the */
1031  /* target behaviour class mdict */
1032  target_class_behaviour->methodDictionaryMerge(this->classMethodDictionary);
1033  }
1034  /* And update the target behaviour */
1035  /* scopes table with this class */
1036  if (this != TheClassClass && !target_class_behaviour->checkScope(this))
1037  {
1038  target_class_behaviour->addScope(this);
1039  }
1040  }
1041 }
1042 
1043 
1045  /* target behaviour to create */
1046  RexxBehaviour *target_instance_behaviour)
1047 /*****************************************************************************/
1048 /* Funcion: To call the superclasses and have them update this classes */
1049 /* instance behaviour mdict and scopes table */
1050 /*****************************************************************************/
1051 {
1052  /* Call each of the superclasses in */
1053  /* this superclass list starting from*/
1054  /* the last going to the first */
1055  for (HashLink index = this->instanceSuperClasses->size(); index > 0; index--)
1056  {
1057  /* get the next super class */
1058  RexxClass *superclass = (RexxClass *)this->instanceSuperClasses->get(index);
1059  /* if there is a superclass and */
1060  /* it hasn't been added into this */
1061  /* behaviour yet, call and have it */
1062  /* add itself */
1063  if (superclass != TheNilObject && !target_instance_behaviour->checkScope(superclass))
1064  {
1065  superclass->createInstanceBehaviour(target_instance_behaviour);
1066  }
1067  }
1068  /* If this class mdict has not been */
1069  /* merged into this target behaviour */
1070  if (!target_instance_behaviour->checkScope(this))
1071  {
1072  /* Merge this class mdict with the */
1073  /* target behaviour class mdict */
1074  target_instance_behaviour->methodDictionaryMerge(this->instanceMethodDictionary);
1075  /* And update the target behaviour */
1076  /* scopes table with this class */
1077  target_instance_behaviour->addScope(this);
1078  }
1079 }
1080 
1081 
1082 /**
1083  * Merge the scopes from the superclasses into a target primitive class.
1084  *
1085  * @param target_instance_behaviour
1086  * The target behavior to update.
1087  */
1088 void RexxClass::mergeSuperClassScopes(RexxBehaviour *target_instance_behaviour)
1089 {
1090  // Call each of the superclasses in this superclass list starting from
1091  // the last going to the first
1092  for (HashLink index = this->instanceSuperClasses->size(); index > 0; index--)
1093  {
1094  RexxClass *superclass = (RexxClass *)this->instanceSuperClasses->get(index);
1095  // if there is a superclass and it hasn't been added into this
1096  // behaviour yet, call and have it add itself */
1097  if (superclass != TheNilObject && !target_instance_behaviour->checkScope(superclass))
1098  {
1099  superclass->mergeSuperClassScopes(target_instance_behaviour);
1100  }
1101  }
1102  // now add in the scope for this class, if still needed.
1103  if (!target_instance_behaviour->checkScope(this))
1104  {
1105  /* Merge this class mdict with the */
1106  /* target behaviour class mdict */
1107  target_instance_behaviour->merge(this->instanceBehaviour);
1108  /* And update the target behaviour */
1109  /* scopes table with this class */
1110  target_instance_behaviour->addScope(this);
1111  }
1112 }
1113 
1115  RexxTable *source_mdict, /* source method dictionary */
1116  RexxTable *target_mdict) /* target method dictionary */
1117 /*****************************************************************************/
1118 /* Function: Merge the source mdict methods into the target mdict after */
1119 /* getting copies of the methods with a new scope */
1120 /* After this merge the method search order will find the source */
1121 /* mdict methods prior to the target methods */
1122 /*****************************************************************************/
1123 {
1124  if (source_mdict == OREF_NULL) /* check for a source mdict */
1125  {
1126  return; /* there isn't anything to do */
1127  }
1128  /* just loop through the entries */
1129  for (HashLink i = source_mdict->first(); source_mdict->available(i); i = source_mdict->next(i))
1130  {
1131  /* get the method name */
1132  RexxString *method_name = REQUEST_STRING(source_mdict->index(i));
1133  ProtectedObject p(method_name);
1134  /* get the method */
1135  RexxMethod *method_instance = (RexxMethod *)source_mdict->value(i);
1136  /* add the method to the target mdict */
1137  target_mdict->stringAdd(method_instance, method_name);
1138  /* check if the method that was added */
1139  /* is the uninit method */
1140  if ( method_name->strCompare(CHAR_UNINIT))
1141  {
1142  this->setHasUninitDefined(); /* and turn on uninit if so */
1143  }
1144  }
1145 }
1146 
1148  RexxTable *sourceCollection, /* source method collection */
1149  RexxClass *scope ) /* required method scope */
1150 /*****************************************************************************/
1151 /* Function: Process a collection of methods that will be added to a class */
1152 /* as class methods, or will be added to an enhanced object. In */
1153 /* either case, this is an arbitrary collection of objects that */
1154 /* may need conversion into method objects and given a scope. */
1155 /*****************************************************************************/
1156 {
1157  RexxTable *newDictionary = new_table(); /* get a new table for this */
1158  ProtectedObject p(newDictionary);
1159  /* loop thru the supplier object */
1160  /* obtained from the source mdict */
1161  ProtectedObject p2;
1162  sourceCollection->sendMessage(OREF_SUPPLIERSYM, p2);
1163  RexxSupplier *supplier = (RexxSupplier *)(RexxObject *)p2;
1164  for (; supplier->available() == TheTrueObject; supplier->next())
1165  {
1166  /* get the method name (uppercased) */
1167  RexxString *method_name = REQUEST_STRING(supplier->index())->upper();
1168  ProtectedObject p(method_name);
1169  /* get the method */
1170  RexxMethod *newMethod = (RexxMethod *)supplier->value();
1171  /* if the method is not TheNilObject */
1172  if (newMethod != (RexxMethod *)TheNilObject)
1173  {
1174  /* and it isn't a primitive method */
1175  if (!isOfClass(Method, newMethod)) /* object */
1176  {
1177  /* make it into a method object */
1178  newMethod = RexxMethod::newMethodObject(method_name, newMethod, IntegerOne, OREF_NULL);
1179  newMethod->setScope(scope); /* and set the scope to the given */
1180  }
1181  else
1182  {
1183  /* if it is a primitive method object */
1184  /* let the newscope method copy it */
1185  newMethod = newMethod->newScope(scope);
1186  }
1187  }
1188  /* add the method to the target mdict */
1189  newDictionary->stringAdd(newMethod, method_name);
1190  }
1191  return newDictionary; /* and return the new version */
1192 }
1193 
1194 
1196  RexxClass *mixin_class, /* target class */
1197  RexxClass *position) /* target inherit position */
1198 /*****************************************************************************/
1199 /* Function: To add the mixin class (parameter one) to the superclass */
1200 /* hierarchy of the receiver class (this), at the last position */
1201 /* or the specified position (parameter two). */
1202 /*****************************************************************************/
1203 {
1204 #if 0
1205  /* make sure this isn't a rexx */
1206  if (this->isRexxDefined()) /* defined class being changed */
1207  {
1208  /* report as a nomethod condition */
1210  }
1211 #endif
1212  requiredArgument(mixin_class, OREF_positional, ARG_ONE); /* make sure it was passed in */
1213 
1214  /* check the mixin class is really a */
1215  /* good class for this */
1216  if (!mixin_class->isInstanceOf(TheClassClass) || !mixin_class->isMixinClass())
1217  {
1218  /* if it isn't raise an error */
1220  }
1221 
1222  /* if the mixin class is also the */
1223  if (this == mixin_class ) /* reciever class */
1224  {
1225  /* raise an error */
1227  }
1228  /* check that the mixin class is not */
1229  /* a superclass of the reciever */
1230  if (this->behaviour->checkScope(mixin_class))
1231  {
1232  /* if it is raise an error */
1234  }
1235  /* check if the reciever class is a */
1236  /* superclass of the mixin class */
1237  if (mixin_class->behaviour->checkScope(this))
1238  {
1239  /* if it is it's an error */
1241  }
1242 
1243  /* Now ensure the mixin class */
1244  /* baseclass is in the reciever's */
1245  /* class superclass hierarchy */
1246  if (!this->behaviour->checkScope(mixin_class->getBaseClass()))
1247  {
1248  /* if it isn't raise an error */
1249  reportException(Error_Execution_baseclass, this, mixin_class, mixin_class->getBaseClass());
1250  }
1251 
1252  /* and the reciever's */
1253  /* instance superclass hierarchy */
1254  if (!this->instanceBehaviour->checkScope(mixin_class->getBaseClass()))
1255  {
1256  /* if it isn't raise an error */
1257  reportException(Error_Execution_baseclass, this, mixin_class, mixin_class->getBaseClass());
1258  }
1259  if ( position == OREF_NULL ) /* if position was not specified */
1260  {
1261  /* insert the mixin class last in the*/
1262  /* reciever's superclasses list */
1263  this->classSuperClasses->addLast(mixin_class);
1264  this->instanceSuperClasses->addLast(mixin_class);
1265  }
1266  else /* if it was specified */
1267  {
1268  /* check that it's a valid superclass*/
1269  /* in the class superclasses list */
1270  /* and the reciever's */
1271  /* instance superclasses list */
1272  HashLink class_index = this->classSuperClasses->indexOf(position);
1273  HashLink instance_index = this->instanceSuperClasses->indexOf(position);
1274  if (class_index == 0 || instance_index == 0)
1275  {
1276  /* if it isn't raise an error */
1277  reportException(Error_Execution_uninherit, this, position);
1278  }
1279  /* insert the mixin class into the */
1280  /* superclasses list's */
1281  this->classSuperClasses->insertAfter(mixin_class, class_index);
1282  this->instanceSuperClasses->insertAfter(mixin_class, instance_index);
1283  }
1284 
1285  /* update the mixin class subclass */
1286  mixin_class->addSubClass(this); /* list to reflect this class */
1287  /* any subclasses that we have need */
1288  /* to redo their behaviour's */
1289  /* this also updates our own */
1290  /* behaviour tables. */
1291  this->updateSubClasses();
1292  /* If the mixin class has an uninit defined, the new class must have one, too */
1293  if (mixin_class->hasUninitDefined() || mixin_class->parentHasUninitDefined())
1294  {
1295  this->setParentHasUninitDefined();
1296  }
1297  return OREF_NULL; /* returns nothing */
1298 }
1299 
1301  RexxClass *mixin_class) /* target subclass to remove */
1302 /*****************************************************************************/
1303 /* Function: To remove a mixin class (parameter one) from the superclass */
1304 /* hierarchy of the receiver class (this). */
1305 /*****************************************************************************/
1306 {
1307  HashLink class_index; /* index for class superclasses list */
1308  HashLink instance_index; /* index for instance superclasses */
1309  /* make sure this isn't rexx defined */
1310  if (this->isRexxDefined()) /* class that is being changed */
1311  {
1312  /* report as a nomethod condition */
1314  }
1315  requiredArgument(mixin_class, OREF_positional, ARG_ONE); /* make sure it was passed in */
1316 
1317  /* check that the mixin class is a */
1318  /* superclass of the receiver class */
1319  /* and not the superclass */
1320  if ( ((class_index = this->classSuperClasses->indexOf(mixin_class)) > 1) &&
1321  ((instance_index = this->instanceSuperClasses->indexOf(mixin_class)) > 1))
1322  {
1323  /* and remove it */
1324  this->classSuperClasses->deleteItem(class_index);
1325  this->instanceSuperClasses->deleteItem(instance_index);
1326  }
1327  else
1328  {
1329  /* else raise an error */
1330  reportException(Error_Execution_uninherit, this, mixin_class);
1331  }
1332  /* update the mixin class subclass */
1333  /* list to not have this class */
1334  removeSubclass(mixin_class);
1335  /* any subclasses that we have need */
1336  /* to redo their behaviour's */
1337  /* this also updates our own behaviour*/
1338  this->updateSubClasses(); /* tables. */
1339  return OREF_NULL; /* returns nothing */
1340 }
1341 
1342 
1343 /**
1344  * Remove a subclass from the uninherit list after an uninherit
1345  * operation.
1346  *
1347  * @param c The class to remove.
1348  */
1350 {
1351  size_t index = subClasses->firstIndex();
1352  // scan the subclasses list looking for the removed class
1353  while (index != LIST_END)
1354  {
1355  WeakReference *ref = (WeakReference *)subClasses->getValue(index);
1356  RexxObject *sc = ref->get();
1357  if (sc == c)
1358  {
1359  subClasses->removeIndex(index);
1360  return;
1361  }
1362  index = subClasses->nextIndex(index);
1363  }
1364 }
1365 
1367  RexxObject **args, /* enhanced arguments */
1368  size_t argCount, /* the number of positional arguments*/
1369  size_t named_argCount) /* the number of named arguments */
1370 /*****************************************************************************/
1371 /* Function: Create a new object that is an instance of the receiver class */
1372 /* object that has had it's instance mdict enhanced. */
1373 /*****************************************************************************/
1374 {
1375  if (argCount == 0) /* make sure an arg was passed in */
1376  {
1377  /* if not report an error */
1379  }
1380  /* get the value of the arg */
1381  RexxTable *enhanced_instance_mdict = (RexxTable *)args[0];
1382  /* make sure it was a real value */
1383  requiredArgument(enhanced_instance_mdict, OREF_positional, ARG_ONE);
1384  /* subclass the reciever class */
1385  RexxClass *dummy_subclass = this->subclass(OREF_NULL, new_string("Enhanced Subclass"), OREF_NULL, OREF_NULL);
1386  ProtectedObject p(dummy_subclass);
1387  /* turn into a real method dictionary*/
1388  enhanced_instance_mdict = dummy_subclass->methodDictionaryCreate(enhanced_instance_mdict, (RexxClass *)TheNilObject);
1389  ProtectedObject p1(enhanced_instance_mdict);
1390  /* enhance the instance behaviour */
1391  dummy_subclass->methodDictionaryMerge(enhanced_instance_mdict, dummy_subclass->instanceMethodDictionary);
1392  /* and record the changes in behavior*/
1393  dummy_subclass->instanceBehaviour->setInstanceMethodDictionary(enhanced_instance_mdict);
1394  /* recreate the instance behaviour */
1396  dummy_subclass->instanceBehaviour->setScopes(OREF_NULL);
1397  dummy_subclass->createInstanceBehaviour(dummy_subclass->instanceBehaviour);
1398  ProtectedObject r;
1399  /* get an instance of the enhanced */
1400  /* subclass */
1401  dummy_subclass->sendMessage(OREF_NEW, args + 1, argCount - 1, named_argCount, r);
1402  RexxObject *enhanced_object = (RexxObject *)r;
1403  /* change the create_class in the */
1404  /* instance behaviour to point to the*/
1405  /* original class object */
1406  enhanced_object->behaviour->setOwningClass(this);
1407  /* remember it was enhanced */
1408  enhanced_object->behaviour->setEnhanced();
1409 
1410  return enhanced_object; /* send back the new improved version*/
1411 }
1412 
1413 /**
1414  * Create a mixinclass of a class directly from Rexx code.
1415  *
1416  * @param class_id The id of the created class.
1417  * @param meta_class The meta class to create this from.
1418  * @param enhancing_class_methods
1419  * Additional class methods.
1420  *
1421  * @return A created class object.
1422  */
1423 RexxClass *RexxClass::mixinClassRexx(RexxString *class_id, RexxClass *meta_class, RexxObject *enhancing_class_methods)
1424 {
1425  // just forward with no source object specified
1426  return mixinclass(OREF_NULL, class_id, meta_class, (RexxTable *)enhancing_class_methods);
1427 }
1428 
1429 
1431  PackageClass *package,
1432  RexxString * mixin_id, /* ID name of the class */
1433  RexxClass * meta_class, /* source meta class */
1434  /* extra class methods */
1435  RexxTable * enhancing_class_methods)
1436 /*****************************************************************************/
1437 /* Function: Create a new class object containng class and instance methods */
1438 /* to be used for multiple inheritance . */
1439 /*****************************************************************************/
1440 {
1441  /* call subclass with the parameters */
1442  RexxClass *mixin_subclass = this->subclass(package, mixin_id, meta_class, enhancing_class_methods);
1443  mixin_subclass->setMixinClass(); /* turn on the mixin info */
1444  /* change the base class to the base */
1445  /* class of the reciever */
1446  OrefSet(mixin_subclass, mixin_subclass->baseClass, this->baseClass);
1447  /* If the mixin's parent class has an uninit defined, the new mixin class must have one, too */
1448  if (this->hasUninitDefined() || this->parentHasUninitDefined())
1449  {
1450  mixin_subclass->setParentHasUninitDefined();
1451  }
1452  return mixin_subclass; /* return the new mixin class */
1453 }
1454 
1455 
1456 /**
1457  * Create a subclass of a class directly from Rexx code.
1458  *
1459  * @param class_id The id of the created class.
1460  * @param meta_class The meta class to create this from.
1461  * @param enhancing_class_methods
1462  * Additional class methods.
1463  *
1464  * @return A created class object.
1465  */
1466 RexxClass *RexxClass::subclassRexx(RexxString *class_id, RexxClass *meta_class, RexxObject *enhancing_class_methods)
1467 {
1468  // just forward with no source object specified
1469  return subclass(OREF_NULL, class_id, meta_class, (RexxTable *)enhancing_class_methods);
1470 }
1471 
1472 
1474  PackageClass *package,
1475  RexxString * class_id, /* ID name of the class */
1476  RexxClass * meta_class, /* source meta class */
1477  /* extra class methods */
1478  RexxTable * enhancing_class_methods)
1479 /*****************************************************************************/
1480 /* Function: Create a new class object that is a subclass of this class */
1481 /* object. */
1482 /*****************************************************************************/
1483 {
1484  if (meta_class == OREF_NULL) /* if there is no metaclass specified*/
1485  {
1486  meta_class = this->getMetaClass(); /* use the default metaclass */
1487  }
1488 
1489  /* check that it is a meta class */
1490  if (!meta_class->isInstanceOf(TheClassClass) || !meta_class->isMetaClass())
1491  {
1493  }
1494  ProtectedObject p;
1495  /* get a copy of the metaclass class */
1496  meta_class->sendMessage(OREF_NEW, class_id, p);
1497  RexxClass *new_class = (RexxClass *)(RexxObject *)p;
1498 
1499  // hook this up with the source as early as possible.
1500  new_class->setPackage(package);
1501 
1502  if (this->isMetaClass()) /* if the superclass is a metaclass */
1503  {
1504  new_class->setMetaClass(); /* mark the new class as a meta class*/
1505  /* and if the metaclass lists haven't */
1506  /* been updated yet */
1507  if (new_class->metaClassScopes->get(this) == OREF_NULL)
1508  {
1509  /* add the class instance info to the */
1510  /* metaclass lists */
1511  new_class->metaClass->addFirst(this);
1512  /* the metaclass mdict list */
1514  /* and the metaclass scopes list */
1515  /* this is done by adding all the */
1516  /* scope information of the new class */
1517  new_class->metaClassScopes->add(this, TheNilObject);
1518  /* add the scope list for this scope */
1519  new_class->metaClassScopes->add(new_class->metaClassScopes->allAt(TheNilObject), this);
1520  }
1521  }
1522  /* set up the new_class behaviour */
1523  /* to match the subclass reciever */
1524  new_class->instanceBehaviour->subclass(this->instanceBehaviour);
1525  /* set this class as the superclass */
1526  /* for the new class' */
1527  /* class_superclasses list */
1528  OrefSet(new_class, new_class->classSuperClasses, new_array(this));
1529  /* make the receiver class the */
1530  /* superclass for the instance behav */
1531  OrefSet(new_class, new_class->instanceSuperClasses, new_array(this));
1532  /* if there was enhancing methods */
1533  /* specified */
1534  if (enhancing_class_methods != OREF_NULL && enhancing_class_methods != TheNilObject)
1535  {
1536  /* convert into a real method dict. */
1537  enhancing_class_methods = new_class->methodDictionaryCreate(enhancing_class_methods, new_class);
1538  ProtectedObject p(enhancing_class_methods);
1539  /* merge them into the class mdict */
1540  new_class->methodDictionaryMerge(enhancing_class_methods, new_class->classMethodDictionary);
1541  }
1542  /* start out the class behaviour clean*/
1544  new_class->behaviour->setScopes(OREF_NULL);
1545  /* create the class behaviour from */
1546  /* the class superclass list */
1547  new_class->createClassBehaviour(new_class->behaviour);
1548  /* set the class behaviour created */
1549  /* class to the meta class */
1550  new_class->behaviour->setOwningClass(meta_class);
1551  /* create the instance behaviour from */
1552  /* the instance superclass list */
1554  new_class->instanceBehaviour->setScopes(OREF_NULL);
1555  new_class->createInstanceBehaviour(new_class->instanceBehaviour);
1556  /* set the instance behaviour created */
1557  /* class to the reciever class */
1558  new_class->instanceBehaviour->setOwningClass(new_class);
1559  /* update the receiver class' subclass*/
1560 
1561  this->addSubClass(new_class); /* list to reflect the new class */
1562  /* if the class object has an UNINIT method defined, make sure we */
1563  /* add this to the table of classes to be processed. */
1564  if (new_class->hasUninitMethod())
1565  {
1566  new_class->hasUninit();
1567  }
1568  new_class->sendMessage(OREF_INIT); /* now drive any user INIT methods */
1569  /* now the new class object should */
1570  /* If the parent class has an uninit defined, the new child class must have one, too */
1571  if (this->hasUninitDefined() || this->parentHasUninitDefined())
1572  {
1573  new_class->setParentHasUninitDefined();
1574  }
1575  /* notify activity this object has an UNINIT that needs to be called
1576  when collecting the object */
1577  if (new_class->hasUninitDefined())
1578  {
1579  new_class->setHasUninitDefined();
1580  }
1581 
1582  return new_class; /* return the new class */
1583 }
1584 
1586  RexxClass *new_metaClass ) /* new meta class to add */
1587 /******************************************************************************/
1588 /* Function: Set a metaclass for a class */
1589 /******************************************************************************/
1590 {
1591  OrefSet(this, this->metaClass, new_array(TheClassClass));
1592  this->metaClass->addFirst(new_metaClass);
1593  /* the metaclass mdict list */
1594  OrefSet(this, this->metaClassMethodDictionary, new_array(TheClassClass->instanceMethodDictionary->copy()));
1596  /* and the metaclass scopes list */
1597  OrefSet(this, this->metaClassScopes, (RexxIdentityTable *)TheClassClass->behaviour->getScopes()->copy());
1598  /* add the scope list for this scope */
1599  this->metaClassScopes->add(new_metaClass, TheNilObject);
1600  this->metaClassScopes->add(this->metaClassScopes->allAt(TheNilObject), new_metaClass);
1601 }
1602 
1603 
1604 /**
1605  * Test if the target class is a "compatible" with the argument
1606  * class. To be compatible, the target class must either A)
1607  * be the same class, B) be a direct subclass of the argument
1608  * class, or C) inherit the argument class as a mixin. This
1609  * rule gets applied recursively down the hierarchy.
1610  *
1611  * @param other The comparison class.
1612  *
1613  * @return True if the two classes are compatible, false otherwise.
1614  */
1616 {
1617  // if asking for a match here, this is true
1618  if (other == this)
1619  {
1620  return true;
1621  }
1622 
1623  // if this is .object, there are no superclasses. Otherwise, ask each of the superclasses
1624  // the same question.
1626  {
1627  for (size_t i = 1; i <= instanceSuperClasses->size(); i++)
1628  {
1629  if (((RexxClass *)instanceSuperClasses->get(i))->isCompatibleWith(other))
1630  {
1631  return true;
1632  }
1633  }
1634  }
1635  return false;
1636 }
1637 
1638 
1639 /**
1640  * A stub to test compatibility of two classes.
1641  *
1642  * @param other The class for the superclass test.
1643  *
1644  * @return True if the class is a subclass of the argument class (or IS
1645  * the argument class).
1646  */
1648 {
1649  requiredArgument(other, OREF_positional, ARG_ONE); // must have the other argument
1650  return isCompatibleWith(other) ? TheTrueObject : TheFalseObject;
1651 }
1652 
1654 /******************************************************************************/
1655 /* Function: Exported access to an object virtual function */
1656 /******************************************************************************/
1657 {
1658  return this->defaultName(); /* forward to the virtual function */
1659 }
1660 
1661 
1662 /**
1663  * Set the source object what a class was created in. This
1664  * will be the source that contains the ::class directive
1665  * that defined the class.
1666  *
1667  * @param s The package file containing the ::class directive that
1668  * created this class.
1669  */
1671 {
1672  OrefSet(this, this->package, s);
1673 }
1674 
1675 /**
1676  * Return the package containing the directive that
1677  * defined a class.
1678  *
1679  * @return The package containing the directive that defined this
1680  * class, or .nil if this class was not created from a
1681  * directive.
1682  */
1684 {
1685  // ooRexx4: package not really managed, workaround...
1686  if (this->isInRexxPackage()) return TheRexxPackage;
1687 
1688  // return the package we've been associated with.
1689  return (PackageClass *)resultOrNil(package);
1690 }
1691 
1692 
1693 // all of the new methods need to check if they are marked as
1694 // abstract as a subclass...this centralizes the check.
1695 void RexxClass::checkAbstract() // ooRexx5
1696 {
1697  if (isAbstract())
1698  {
1700  }
1701 }
1702 
1703 
1704 /**
1705  * Mark a class as abstract, if this is allowed for this
1706  * type of class.
1707  */
1708 void RexxClass::makeAbstract() // ooRexx5
1709 {
1710  if (isMetaClass())
1711  {
1713  }
1714  setAbstract();
1715 }
1716 
1717 
1718 void *RexxClass::operator new(size_t size,
1719  size_t size1, /* additional size */
1720  const char *className, // The id string of the class
1721  RexxBehaviour *class_behaviour, /* new class behaviour */
1722  RexxBehaviour *instanceBehaviour) /* instance behaviour info */
1723 /*****************************************************************************/
1724 /* Function: Create a new primitive class */
1725 /* for the subclassable classes the rest of the class information */
1726 /* will be filled in when oksetup.c is run */
1727 /*****************************************************************************/
1728 {
1729  RexxClass *new_class; /* newly create class */
1730 
1731  if (size1 == 0) /* want the default? */
1732  {
1733  /* Get new class object */
1734  new_class = (RexxClass *)new_object(size);
1735  }
1736  else
1737  {
1738  /* use the specified size */
1739  new_class = (RexxClass *)new_object(size1);
1740  }
1741  // set this value immediately
1742  new_class->id = new_string(className);
1743  /* set the class specific behaviour */
1744  new_class->setBehaviour(class_behaviour);
1745  /* set the class into the behaviour */
1746  new_class->behaviour->setOwningClass(new_class);
1747  /* set the instance behaviour */
1748  OrefSet(new_class, new_class->instanceBehaviour, instanceBehaviour);
1749  /* and the class of this behaviour */
1750  new_class->instanceBehaviour->setOwningClass(new_class);
1751  /* tell the mobile support to just */
1752  new_class->makeProxiedObject(); /* make a proxy for this class */
1753  return(void *)new_class; /* should be ready */
1754 }
1755 
1756 RexxClass *RexxClass::newRexx(RexxObject **args, size_t argCount, size_t named_argCount)
1757 /*****************************************************************************/
1758 /* Function: Create a new class for a rexx class */
1759 /* A copy of this class object is made */
1760 /* This class' behaviour, class_mdict, metaclass, and class_info */
1761 /* are used in the new class. All the rest of the object state */
1762 /* data is updated to reflect a new class object */
1763 /*****************************************************************************/
1764 {
1765  if (argCount == 0) /* make sure an arg was passed in */
1766  {
1767  /* if not report an error */
1769  }
1770  RexxString *class_id = (RexxString *)args[0]; /* get the id parameter */
1771  class_id = stringArgument(class_id, OREF_positional, ARG_ONE); /* and that it can be a string */
1772  ProtectedObject p1(class_id);
1773  /* get a copy of this class object */
1774  RexxClass *new_class = (RexxClass *)this->clone();
1775 
1776  // NOTE: we do this before save() is called. The class object hash value
1777  // is based off of the string name, so we need to set this before we
1778  // attempt putting this into a hash collection.
1779  OrefSet(new_class, new_class->id, class_id);
1780  /* update cloned hashvalue */
1781  ProtectedObject p(new_class); /* better protect this */
1782 
1783  // no new class objects start out as abstract.
1784  new_class->clearAbstract();
1785 
1786  /* make this into an instance of the */
1787  /* meta class */
1788  OrefSet(new_class, new_class->behaviour, (RexxBehaviour *)new_class->instanceBehaviour->copy());
1789  /* don't give access to this class' */
1790  /* class mdict */
1791  OrefSet(new_class, new_class->classMethodDictionary, new_table());
1792  /* make this class the superclass */
1793  OrefSet(new_class, new_class->classSuperClasses, new_array(this));
1794  new_class->behaviour->setOwningClass(this);/* and set the behaviour class */
1795  /* if this is a primitive class then */
1796  /* there isn't any metaclass info */
1797  if (this->isPrimitiveClass()) /* set up yet */
1798  {
1799  /* set up the new metaclass list */
1800  OrefSet(new_class, new_class->metaClass, new_array(TheClassClass));
1801  /* the metaclass mdict list */
1802  OrefSet(new_class, new_class->metaClassMethodDictionary, new_array(TheClassClass->instanceMethodDictionary->copy()));
1803  /* and the metaclass scopes list */
1804  OrefSet(new_class, new_class->metaClassScopes, (RexxIdentityTable *)TheClassClass->behaviour->getScopes()->copy());
1805  }
1806  else
1807  {
1808  /* add this class to the new class */
1809  /* metaclass list */
1810  OrefSet(new_class, new_class->metaClass, (RexxArray *)new_class->metaClass->copy());
1811  new_class->metaClass->addFirst(this);
1812  /* the metaclass mdict list */
1813  OrefSet(new_class, new_class->metaClassMethodDictionary, (RexxArray *)new_class->metaClassMethodDictionary->copy());
1815  /* and the metaclass scopes list */
1816  /* this is done by adding all the */
1817  /* scope information of the new class */
1818  OrefSet(new_class, new_class->metaClassScopes, (RexxIdentityTable *)new_class->metaClassScopes->copy());
1819  /* and update the scopes to include */
1820  /* the metaclass scopes */
1821  new_class->metaClassScopes->add(this, TheNilObject);
1822  new_class->metaClassScopes->add(this->behaviour->getScopes()->allAt(TheNilObject), this);
1823  }
1824 
1825  // create the subclasses list
1826  OrefSet(new_class, new_class->subClasses, new_list());
1827  /* set up the instance behaviour with */
1828  /* object's instance methods */
1829  OrefSet(new_class, new_class->instanceBehaviour, (RexxBehaviour *)TheObjectClass->instanceBehaviour->copy());
1830  /* don't give access to this class' */
1831  /* instance mdict */
1832  OrefSet(new_class, new_class->instanceMethodDictionary, new_table());
1833  /* make the instance_superclass list */
1834  /* with OBJECT in it */
1835  OrefSet(new_class, new_class->instanceSuperClasses, new_array(TheObjectClass));
1836  /* and set the behaviour class */
1838  /* and the instance behaviour scopes */
1840  /* set the scoping info */
1842  /* don't give access to this class' */
1843  /* ovd's */
1844  OrefSet(new_class, new_class->objectVariables, OREF_NULL);
1845  /* set the new class as it's own */
1846  /* baseclass */
1847  OrefSet(new_class, new_class->baseClass, new_class);
1848  /* clear the info area except for */
1849  /* uninit */
1850  new_class->setInitialFlagState();
1851  /* if the class object has an UNINIT method defined, make sure we */
1852  /* add this to the table of classes to be processed. */
1853  if (new_class->hasUninitDefined())
1854  {
1855  new_class->setHasUninitDefined();
1856  }
1857  new_class->sendMessage(OREF_INIT, args + 1, argCount - 1, named_argCount);
1858  return new_class; /* return the new class */
1859 }
1860 
1862 /******************************************************************************/
1863 /* Function: Create the initial class object */
1864 /******************************************************************************/
1865 {
1866  /* create a class object */
1868  /* set the instance behaviour */
1869  TheClassClass->setBehaviour(TheClassClassBehaviour);
1870  /* set the instance behaviour */
1871  TheClassClass->setInstanceBehaviour(TheClassBehaviour);
1872 
1873  // the initial class needs to have an ID before it can be used for
1874  // other purposes.
1875  TheClassClass->id = new_string("Class");
1876 
1877  /* tell the mobile support to just */
1878  /* make a proxy for this class */
1879  TheClassClass->makeProxiedObject();
1880  new (TheClassClass) RexxClass;
1881 }
1882 
1883 
1884 // ooRexx5
1885 // jlf: not called (yet). Should be called by ALL the native classes.
1886 // High risk of regression!
1887 /**
1888  * Perform common initialization steps on an object created
1889  * by a new method from Rexx. This handles subclass
1890  * behaviour issues, uninit processing, etc.
1891  *
1892  * @param obj The newly created object. NOTE: this assumes the
1893  * caller has protected this object from garbage collection.
1894  * @param initArgs A pointer to arguments intended for the INIT method.
1895  * @param argCount The count of arguments.
1896  */
1897 #if 0
1898 void RexxClass::completeNewObject(RexxObject *obj, RexxObject **initArgs, size_t argCount)
1899 {
1900  // this is a good common place to perform the abstract checks
1901  checkAbstract();
1902 
1903  // set the behaviour (this might be a subclass, so don't assume the
1904  // one from the base class is correct).
1906  // a subclass might define an uninit method, so we need to
1907  // check that also.
1908  if (hasUninitDefined())
1909  {
1910  obj->requiresUninit();
1911  }
1912 
1913  ProtectedObject result;
1914  // now send an INIT message to complete initialization.
1915  obj->sendMessage(GlobalNames::INIT, initArgs, argCount, result);
1916 }
1917 #endif
1918 
1919 
1921  RexxObject **arg_array, /* source argument array */
1922  size_t argCount, /* size of the argument array */
1923  RexxObject***init_args, /* remainder arguments */
1924  size_t *remainderSize, /* remaining count of arguments */
1925  size_t required, /* number of arguments we require */
1926  RexxObject **argument1, /* first returned argument */
1927  RexxObject **argument2 ) /* second return argument */
1928 /******************************************************************************/
1929 /* Function: Divide up a class new arglist into new arguments and init args */
1930 /******************************************************************************/
1931 {
1932  *argument1 = OREF_NULL; /* clear the first argument */
1933  if (argCount >= 1) /* have at least one argument? */
1934  {
1935  *argument1 = arg_array[0]; /* get the first argument */
1936  }
1937  if (required == 2)
1938  { /* processing two arguments? */
1939  if (argCount >= 2) /* get at least 2? */
1940  {
1941  *argument2 = arg_array[1]; /* get the second argument */
1942  }
1943  else
1944  {
1945  *argument2 = OREF_NULL; /* clear the second argument */
1946  }
1947  }
1948  /* get the init args part */
1949  *init_args = arg_array + required;
1950  /* if we have at least the required arguments, reduce the count. */
1951  /* Otherwise, set this to zero. */
1952  if (argCount >= required)
1953  {
1954  *remainderSize = argCount - required;
1955  }
1956  else
1957  {
1958  *remainderSize = 0;
1959  }
1960 }
void reportException(wholenumber_t error)
void reportNomethod(RexxErrorCodes error, RexxString *message, RexxObject *receiver)
RexxString * lastMessageName()
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
RexxIdentityTable * new_identity_table()
#define LIST_END
Definition: ListClass.hpp:60
RexxList * new_list()
Definition: ListClass.hpp:147
size_t HashCode
Definition: ObjectClass.hpp:79
#define TheClassBehaviour
#define TheClassClassBehaviour
#define TheObjectBehaviour
#define TheRexxPackage
Definition: RexxCore.h:189
RexxObject * resultOrNil(RexxInternalObject *o)
Definition: RexxCore.h:484
RexxObject * booleanObject(bool v)
Definition: RexxCore.h:496
#define OREF_NULL
Definition: RexxCore.h:61
RexxString * stringArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:315
#define TheObjectClass
Definition: RexxCore.h:166
#define TheNullArray
Definition: RexxCore.h:193
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:295
#define IntegerOne
Definition: RexxCore.h:200
#define TheClassClass
Definition: RexxCore.h:156
#define TheStringClass
Definition: RexxCore.h:169
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define TheTrueObject
Definition: RexxCore.h:196
const int ARG_TWO
Definition: RexxCore.h:84
#define TheIntegerClass
Definition: RexxCore.h:158
#define IntegerTwo
Definition: RexxCore.h:201
#define isOfClass(t, r)
Definition: RexxCore.h:224
#define TheNilObject
Definition: RexxCore.h:191
#define TheFalseObject
Definition: RexxCore.h:195
const int ARG_ONE
Definition: RexxCore.h:83
#define TheNumberStringClass
Definition: RexxCore.h:165
void requiredArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:303
#define Error_Logical_value_method
#define Error_Execution_mixinclass
#define Error_No_result_object_message
#define Error_Translation_bad_metaclass
#define Error_Execution_uninherit
#define Error_Incorrect_method_minarg
#define Error_No_method_name
#define Error_Execution_recursive_inherit
#define Error_Execution_abstract_class
#define Error_Execution_abstract_metaclass
#define Error_Execution_baseclass
size_t HashLink
#define memory_mark(oref)
Definition: RexxMemory.hpp:450
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:436
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:451
@ SAVINGIMAGE
Definition: RexxMemory.hpp:117
RexxString * new_string(const char *s, stringsize_t l)
RexxString * new_proxy(const char *name)
RexxTable * new_table()
Definition: TableClass.hpp:76
size_t addFirst(RexxObject *item)
Definition: ArrayClass.hpp:199
size_t insertAfter(RexxObject *item, size_t index)
Definition: ArrayClass.hpp:200
RexxObject * copy()
Definition: ArrayClass.cpp:122
size_t indexOf(RexxObject *)
size_t size()
Definition: ArrayClass.hpp:202
size_t addLast(RexxObject *item)
Definition: ArrayClass.hpp:198
RexxObject * deleteItem(size_t index)
RexxObject * get(size_t pos)
Definition: ArrayClass.hpp:203
RexxTable * getMethodDictionary()
void merge(RexxBehaviour *)
RexxObject * mergeScope(RexxObject *)
RexxObject * addScope(RexxObject *)
void methodDictionaryMerge(RexxTable *)
RexxObject * define(RexxString *, RexxMethod *)
RexxObject * copy()
void setMethodDictionary(RexxTable *m)
RexxObject * deleteMethod(RexxString *)
RexxObject * setScopes(RexxIdentityTable *)
bool checkScope(RexxObject *)
RexxIdentityTable * getScopes()
void subclass(RexxBehaviour *)
void setInstanceMethodDictionary(RexxTable *m)
void setOwningClass(RexxClass *c)
void removeSubclass(RexxClass *c)
void createClassBehaviour(RexxBehaviour *)
Definition: ClassClass.cpp:969
void setHasUninitDefined()
Definition: ClassClass.hpp:126
RexxClass * newRexx(RexxObject **args, size_t argCount, size_t named_argCount)
void setInstanceBehaviour(RexxBehaviour *)
Definition: ClassClass.cpp:324
PackageClass * package
Definition: ClassClass.hpp:186
RexxObject * deleteMethod(RexxString *)
Definition: ClassClass.cpp:821
RexxClass * getSuperClass()
Definition: ClassClass.cpp:333
uint32_t classFlags
Definition: ClassClass.hpp:183
RexxClass * subclassRexx(RexxString *, RexxClass *, RexxObject *)
RexxTable * methodDictionaryCreate(RexxTable *, RexxClass *)
static void createInstance()
void mergeSuperClassScopes(RexxBehaviour *target_instance_behaviour)
void addSubClass(RexxClass *)
Definition: ClassClass.cpp:367
static RexxClass * classInstance
Definition: ClassClass.hpp:148
PackageClass * getPackage()
bool isRexxDefined()
Definition: ClassClass.hpp:121
bool isAbstract()
Definition: ClassClass.hpp:124
void updateInstanceSubClasses()
Definition: ClassClass.cpp:944
void methodDictionaryMerge(RexxTable *, RexxTable *)
RexxClass * baseClass
Definition: ClassClass.hpp:171
void setInitialFlagState()
Definition: ClassClass.hpp:129
RexxTable * instanceMethodDictionary
Definition: ClassClass.hpp:170
RexxMethod * method(RexxString *)
Definition: ClassClass.cpp:850
void setMetaClass(RexxClass *)
RexxClass * getMetaClass()
Definition: ClassClass.cpp:309
RexxArray * instanceSuperClasses
Definition: ClassClass.hpp:180
RexxTable * getInstanceBehaviourDictionary()
Definition: ClassClass.cpp:417
bool isPrimitiveClass()
Definition: ClassClass.hpp:132
static void processNewArgs(RexxObject **, size_t, RexxObject ***, size_t *, size_t, RexxObject **, RexxObject **)
RexxObject * inherit(RexxClass *, RexxClass *)
void defmeths(RexxTable *)
Definition: ClassClass.cpp:378
void checkAbstract()
RexxString * defaultNameRexx()
RexxObject * isMetaClassRexx()
Definition: ClassClass.cpp:267
RexxObject * notEqual(RexxObject *)
Definition: ClassClass.cpp:231
RexxArray * getSubClasses()
Definition: ClassClass.cpp:358
void liveGeneral(int reason)
Definition: ClassClass.cpp:87
RexxIdentityTable * metaClassScopes
Definition: ClassClass.hpp:175
void removeClassMethod(RexxString *method_name)
Definition: ClassClass.cpp:803
RexxClass * getBaseClass()
Definition: ClassClass.cpp:301
RexxTable * classMethodDictionary
Definition: ClassClass.hpp:166
RexxObject * defineMethod(RexxString *, RexxMethod *)
Definition: ClassClass.cpp:653
RexxArray * getSuperClasses()
Definition: ClassClass.cpp:348
RexxObject * isAbstractRexx()
Definition: ClassClass.cpp:278
void setPackage(PackageClass *s)
RexxObject * isSubclassOf(RexxClass *other)
RexxObject * enhanced(RexxObject **, size_t, size_t)
RexxObject * unflatten(RexxEnvelope *)
Definition: ClassClass.cpp:120
void updateSubClasses()
Definition: ClassClass.cpp:909
RexxInteger * queryMixinClass()
Definition: ClassClass.cpp:253
RexxBehaviour * getInstanceBehaviour()
Definition: ClassClass.hpp:135
RexxTable * getBehaviourDictionary()
Definition: ClassClass.cpp:435
RexxObject * equal(RexxObject *)
Definition: ClassClass.cpp:209
void setParentHasUninitDefined()
Definition: ClassClass.hpp:131
bool parentHasUninitDefined()
Definition: ClassClass.hpp:130
RexxObject * defineMethods(RexxTable *)
Definition: ClassClass.cpp:725
void clearAbstract()
Definition: ClassClass.hpp:138
RexxObject * setRexxDefined()
Definition: ClassClass.cpp:292
bool isCompatibleWith(RexxClass *other)
void completeNewObject(RexxObject *obj, RexxObject **initArgs=OREF_NULL, size_t argCount=0)
RexxObject * defineClassMethod(RexxString *method_name, RexxMethod *newMethod)
Definition: ClassClass.cpp:772
void setAbstract()
Definition: ClassClass.hpp:137
RexxSupplier * methods(RexxClass *)
Definition: ClassClass.cpp:869
RexxArray * metaClass
Definition: ClassClass.hpp:172
void flatten(RexxEnvelope *)
Definition: ClassClass.cpp:112
RexxClass * mixinClassRexx(RexxString *, RexxClass *, RexxObject *)
RexxBehaviour * instanceBehaviour
Definition: ClassClass.hpp:168
bool hasUninitDefined()
Definition: ClassClass.hpp:125
RexxObject * strictEqual(RexxObject *)
Definition: ClassClass.cpp:172
RexxList * subClasses
Definition: ClassClass.hpp:185
bool isEqual(RexxObject *)
Definition: ClassClass.cpp:181
RexxObject * uninherit(RexxClass *)
void setMetaClass()
Definition: ClassClass.hpp:136
RexxArray * classSuperClasses
Definition: ClassClass.hpp:177
void makeAbstract()
RexxString * id
Definition: ClassClass.hpp:163
RexxString * getId()
Definition: ClassClass.cpp:284
bool isMixinClass()
Definition: ClassClass.hpp:122
HashCode getHashValue()
Definition: ClassClass.cpp:163
RexxString * defaultName()
Definition: ClassClass.cpp:403
HashCode hash()
Definition: ClassClass.cpp:149
void live(size_t)
Definition: ClassClass.cpp:67
void createInstanceBehaviour(RexxBehaviour *)
RexxObject * makeProxy(RexxEnvelope *)
Definition: ClassClass.cpp:128
RexxArray * metaClassMethodDictionary
Definition: ClassClass.hpp:174
void subClassable(bool)
Definition: ClassClass.cpp:462
void setMixinClass()
Definition: ClassClass.hpp:133
bool isMetaClass()
Definition: ClassClass.hpp:123
RexxClass * subclass(PackageClass *, RexxString *, RexxClass *, RexxTable *)
RexxClass * mixinclass(PackageClass *, RexxString *, RexxClass *, RexxTable *)
bool available(HashLink pos)
RexxObject * value(HashLink pos)
HashLink next(HashLink pos)
virtual RexxObject * remove(RexxObject *key)
RexxObject * index(HashLink pos)
RexxSupplier * supplier()
RexxArray * allAt(RexxObject *key)
virtual RexxObject * get(RexxObject *key)
virtual RexxObject * add(RexxObject *, RexxObject *)
void setBehaviour(RexxBehaviour *b)
RexxObject * clone()
RexxBehaviour * behaviour
RexxObject * removeIndex(size_t i)
Definition: ListClass.hpp:113
size_t firstIndex()
Definition: ListClass.hpp:84
size_t nextIndex(size_t i)
Definition: ListClass.cpp:804
RexxArray * weakReferenceArray()
Definition: ListClass.cpp:1170
RexxObject * getValue(size_t i)
Definition: ListClass.cpp:276
void addFirst(RexxObject *value)
Definition: ListClass.cpp:486
void setScope(RexxClass *)
static RexxMethod * newMethodObject(RexxString *, RexxObject *, RexxObject *, RexxSource *a, bool isBlock=false)
RexxMethod * newScope(RexxClass *)
bool hasUninitMethod()
void sendMessage(RexxString *, RexxArray *, RexxDirectory *, ProtectedObject &)
bool isInstanceOf(RexxClass *)
const char * getStringData()
RexxString * concatWithCstring(const char *)
RexxString * concatToCstring(const char *)
bool strCompare(const char *s)
RexxString * upper()
RexxObject * next()
RexxInteger * available()
RexxObject * value()
RexxObject * index()
RexxObject * stringAdd(RexxObject *, RexxString *)
Definition: TableClass.cpp:94
RexxObject * stringPut(RexxObject *, RexxString *)
Definition: TableClass.cpp:113
RexxObject * stringGet(RexxString *key)
Definition: TableClass.hpp:67
RexxObject * get()