3 * @brief EJS class support
5 /********************************* Copyright **********************************/
9 * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
10 * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
12 * This software is distributed under commercial and open source licenses.
13 * You may use the GPL open source license described below or you may acquire
14 * a commercial license from Mbedthis Software. You agree to be fully bound
15 * by the terms of either license. Consult the LICENSE.TXT distributed with
16 * this software for full details.
18 * This software is open source; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version. See the GNU General Public License for more
22 * details at: http://www.mbedthis.com/downloads/gplLicense.html
24 * This program is distributed WITHOUT ANY WARRANTY; without even the
25 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 * This GPL license does NOT permit incorporating this software into
28 * proprietary programs. If you are unable to comply with the GPL, you must
29 * acquire a commercial license to use this software. Commercial licenses
30 * for this software and support services are available from Mbedthis
31 * Software at http://www.mbedthis.com
35 /********************************* Includes ***********************************/
41 /************************************ Code ************************************/
45 * Routine to create a simple class object. This routine will create a
46 * stand-alone class object. Callers must insert this into the relevant
47 * "global" object for name resolution. From these class objects, instance
48 * objects may be created via the javascript "new" command.
50 * Users should use ejsDefineClass
53 EjsVar *ejsCreateSimpleClass(Ejs *ep, EjsVar *baseClass, const char *className)
59 * Create an instance of an Object to act as the static class object
61 classObj = ejsCreateSimpleObjUsingClass(ep, baseClass);
66 ejsSetClassName(ep, classObj, className);
69 * Set the propotype property to point to this class.
70 * Note: this is a self reference so the alive bit will not be turned on.
72 pp = ejsSetProperty(ep, classObj, "prototype", classObj);
73 ejsMakePropertyEnumerable(pp, 0);
78 /******************************************************************************/
80 * Define a class in the given interpreter. If parentClass is specified, the
81 * class is defined in the parent. Otherwise, the class will be defined
82 * locally/globally. ClassName and extends are full variable specs
86 EjsVar *ejsDefineClass(Ejs *ep, const char *className, const char *extends,
87 EjsCMethod constructor)
89 EjsVar *parentClass, *classObj, *baseClass, *vp;
94 * If the className is a qualified name (with "."), then get the
97 name = mprStrdup(ep, className);
98 cp = strrchr(name, '.');
102 parentClass = ejsFindProperty(ep, 0, 0, ep->global, ep->local, name, 0);
103 if (parentClass == 0 || parentClass->type != EJS_TYPE_OBJECT) {
104 mprError(ep, MPR_LOC, "Can't find class's parent class %s", name);
111 * Simple class name without a "." so create the class locally
112 * if a local scope exists, otherwise globally.
114 parentClass = (ep->local) ? ep->local : ep->global;
117 if (parentClass == 0) {
118 mprError(ep, MPR_LOC, "Can't find parent class");
123 /* OPT should use function that doesn't parse [] . */
124 baseClass = ejsGetClass(ep, 0, extends);
125 if (baseClass == 0) {
126 mprAssert(baseClass);
131 classObj = ejsCreateSimpleClass(ep, baseClass, className);
139 ejsDefineCMethod(ep, classObj, className, constructor, 0);
142 ejsSetPropertyAndFree(ep, parentClass, className, classObj);
144 vp = ejsGetPropertyAsVar(ep, parentClass, className);
150 /******************************************************************************/
152 * Find a class and return the property defining the class. ClassName may
153 * contain "." and is interpreted relative to obj. Obj is typically some
154 * parent object, ep->local or ep->global. If obj is null, then the global
158 EjsVar *ejsGetClass(Ejs *ep, EjsVar *obj, const char *className)
165 * Search first for a constructor of the name of class
166 * global may not be defined yet.
169 vp = ejsFindProperty(ep, 0, 0, obj, 0, className, 0);
172 mprAssert(ep->global);
173 vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, className, 0);
175 if (vp == 0 || vp->type != EJS_TYPE_OBJECT) {
180 * Return a reference to the prototype (self) reference. This
181 * ensures that even if "obj" is deleted, this reference will remain
184 return ejsGetPropertyAsVar(ep, vp, "prototype");
187 /******************************************************************************/
189 * Return the class name of a class or object
192 const char *ejsGetClassName(EjsVar *vp)
197 mprAssert(vp->type == EJS_TYPE_OBJECT);
198 mprAssert(vp->objectState->baseClass);
200 if (vp == 0 || !ejsVarIsObject(vp)) {
203 obj = vp->objectState;
205 return obj->className;
208 /******************************************************************************/
210 * Return the class name of an objects underlying class
211 * If called on an object, it returns the base class.
212 * If called on a class, it returns the base class for the class.
215 const char *ejsGetBaseClassName(EjsVar *vp)
220 mprAssert(vp->type == EJS_TYPE_OBJECT);
221 mprAssert(vp->objectState->baseClass);
223 if (vp == 0 || !ejsVarIsObject(vp)) {
226 obj = vp->objectState;
227 if (obj->baseClass == 0) {
230 mprAssert(obj->baseClass->objectState);
232 return obj->baseClass->objectState->className;
235 /******************************************************************************/
237 EjsVar *ejsGetBaseClass(EjsVar *vp)
239 if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) {
243 return vp->objectState->baseClass;
246 /******************************************************************************/
248 void ejsSetBaseClass(EjsVar *vp, EjsVar *baseClass)
250 if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) {
254 vp->objectState->baseClass = baseClass;
257 /******************************************************************************/
260 void ejsProcsDummy() {}
262 /******************************************************************************/
263 #endif /* BLD_FEATURE_EJS */
271 * vim600: sw=4 ts=4 fdm=marker