ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

ClassDirective.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 ClassDirective.cpp */
40 /* */
41 /* Primitive Translator Abstract Directive Code */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "ClassDirective.hpp"
47 #include "Clause.hpp"
48 #include "DirectoryClass.hpp"
49 #include "TableClass.hpp"
50 #include "ListClass.hpp"
51 #include "RexxActivation.hpp"
52 
53 
54 
63 {
64  idName = n;
65  publicName = p;
66 }
67 
73 void ClassDirective::live(size_t liveMark)
74 {
75  memory_mark(this->nextInstruction); // must be first one marked (though normally null)
76  memory_mark(this->publicName);
77  memory_mark(this->idName);
84 }
85 
86 
93 {
94  memory_mark_general(this->nextInstruction); // must be first one marked (though normally null)
103 }
104 
105 
112 {
114 
115  flatten_reference(newThis->nextInstruction, envelope);
116  flatten_reference(newThis->publicName, envelope);
117  flatten_reference(newThis->idName, envelope);
118  flatten_reference(newThis->metaclassName, envelope);
119  flatten_reference(newThis->subclassName, envelope);
120  flatten_reference(newThis->inheritsClasses, envelope);
121  flatten_reference(newThis->instanceMethods, envelope);
122  flatten_reference(newThis->classMethods, envelope);
123  // by this time, we should be finished with this, and it should
124  // already be null. Make sure this is the case.
125  newThis->dependencies = OREF_NULL;
126 
128 }
129 
130 
138 void *ClassDirective::operator new(size_t size)
139 {
140  return new_object(size, T_ClassDirective); /* Get new object */
141 }
142 
143 
152 {
153  RexxClass *metaclass = OREF_NULL;
154  RexxClass *subclass = TheObjectClass;
155 
156  // make this the current line for the error context
157  activation->setCurrent(this);
158 
159  if (metaclassName != OREF_NULL)
160  {
161  /* resolve the class */
162  metaclass = source->findClass(metaclassName);
163  if (metaclass == OREF_NULL) /* nothing found? */
164  {
165  /* not found in environment, error! */
167  }
168  }
169 
170  if (subclassName != OREF_NULL) /* no subclass? */
171  {
172  /* resolve the class */
173  subclass = source->findClass(subclassName);
174  if (subclass == OREF_NULL) /* nothing found? */
175  {
176  /* not found in environment, error! */
178  }
179  }
180 
181  RexxClass *classObject; // the class object we're creating
182 
183  // create the class object using the appropriate mechanism
184  if (mixinClass)
185  {
186  classObject = subclass->mixinclass(idName, metaclass, classMethods);
187  }
188  else
189  {
190  /* doing a subclassing */
191  classObject = subclass->subclass(idName, metaclass, classMethods);
192  }
193  /* add the class to the directory */
194  source->addInstalledClass(publicName, classObject, publicClass);
195 
196  if (inheritsClasses != OREF_NULL) /* have inherits to process? */
197  {
198  // now handle the multiple inheritance issues
199  for (size_t i = inheritsClasses->firstIndex(); i != LIST_END; i = inheritsClasses->nextIndex(i))
200  {
201  /* get the next inherits name */
202  RexxString *inheritsName = (RexxString *)inheritsClasses->getValue(i);
203  /* go resolve the entry */
204  RexxClass *mixin = source->findClass(inheritsName);
205  if (mixin == OREF_NULL) /* not found? */
206  {
207  /* not found in environment, error! */
209  }
210  /* do the actual inheritance */
211  classObject->sendMessage(OREF_INHERIT, mixin);
212  }
213  }
214 
215  if (instanceMethods != OREF_NULL) /* have instance methods to add? */
216  {
217  /* define them to the class object */
218  classObject->defineMethods(instanceMethods);
219  }
220  // the source needs this at the end so it call call the activate methods
221  return classObject;
222 }
223 
224 
234 {
235  if (name != OREF_NULL)
236  {
237  // if this is in install? */
238  if (class_directives->entry(name) != OREF_NULL)
239  {
240  if (dependencies == OREF_NULL)
241  {
242  OrefSet(this, this->dependencies, new_directory());
243  }
244  /* add to our pending list */
245  dependencies->setEntry(name, name);
246  }
247  }
248 }
249 
250 
259 {
260  // now for each of our dependent classes, if this is defined locally, we
261  // an entry to our dependency list to aid the class ordering
262 
263  checkDependency(metaclassName, class_directives);
264  checkDependency(subclassName, class_directives);
265  // process each inherits item the same way
266  if (inheritsClasses != OREF_NULL)
267  {
268  for (size_t i = inheritsClasses->firstIndex(); i != LIST_END; i = inheritsClasses->nextIndex(i))
269  {
270  /* get the next inherits name */
271  RexxString *inheritsName = (RexxString *)inheritsClasses->getValue(i);
272  checkDependency(inheritsName, class_directives);
273  }
274  }
275 }
276 
277 
284 {
285  return dependencies == OREF_NULL;
286 }
287 
288 
295 {
296  // if we have a dependency list, remove this name from the
297  // list. If this is our last dependency item, we can junk
298  // the list entirely.
299  if (dependencies != OREF_NULL)
300  {
301  dependencies->remove(name);
302  if (dependencies->items() == 0)
303  {
304  OrefSet(this, this->dependencies, OREF_NULL);
305  }
306  }
307 }
308 
309 
316 {
317  if (inheritsClasses == OREF_NULL)
318  {
319  OrefSet(this, this->inheritsClasses, new_list());
320  }
321  inheritsClasses->append(name);
322 }
323 
324 
331 {
332  if (classMethods == OREF_NULL)
333  {
334  OrefSet(this, this->classMethods, new_table());
335  }
336  return classMethods;
337 }
338 
339 
346 {
347  if (instanceMethods == OREF_NULL)
348  {
349  OrefSet(this, this->instanceMethods, new_table());
350  }
351  return instanceMethods;
352 }
353 
354 
365 {
366  if (classMethod)
367  {
368  return getClassMethods()->get(name) != OREF_NULL;
369  }
370  else
371  {
372  return getInstanceMethods()->get(name) != OREF_NULL;
373  }
374 
375 }
376 
377 
386 void ClassDirective::addMethod(RexxString *name, RexxMethod *method, bool classMethod)
387 {
388  if (classMethod)
389  {
390  getClassMethods()->put(method, name);
391  }
392  else
393  {
394  getInstanceMethods()->put(method, name);
395  }
396 }
397 
398 
406 {
407  // this gets added as both a class and instance method
408  addMethod(name, method, false);
409  addMethod(name, method, true);
410 }
RexxClass::mixinclass
RexxClass * mixinclass(RexxString *, RexxClass *, RexxTable *)
Definition: ClassClass.cpp:1332
ClassDirective::addConstantMethod
void addConstantMethod(RexxString *name, RexxMethod *method)
Definition: ClassDirective.cpp:405
RexxObject::sendMessage
void sendMessage(RexxString *, RexxArray *, ProtectedObject &)
Definition: ObjectClass.cpp:668
ClassDirective.hpp
RexxHashTableCollection::put
virtual RexxObject * put(RexxObject *, RexxObject *)
Definition: RexxCollection.cpp:279
RexxSource::addInstalledClass
void addInstalledClass(RexxString *name, RexxClass *classObject, bool publicClass)
Definition: SourceFile.cpp:6175
RexxClause
Definition: Clause.hpp:52
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
ClassDirective::addInherits
void addInherits(RexxString *name)
Definition: ClassDirective.cpp:315
RexxActivation.hpp
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
Error_Execution_noclass
#define Error_Execution_noclass
Definition: RexxErrorCodes.h:530
ClassDirective::checkDuplicateMethod
bool checkDuplicateMethod(RexxString *name, bool classMethod)
Definition: ClassDirective.cpp:364
ClassDirective::addMethod
void addMethod(RexxString *name, RexxMethod *method, bool classMethod)
Definition: ClassDirective.cpp:386
ListClass.hpp
ClassDirective::install
RexxClass * install(RexxSource *source, RexxActivation *activation)
Definition: ClassDirective.cpp:151
ClassDirective::idName
RexxString * idName
Definition: ClassDirective.hpp:95
TableClass.hpp
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
ClassDirective::flatten
void flatten(RexxEnvelope *)
Definition: ClassDirective.cpp:111
ClassDirective::dependenciesResolved
bool dependenciesResolved()
Definition: ClassDirective.cpp:283
RexxClass::subclass
RexxClass * subclass(RexxString *, RexxClass *, RexxTable *)
Definition: ClassClass.cpp:1357
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxDirectory::items
size_t items()
Definition: DirectoryClass.cpp:137
ClassDirective::publicName
RexxString * publicName
Definition: ClassDirective.hpp:94
ClassDirective::addDependencies
void addDependencies(RexxDirectory *class_directives)
Definition: ClassDirective.cpp:258
ClassDirective::getClassMethods
RexxTable * getClassMethods()
Definition: ClassDirective.cpp:330
RexxList::nextIndex
size_t nextIndex(size_t i)
Definition: ListClass.cpp:803
RexxHashTableCollection::get
virtual RexxObject * get(RexxObject *key)
Definition: RexxCollection.cpp:242
ClassDirective::ClassDirective
ClassDirective(RexxString *, RexxString *, RexxClause *)
Definition: ClassDirective.cpp:62
TheObjectClass
#define TheObjectClass
Definition: RexxCore.h:159
RexxSource
Definition: SourceFile.hpp:131
ClassDirective
Definition: ClassDirective.hpp:52
RexxInstruction::nextInstruction
RexxInstruction * nextInstruction
Definition: RexxInstruction.hpp:85
ClassDirective::subclassName
RexxString * subclassName
Definition: ClassDirective.hpp:97
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
ClassDirective::liveGeneral
void liveGeneral(int reason)
Definition: ClassDirective.cpp:92
RexxDirectory
Definition: DirectoryClass.hpp:49
RexxList::append
RexxObject * append(RexxObject *)
Definition: ListClass.cpp:537
RexxClass
Definition: ClassClass.hpp:49
ClassDirective::removeDependency
void removeDependency(RexxString *name)
Definition: ClassDirective.cpp:294
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
RexxList::getValue
RexxObject * getValue(size_t i)
Definition: ListClass.cpp:275
ClassDirective::dependencies
RexxDirectory * dependencies
Definition: ClassDirective.hpp:103
RexxActivation::setCurrent
void setCurrent(RexxInstruction *v)
Definition: RexxActivation.hpp:362
ClassDirective::metaclassName
RexxString * metaclassName
Definition: ClassDirective.hpp:96
T_ClassDirective
Definition: ClassTypeCodes.h:173
Error_Execution_nometaclass
#define Error_Execution_nometaclass
Definition: RexxErrorCodes.h:529
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
new_table
RexxTable * new_table()
Definition: TableClass.hpp:76
RexxDirectory::entry
RexxObject * entry(RexxString *)
Definition: DirectoryClass.cpp:125
KEYWORD_CLASS
#define KEYWORD_CLASS
Definition: Token.hpp:187
ClassDirective::getInstanceMethods
RexxTable * getInstanceMethods()
Definition: ClassDirective.cpp:345
RexxDirectory::setEntry
RexxObject * setEntry(RexxString *, RexxObject *)
Definition: DirectoryClass.cpp:382
RexxActivation
Definition: RexxActivation.hpp:156
ClassDirective::live
void live(size_t)
Definition: ClassDirective.cpp:73
new_directory
RexxDirectory * new_directory()
Definition: DirectoryClass.hpp:101
RexxTable
Definition: TableClass.hpp:49
ClassDirective::checkDependency
void checkDependency(RexxString *name, RexxDirectory *class_directives)
Definition: ClassDirective.cpp:233
ClassDirective::classMethods
RexxTable * classMethods
Definition: ClassDirective.hpp:100
new_list
RexxList * new_list()
Definition: ListClass.hpp:147
RexxClass::defineMethods
RexxObject * defineMethods(RexxTable *)
Definition: ClassClass.cpp:676
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxDirectory::remove
RexxObject * remove(RexxString *)
Definition: DirectoryClass.cpp:433
LIST_END
#define LIST_END
Definition: ListClass.hpp:60
ClassDirective::inheritsClasses
RexxList * inheritsClasses
Definition: ClassDirective.hpp:98
ClassDirective::instanceMethods
RexxTable * instanceMethods
Definition: ClassDirective.hpp:99
RexxCore.h
RexxSource::findClass
RexxClass * findClass(RexxString *)
Definition: SourceFile.cpp:1609
RexxDirective
Definition: RexxDirective.hpp:51
DirectoryClass.hpp
RexxMethod
Definition: MethodClass.hpp:101
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
RexxList::firstIndex
size_t firstIndex()
Definition: ListClass.hpp:84
ClassDirective::publicClass
bool publicClass
Definition: ClassDirective.hpp:101
ClassDirective::mixinClass
bool mixinClass
Definition: ClassDirective.hpp:102
Clause.hpp
RexxString
Definition: StringClass.hpp:119