📄 ejsobject.c
字号:
}/******************************************************************************/static int classGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv){ if (thisObj->objectState == 0 || thisObj->objectState->baseClass == 0) { ejsSetReturnValueToString(ejs, "object"); } else { ejsSetReturnValueToString(ejs, thisObj->objectState->baseClass->objectState->className); } return 0;}/******************************************************************************//* * Format an object. Called recursively to format properties and contained * objects. */static void formatVar(Ejs *ep, MprBuf *bp, EjsVar *vp){ EjsProperty *pp, *first; EjsVar *propVar, *baseClass; char *buf, *value; int i; if (vp->type == EJS_TYPE_OBJECT) { if (!vp->objectState->visited) { mprPutStringToBuf(bp, vp->isArray ? "[\n" : "{\n"); ep->depth++; vp->objectState->visited = 1; if (ep->depth <= ep->maxDepth) { first = ejsGetFirstProperty(vp, EJS_ENUM_ALL); if (ep->flags & EJS_FLAGS_ENUM_BASE) { baseClass = vp->objectState->baseClass; if (baseClass) { for (i = 0; i < ep->depth; i++) { mprPutStringToBuf(bp, " "); } mprPutStringToBuf(bp, baseClass->objectState->objName); mprPutStringToBuf(bp, ": /* Base Class */ "); if (baseClass->objectState == vp->objectState) { value = "this"; } else if (ejsRunMethodCmd(ep, baseClass, "toString", "%d", ep->maxDepth) < 0) { value = "[object Object]"; } else { mprAssert(ejsVarIsString(ep->result)); value = ep->result->string; } mprPutStringToBuf(bp, value); if (first) { mprPutStringToBuf(bp, ",\n"); } } } pp = first; while (pp) { if (! pp->dontEnumerate || ep->flags & EJS_FLAGS_ENUM_HIDDEN) { for (i = 0; i < ep->depth; i++) { mprPutStringToBuf(bp, " "); } if (! vp->isArray) { mprPutStringToBuf(bp, pp->name); mprPutStringToBuf(bp, ": "); } propVar = ejsGetVarPtr(pp); if (propVar->type == EJS_TYPE_OBJECT) { if (pp->var.objectState == vp->objectState) { value = "this"; } else if (ejsRunMethodCmd(ep, propVar, "toString", "%d", ep->maxDepth) < 0) { value = "[object Object]"; } else { mprAssert(ejsVarIsString(ep->result)); value = ep->result->string; } mprPutStringToBuf(bp, value); } else { formatVar(ep, bp, &pp->var); } pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); if (pp) { mprPutStringToBuf(bp, ",\n"); } } else { pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); } } } vp->objectState->visited = 0; mprPutCharToBuf(bp, '\n'); ep->depth--; for (i = 0; i < ep->depth; i++) { mprPutStringToBuf(bp, " "); } mprPutCharToBuf(bp, vp->isArray ? ']' : '}'); } } else if (vp->type == EJS_TYPE_METHOD) { mprPutStringToBuf(bp, "function ("); for (i = 0; i < vp->method.args->length; i++) { mprPutStringToBuf(bp, vp->method.args->items[i]); if ((i + 1) < vp->method.args->length) { mprPutStringToBuf(bp, ", "); } } mprPutStringToBuf(bp, ") {"); mprPutStringToBuf(bp, vp->method.body); for (i = 0; i < ep->depth; i++) { mprPutStringToBuf(bp, " "); } mprPutStringToBuf(bp, "}"); } else { if (vp->type == EJS_TYPE_STRING) { mprPutCharToBuf(bp, '\"'); } /* * We don't use ejsVarToString for arrays, objects and strings. * This is because ejsVarToString does not call "obj.toString" * and it is not required for strings. * MOB - rc */ buf = ejsVarToString(ep, vp); mprPutStringToBuf(bp, buf); if (vp->type == EJS_TYPE_STRING) { mprPutCharToBuf(bp, '\"'); } }}/******************************************************************************//* * mixin code. Blends code at the "thisObj" level. */ static int mixinMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){ EjsProperty *pp; char *buf; int fid, i, rc; mprAssert(argv); /* * Create a variable scope block set to the current object */ rc = 0; fid = ejsSetBlock(ep, thisObj); for (i = 0; i < argc; i++) { if (ejsVarIsString(argv[i])) { rc = ejsEvalScript(ep, argv[i]->string, 0); } else if (ejsVarIsObject(argv[i])) { /* MOB -- OPT. When we have proper scope chains, we should just refer to the module and not copy */ pp = ejsGetFirstProperty(argv[i], EJS_ENUM_ALL); while (pp) { ejsSetProperty(ep, thisObj, pp->name, ejsGetVarPtr(pp)); pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); } } else { /* MOB - rc */ buf = ejsVarToString(ep, argv[i]); rc = ejsEvalScript(ep, buf, 0); } if (rc < 0) { ejsCloseBlock(ep, fid); return -1; } } ejsCloseBlock(ep, fid); return 0;}/******************************************************************************//* * Create the object class */int ejsDefineObjectClass(Ejs *ep){ EjsMethods *methods; EjsProperty *objectProp, *protoProp; EjsVar *op, *globalClass; /* * Must specially hand-craft the object class as it is the base class * of all objects. */ op = ejsCreateObjVar(ep); if (op == 0) { return MPR_ERR_CANT_CREATE; } ejsSetClassName(ep, op, "Object"); /* * Don't use a constructor for objects for speed */ ejsMakeClassNoConstructor(op); /* * MOB -- should mark properties as public / private and class or instance. */ ejsDefineCMethod(ep, op, "clone", cloneMethod, EJS_NO_LOCAL); ejsDefineCMethod(ep, op, "toString", toStringMethod, EJS_NO_LOCAL); ejsDefineCMethod(ep, op, "valueOf", valueOfMethod, EJS_NO_LOCAL); ejsDefineCMethod(ep, op, "mixin", mixinMethod, EJS_NO_LOCAL); ejsDefineCAccessors(ep, op, "hash", hashGetAccessor, 0, EJS_NO_LOCAL); ejsDefineCAccessors(ep, op, "baseClass", classGetAccessor, 0, EJS_NO_LOCAL); /* * MOB -- make this an accessor */ protoProp = ejsSetProperty(ep, op, "prototype", op); if (protoProp == 0) { ejsFreeVar(ep, op); return MPR_ERR_CANT_CREATE; } /* * Setup the internal methods. Most classes will never override these. * The XML class will. We rely on talloc to free internal. Use "ep" as * the parent as we need "methods" to live while the interpreter lives. */ methods = mprAllocTypeZeroed(ep, EjsMethods); op->objectState->methods = methods; methods->createProperty = createObjProperty; methods->deleteProperty = deleteObjProperty; methods->getProperty = getObjProperty; methods->setProperty = setObjProperty; objectProp = ejsSetPropertyAndFree(ep, ep->global, "Object", op); /* * Change the global class to use Object's methods */ globalClass = ep->service->globalClass; globalClass->objectState->methods = methods; globalClass->objectState->baseClass = ejsGetVarPtr(protoProp); ep->objectClass = ejsGetVarPtr(objectProp); if (ejsObjHasErrors(ejsGetVarPtr(objectProp))) { ejsFreeVar(ep, op); return MPR_ERR_CANT_CREATE; } return 0;}/******************************************************************************/#elsevoid ejsObjectDummy() {}/******************************************************************************/#endif /* BLD_FEATURE_EJS *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -