Index: TODO =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- TODO (.../TODO) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ TODO (.../TODO) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -5426,6 +5426,14 @@ - relax the meaning of noleadingdash to allow negative numbers - rename noleadingdash to e.g. nodashalnum +nsf.c: +- define means to protect "undefined" internally-directly called methods + __alloc and __dealloc in nx. This is achieved mostly via a an + additional value in a method declaration in ::nsf::objectsystem::create. + Example: + -class.dealloc {__dealloc ::nsf::methods::class::dealloc 1} +- extend regression test + ======================================================================== TODO: Index: generic/nsf.c =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- generic/nsf.c (.../nsf.c) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ generic/nsf.c (.../nsf.c) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -388,7 +388,7 @@ static int AliasDeleteObjectReference(Tcl_Interp *interp, Tcl_Command cmd) nonnull(1) nonnull(2); static int NsfMethodAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, - CONST char *methodName, int withFrame, Tcl_Obj *cmdName) + CONST char *methodName, int withFrame, int withProtection, Tcl_Obj *cmdName) nonnull(1) nonnull(2) nonnull(4); static int AliasRefetch(Tcl_Interp *interp, NsfObject *object, CONST char *methodName, @@ -432,6 +432,9 @@ static NsfObjectOpt *NsfRequireObjectOpt(NsfObject *object) nonnull(1) returns_nonnull; static NsfClassOpt * NsfRequireClassOpt(/*@notnull@*/ NsfClass *cl) nonnull(1) returns_nonnull; +static int ObjectSystemsCheckSystemMethod(Tcl_Interp *interp, CONST char *methodName, NsfObject *object, int flags) + nonnull(1) nonnull(2) nonnull(3); + #ifdef DO_CLEANUP static void DeleteNsfProcs(Tcl_Interp *interp, Tcl_Namespace *nsPtr) nonnull(1); #endif @@ -3878,122 +3881,7 @@ } -/* - *---------------------------------------------------------------------- - * ObjectSystemsCheckSystemMethod -- - * - * Mark in all object systems the specified method as - * (potentially) overloaded and mark it in the specified - * object system as defined. - * - * Results: - * None. - * - * Side effects: - * Updating the object system structure(s). - * - *---------------------------------------------------------------------- - */ -static void ObjectSystemsCheckSystemMethod(Tcl_Interp *interp, CONST char *methodName, NsfObject *object) - nonnull(1) nonnull(2) nonnull(3); -static void -ObjectSystemsCheckSystemMethod(Tcl_Interp *interp, CONST char *methodName, NsfObject *object) { - NsfObjectSystem *osPtr, *defOsPtr = GetObjectSystem(object); - char firstChar; - - assert(interp); - assert(object); - assert(methodName); - - firstChar = *methodName; - - for (osPtr = RUNTIME_STATE(interp)->objectSystems; osPtr; osPtr = osPtr->nextPtr) { - int i, rootClassMethod, flag = 0; - - for (i = 0; i <= NSF_s_set_idx; i++) { - Tcl_Obj *methodObj = osPtr->methods[i]; - CONST char *methodString = methodObj ? ObjStr(methodObj) : NULL; - - if (methodString && *methodString == firstChar && !strcmp(methodName, methodString)) { - flag = 1<definedMethods & flag) { - /* - * If for some reason (e.g. reload) we redefine the base - * methods, these never count as overloads. - */ - if ((rootClassMethod && object == &defOsPtr->rootClass->object) - || (!rootClassMethod && object == &defOsPtr->rootMetaClass->object) ) { - /*fprintf(stderr, "+++ %s %.6x NOT overloading %s.%s %s (is root %d, is meta %d)\n", - ClassName(defOsPtr->rootClass), - osPtr->overloadedMethods, ObjectName(object), methodName, Nsf_SystemMethodOpts[i], - object == &defOsPtr->rootClass->object, - object == &defOsPtr->rootMetaClass->object);*/ - } else { - osPtr->overloadedMethods |= flag; - /*fprintf(stderr, "+++ %s %.6x overloading %s.%s %s (is root %d, is meta %d)\n", - ClassName(defOsPtr->rootClass), - osPtr->overloadedMethods, ObjectName(object), methodName, Nsf_SystemMethodOpts[i], - object == &defOsPtr->rootClass->object, - object == &defOsPtr->rootMetaClass->object);*/ - } - } - if (osPtr == defOsPtr && ((osPtr->definedMethods & flag) == 0)) { - /* - * Mark the method das defined - */ - osPtr->definedMethods |= flag; - - /*fprintf(stderr, "+++ %s %.6x defining %s.%s %s osPtr %p defined %.8x flag %.8x\n", - ClassName(defOsPtr->rootClass), osPtr->definedMethods, ObjectName(object), - methodName, Nsf_SystemMethodOpts[i], osPtr, osPtr->definedMethods, flag);*/ - - /* - * If there is a method-handle provided for this system method, - * register it as a fallback unless the method being defined is - * already at the root class. - */ - if (osPtr->handles[i]) { - NsfObject *defObject = rootClassMethod - ? &osPtr->rootClass->object - : &osPtr->rootMetaClass->object; - - if (defObject != object) { - int result = NsfMethodAliasCmd(interp, defObject, 0, methodName, 0, osPtr->handles[i]); - - /* - * Since the defObject is not equals the overloaded method, the - * definition above is effectively an overload of the alias. - */ - osPtr->overloadedMethods |= flag; - - NsfLog(interp, NSF_LOG_NOTICE, "Define automatically alias %s for %s", - ObjStr(osPtr->handles[i]), Nsf_SystemMethodOpts[i]); - /* - * If the definition was ok, make the method protected. - */ - if (likely(result == TCL_OK)) { - Tcl_Obj *methodObj = Tcl_GetObjResult(interp); - Tcl_Command cmd = Tcl_GetCommandFromObj(interp, methodObj); - if (cmd) { Tcl_Command_flags(cmd) |= NSF_CMD_CALL_PROTECTED_METHOD; } - Tcl_ResetResult(interp); - } else { - NsfLog(interp, NSF_LOG_WARN, "Could not define alias %s for %s", - ObjStr(osPtr->handles[i]), Nsf_SystemMethodOpts[i]); - } - } - } - } - } -} - /* *---------------------------------------------------------------------- * ObjectSystemsCleanup -- @@ -6211,10 +6099,11 @@ * *---------------------------------------------------------------------- */ -static int CanRedefineCmd(Tcl_Interp *interp, Tcl_Namespace *nsPtr, NsfObject *object, CONST char *methodName) nonnull(1) nonnull(2) nonnull(3) nonnull(4); +static int CanRedefineCmd(Tcl_Interp *interp, Tcl_Namespace *nsPtr, NsfObject *object, CONST char *methodName, int flags) + nonnull(1) nonnull(2) nonnull(3) nonnull(4); static int -CanRedefineCmd(Tcl_Interp *interp, Tcl_Namespace *nsPtr, NsfObject *object, CONST char *methodName) { +CanRedefineCmd(Tcl_Interp *interp, Tcl_Namespace *nsPtr, NsfObject *object, CONST char *methodName, int flags) { int result, ok; Tcl_Command cmd; @@ -6257,7 +6146,7 @@ } if (likely(result == TCL_OK)) { - ObjectSystemsCheckSystemMethod(interp, methodName, object); + result = ObjectSystemsCheckSystemMethod(interp, methodName, object, flags); } return result; } @@ -6297,7 +6186,7 @@ assert(proc); /* Check, if we are allowed to redefine the method */ - result = CanRedefineCmd(interp, object->nsPtr, object, (char *)methodName); + result = CanRedefineCmd(interp, object->nsPtr, object, (char *)methodName, flags); if (unlikely(result != TCL_OK)) { return result; } @@ -6340,8 +6229,8 @@ int NsfAddClassMethod(Tcl_Interp *interp, Nsf_Class *class, CONST char *methodName, - Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *dp, - int flags) { + Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *dp, + int flags) { NsfClass *cl = (NsfClass *)class; Tcl_DString newCmdName, *dsPtr = &newCmdName; Tcl_Command newCmd; @@ -6352,8 +6241,10 @@ assert(methodName); assert(proc); + + /* Check, if we are allowed to redefine the method */ - result = CanRedefineCmd(interp, cl->nsPtr, &cl->object, (char *)methodName); + result = CanRedefineCmd(interp, cl->nsPtr, &cl->object, (char *)methodName, flags); if (unlikely(result != TCL_OK)) { return result; } @@ -10874,6 +10765,144 @@ #include "nsfAPI.h" +/* + *---------------------------------------------------------------------- + * ObjectSystemsCheckSystemMethod -- + * + * Mark in all object systems the specified method as + * (potentially) overloaded and mark it in the specified + * object system as defined. + * + * Results: + * Tcl result code. + * + * Side effects: + * Updating the object system structure(s). + * + *---------------------------------------------------------------------- + */ + +static int +ObjectSystemsCheckSystemMethod(Tcl_Interp *interp, CONST char *methodName, NsfObject *object, int flags) { + NsfObjectSystem *osPtr, *defOsPtr = GetObjectSystem(object); + + char firstChar; + + assert(interp); + assert(object); + assert(methodName); + + firstChar = *methodName; + + for (osPtr = RUNTIME_STATE(interp)->objectSystems; osPtr; osPtr = osPtr->nextPtr) { + int i, rootClassMethod, flag = 0; + NsfObject *defObject; + + for (i = 0; i <= NSF_s_set_idx; i++) { + Tcl_Obj *methodObj = osPtr->methods[i]; + CONST char *methodString = methodObj ? ObjStr(methodObj) : NULL; + + if (methodString && *methodString == firstChar && !strcmp(methodName, methodString)) { + flag = 1<rootClass->object + : &osPtr->rootMetaClass->object; + + if (osPtr->handles[i] && osPtr->protected[i]) { + if (defObject == object && (flags & NSF_CMD_REDEFINE_PROTECTED_METHOD) == 0) { + return NsfPrintError(interp, "refuse to overwrite protected method %s on %s", + methodName, ObjectName(defObject)); + } + } + + + if (osPtr->definedMethods & flag) { + /* + * If for some reason (e.g. reload) we redefine the base + * methods, these never count as overloads. + */ + if ((rootClassMethod && object == &defOsPtr->rootClass->object) + || (!rootClassMethod && object == &defOsPtr->rootMetaClass->object) ) { + /*fprintf(stderr, "+++ %s %.6x NOT overloading %s.%s %s (is root %d, is meta %d)\n", + ClassName(defOsPtr->rootClass), + osPtr->overloadedMethods, ObjectName(object), methodName, Nsf_SystemMethodOpts[i], + object == &defOsPtr->rootClass->object, + object == &defOsPtr->rootMetaClass->object);*/ + } else { + osPtr->overloadedMethods |= flag; + /*fprintf(stderr, "+++ %s %.6x overloading %s.%s %s (is root %d, is meta %d)\n", + ClassName(defOsPtr->rootClass), + osPtr->overloadedMethods, ObjectName(object), methodName, Nsf_SystemMethodOpts[i], + object == &defOsPtr->rootClass->object, + object == &defOsPtr->rootMetaClass->object);*/ + } + } + if (osPtr == defOsPtr && ((osPtr->definedMethods & flag) == 0)) { + /* + * Mark the method das defined + */ + osPtr->definedMethods |= flag; + + /*fprintf(stderr, "+++ %s %.6x defining %s.%s %s osPtr %p defined %.8x flag %.8x handle %p\n", + ClassName(defOsPtr->rootClass), osPtr->definedMethods, ObjectName(object), + methodName, Nsf_SystemMethodOpts[i], osPtr, osPtr->definedMethods, flag, + osPtr->handles[i]);*/ + + /* + * If there is a method-handle provided for this system method, + * register it as a fallback unless the method being defined is + * already at the root class. + */ + if (osPtr->handles[i]) { + + if (defObject != object) { + int result = NsfMethodAliasCmd(interp, defObject, 0, methodName, 0, + ProtectionRedefine_protectedIdx, osPtr->handles[i]); + + if (result != TCL_OK) { + return TCL_ERROR; + } + + /* + * Since the defObject is not equals the overloaded method, the + * definition above is effectively an overload of the alias. + */ + osPtr->overloadedMethods |= flag; + + NsfLog(interp, NSF_LOG_NOTICE, "Define automatically alias %s for %s", + ObjStr(osPtr->handles[i]), Nsf_SystemMethodOpts[i]); + /* + * If the definition was ok, make the method protected. + */ + if (likely(result == TCL_OK)) { + Tcl_Obj *methodObj = Tcl_GetObjResult(interp); + Tcl_Command cmd = Tcl_GetCommandFromObj(interp, methodObj); + if (cmd) { + Tcl_Command_flags(cmd) |= NSF_CMD_CALL_PROTECTED_METHOD; + if (osPtr->protected[i]) { + Tcl_Command_flags(cmd) |= NSF_CMD_REDEFINE_PROTECTED_METHOD; + } + } + Tcl_ResetResult(interp); + } else { + NsfLog(interp, NSF_LOG_WARN, "Could not define alias %s for %s", + ObjStr(osPtr->handles[i]), Nsf_SystemMethodOpts[i]); + } + } + } + } + } + + return TCL_OK; +} + + /*---------------------------------------------------------------------- * ParamsNew -- * @@ -15697,7 +15726,7 @@ if (regObject == NULL) {regObject = defObject;} /* Check, if we are allowed to redefine the method */ - result = CanRedefineCmd(interp, nsPtr, defObject, methodName); + result = CanRedefineCmd(interp, nsPtr, defObject, methodName, 0); if (likely(result == TCL_OK)) { /* Yes, we can! ...so obtain an method parameter definitions */ result = ParamDefsParse(interp, nameObj, args, @@ -24280,13 +24309,14 @@ {-argName "-per-object"} {-argName "methodName"} {-argName "-frame" -required 0 -nrargs 1 -type "method|object|default" -default "default"} + {-argName "-protection" -required 0 -type "call-protected|redefine-protected|none" -default "none"} {-argName "cmdName" -required 1 -type tclobj} } */ static int NsfMethodAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, - CONST char *methodName, int withFrame, - Tcl_Obj *cmdName) { + CONST char *methodName, int withFrame, int withProtection, + Tcl_Obj *cmdName) { Tcl_ObjCmdProc *objProc, *newObjProc = NULL; Tcl_CmdDeleteProc *deleteProc = NULL; AliasCmdClientData *tcd = NULL; /* make compiler happy */ @@ -24425,7 +24455,11 @@ /*fprintf(stderr, "NsfMethodAliasCmd no wrapper cmd %p\n", cmd);*/ } - flags = 0; + switch (withProtection) { + case ProtectionCall_protectedIdx: flags = NSF_CMD_CALL_PROTECTED_METHOD; break; + case ProtectionRedefine_protectedIdx: flags = NSF_CMD_REDEFINE_PROTECTED_METHOD; break; + default: flags = 0; + } if (cl) { result = NsfAddClassMethod(interp, (Nsf_Class *)cl, methodName, @@ -25185,7 +25219,7 @@ if (unlikely(result != TCL_OK)) { ObjectSystemFree(interp, osPtr); return NsfPrintError(interp, "invalid system method '%s'", ObjStr(ov[i])); - } else if (arg_oc < 1 || arg_oc > 2) { + } else if (arg_oc < 1 || arg_oc > 3) { ObjectSystemFree(interp, osPtr); return NsfPrintError(interp, "invalid system method argument '%s'", ObjStr(ov[i]), ObjStr(arg)); } @@ -25197,6 +25231,11 @@ } else { /* (arg_oc == 2) */ osPtr->methods[idx] = arg_ov[0]; osPtr->handles[idx] = arg_ov[1]; + if (arg_oc == 3) { + int bool = 0; + Tcl_GetBooleanFromObj(interp, arg_ov[2], &bool); + osPtr->protected[idx] = bool; + } INCR_REF_COUNT(osPtr->handles[idx]); } INCR_REF_COUNT(osPtr->methods[idx]); Index: generic/nsfAPI.decls =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -113,6 +113,7 @@ {-argName "-per-object" -required 0 -nrargs 0 -type switch} {-argName "methodName" -required 1} {-argName "-frame" -required 0 -type "method|object|default" -default "default"} + {-argName "-protection" -required 0 -type "call-protected|redefine-protected|none" -default "none"} {-argName "cmdName" -required 1 -type tclobj} } {-nxdoc 1} cmd "method::assertion" NsfMethodAssertionCmd { Index: generic/nsfAPI.h =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- generic/nsfAPI.h (.../nsfAPI.h) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -168,6 +168,19 @@ return result; } +enum ProtectionIdx {ProtectionNULL, ProtectionCall_protectedIdx, ProtectionRedefine_protectedIdx, ProtectionNoneIdx}; + +static int ConvertToProtection(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, + ClientData *clientData, Tcl_Obj **outObjPtr) { + int index, result; + static CONST char *opts[] = {"call-protected", "redefine-protected", "none", NULL}; + (void)pPtr; + result = Tcl_GetIndexFromObj(interp, objPtr, opts, "-protection", 0, &index); + *clientData = (ClientData) INT2PTR(index + 1); + *outObjPtr = objPtr; + return result; +} + enum AssertionsubcmdIdx {AssertionsubcmdNULL, AssertionsubcmdCheckIdx, AssertionsubcmdObject_invarIdx, AssertionsubcmdClass_invarIdx}; static int ConvertToAssertionsubcmd(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, @@ -276,6 +289,7 @@ {ConvertToObjectproperty, "initialized|class|rootmetaclass|rootclass|volatile|slotcontainer|hasperobjectslots|keepcallerself|perobjectdispatch"}, {ConvertToAssertionsubcmd, "check|object-invar|class-invar"}, {ConvertToParametersubcmd, "default|list|name|syntax|type"}, + {ConvertToProtection, "call-protected|redefine-protected|none"}, {NULL, NULL} }; @@ -582,8 +596,8 @@ NSF_nonnull(1) NSF_nonnull(2); static int NsfIsCmd(Tcl_Interp *interp, int withComplain, int withConfigure, CONST char *withName, Tcl_Obj *constraint, Tcl_Obj *value) NSF_nonnull(1) NSF_nonnull(5) NSF_nonnull(6); -static int NsfMethodAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, CONST char *methodName, int withFrame, Tcl_Obj *cmdName) - NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4) NSF_nonnull(6); +static int NsfMethodAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, CONST char *methodName, int withFrame, int withProtection, Tcl_Obj *cmdName) + NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4) NSF_nonnull(7); static int NsfMethodAssertionCmd(Tcl_Interp *interp, NsfObject *object, int subcmd, Tcl_Obj *arg) NSF_nonnull(1) NSF_nonnull(2); static int NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, int withCheckalways, int withInner_namespace, int withPer_object, NsfObject *withReg_object, Tcl_Obj *methodName, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition) @@ -1680,10 +1694,11 @@ int withPer_object = (int )PTR2INT(pc.clientData[1]); CONST char *methodName = (CONST char *)pc.clientData[2]; int withFrame = (int )PTR2INT(pc.clientData[3]); - Tcl_Obj *cmdName = (Tcl_Obj *)pc.clientData[4]; + int withProtection = (int )PTR2INT(pc.clientData[4]); + Tcl_Obj *cmdName = (Tcl_Obj *)pc.clientData[5]; assert(pc.status == 0); - return NsfMethodAliasCmd(interp, object, withPer_object, methodName, withFrame, cmdName); + return NsfMethodAliasCmd(interp, object, withPer_object, methodName, withFrame, withProtection, cmdName); } else { return TCL_ERROR; @@ -3373,11 +3388,12 @@ {"constraint", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"value", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::method::alias", NsfMethodAliasCmdStub, 5, { +{"::nsf::method::alias", NsfMethodAliasCmdStub, 6, { {"object", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Object, NULL,NULL,"object",NULL,NULL,NULL,NULL,NULL}, {"-per-object", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, {"methodName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-frame", NSF_ARG_IS_ENUMERATION, 1, ConvertToFrame, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-protection", NSF_ARG_IS_ENUMERATION, 1, ConvertToProtection, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"cmdName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::nsf::method::assertion", NsfMethodAssertionCmdStub, 3, { Index: generic/nsfInt.h =================================================================== diff -u -r75383021cb9f2f2db883583779a02eef6f1801f5 -rcd7387dce218900697565aeabc0e58afb0294a6a --- generic/nsfInt.h (.../nsfInt.h) (revision 75383021cb9f2f2db883583779a02eef6f1801f5) +++ generic/nsfInt.h (.../nsfInt.h) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -635,6 +635,7 @@ Tcl_Obj *methods[NSF_s_set_idx+1]; Tcl_Obj *handles[NSF_s_set_idx+1]; struct NsfObjectSystem *nextPtr; + char protected[NSF_s_set_idx+1]; } NsfObjectSystem; Index: library/nx/nx.tcl =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- library/nx/nx.tcl (.../nx.tcl) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ library/nx/nx.tcl (.../nx.tcl) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -54,9 +54,9 @@ # via alias). # ::nsf::objectsystem::create ::nx::Object ::nx::Class { - -class.alloc {__alloc ::nsf::methods::class::alloc} + -class.alloc {__alloc ::nsf::methods::class::alloc 1} -class.create create - -class.dealloc {__dealloc ::nsf::methods::class::dealloc} + -class.dealloc {__dealloc ::nsf::methods::class::dealloc 1} -class.configureparameter __class_configureparameter -class.recreate {__recreate ::nsf::methods::class::recreate} -object.configure __configure Index: tests/disposition.test =================================================================== diff -u -r75383021cb9f2f2db883583779a02eef6f1801f5 -rcd7387dce218900697565aeabc0e58afb0294a6a --- tests/disposition.test (.../disposition.test) (revision 75383021cb9f2f2db883583779a02eef6f1801f5) +++ tests/disposition.test (.../disposition.test) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -131,7 +131,7 @@ [list [list X Y]] # - # By design, all parameters are currently limited to 0 or 1 + # As used, all parameters receive currently 0 or 1 # argument. The same is true for disposition "alias" an # "forward". One could consider to unbox a parameter list via a # parameter option "expand" (like {*}) for alias|forward parameter @@ -141,10 +141,16 @@ # # Without the sketched extension, one could use eval in a forwarder. # - +puts stderr ===1 C setObjectParams {{{-multi-2:forward,method=eval %self %method}}} +puts stderr ===2a +set x [C new -multi-2 {X Y}] +puts stderr [$x eval {set :multi-2}] +puts stderr ===2b + ? {[C new -multi-2 {X Y}] eval {set :multi-2}} \ "X Y" +puts stderr ===3 # # In the positional case, why is FOO not passed on as arg value to Index: tests/method-parameter.test =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- tests/method-parameter.test (.../method-parameter.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ tests/method-parameter.test (.../method-parameter.test) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -104,7 +104,7 @@ # testing error message when flags are used within an ensemble # -nx::test case flag-in-enemble { +nx::test case flag-in-ensemble { nx::Class create C set info {info children, info class, info filter guard, info filter methods, info has mixin, info has namespace, info has type, info heritage, info info, info instances, info lookup filter, info lookup filters, info lookup method, info lookup methods, info lookup mixins, info lookup parameters, info lookup slots, info lookup syntax, info lookup variables, info method args, info method body, info method definition, info method definitionhandle, info method exists, info method handle, info method origin, info method parameters, info method registrationhandle, info method returns, info method submethods, info method syntax, info method type, info methods, info mixin classes, info mixin guard, info mixinof, info name, info object filter guard, info object filter methods, info object method args, info object method body, info object method definition, info object method definitionhandle, info object method exists, info object method handle, info object method origin, info object method parameters, info object method registrationhandle, info object method returns, info object method submethods, info object method syntax, info object method type, info object methods, info object mixin classes, info object mixin guard, info object slots, info object variables, info parent, info precedence, info slots, info subclass, info superclass, info variable definition, info variable name, info variable parameter, info variables, info vars} Index: tests/method-require.test =================================================================== diff -u -r4bc60e16c10fdbbb640b3019d4bdebdc469fdf55 -rcd7387dce218900697565aeabc0e58afb0294a6a --- tests/method-require.test (.../method-require.test) (revision 4bc60e16c10fdbbb640b3019d4bdebdc469fdf55) +++ tests/method-require.test (.../method-require.test) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -119,11 +119,18 @@ } # +# Test what happens if we try to redefine a "nonexistant" protected method. +# +nx::test case method-require-scope { + ? {nx::Class public method __alloc arg {return 1}} {refuse to overwrite protected method __alloc on ::nx::Class} + ? {nx::Class public method __dealloc arg {return 1}} {refuse to overwrite protected method __dealloc on ::nx::Class} +} + +# # Test what happens if a class-specific method is registered and # called on an object. # nx::test case method-require-scope { - nx::Object create o ::nsf::method::require o __alloc ? {o __alloc x} {method __alloc not dispatched on valid class} Index: tests/parameters.test =================================================================== diff -u -r896f9013e125e965474ea7fdbda099ca22b152c2 -rcd7387dce218900697565aeabc0e58afb0294a6a --- tests/parameters.test (.../parameters.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) +++ tests/parameters.test (.../parameters.test) (revision cd7387dce218900697565aeabc0e58afb0294a6a) @@ -28,12 +28,12 @@ ? {::nsf::method::alias C} \ {required argument 'methodName' is missing, should be: - ::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? /cmdName/} + ::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? ?-protection call-protected|redefine-protected|none? /cmdName/} ? {::nsf::method::alias C foo ::set} "::nsf::classes::C::foo" ? {::nsf::method::alias C foo ::set 1} \ - {invalid argument '1', maybe too many arguments; should be "::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? /cmdName/"} + {invalid argument '1', maybe too many arguments; should be "::nsf::method::alias /object/ ?-per-object? /methodName/ ?-frame method|object|default? ?-protection call-protected|redefine-protected|none? /cmdName/"} ? {C eval {:property x -class D}} {invalid argument 'D', maybe too many arguments; should be "::C property ?-accessor /value/? ?-configurable /boolean/? ?-incremental? ?-class /value/? /spec/ ?/initblock/?"} "Test whether the colon prefix is suppressed" }