Index: generic/gentclAPI.decls =================================================================== diff -u -r496dfc7bd5088b8a90f1fe532cd22336c151b06d -r84af56591a1cc4ac7a3779ec44f6978203ef016a --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 496dfc7bd5088b8a90f1fe532cd22336c151b06d) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 84af56591a1cc4ac7a3779ec44f6978203ef016a) @@ -184,7 +184,7 @@ {-argName "object" -required 1 -type object} {-argName "-per-object"} {-argName "methodName" -required 1 -type tclobj} - {-argName "methodproperty" -required 1 -type "protected|redefine-protected|returns|slotobj"} + {-argName "methodproperty" -required 1 -type "class-only|protected|redefine-protected|returns|slotobj"} {-argName "value" -type tclobj} } xotclCmd my XOTclMyCmd { Index: generic/tclAPI.h =================================================================== diff -u -r496dfc7bd5088b8a90f1fe532cd22336c151b06d -r84af56591a1cc4ac7a3779ec44f6978203ef016a --- generic/tclAPI.h (.../tclAPI.h) (revision 496dfc7bd5088b8a90f1fe532cd22336c151b06d) +++ generic/tclAPI.h (.../tclAPI.h) (revision 84af56591a1cc4ac7a3779ec44f6978203ef016a) @@ -90,13 +90,13 @@ static int convertToMethodproperty(Tcl_Interp *interp, Tcl_Obj *objPtr, XOTclParam CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { int index, result; - static CONST char *opts[] = {"protected", "redefine-protected", "returns", "slotobj", NULL}; + static CONST char *opts[] = {"class-only", "protected", "redefine-protected", "returns", "slotobj", NULL}; result = Tcl_GetIndexFromObj(interp, objPtr, opts, "methodproperty", 0, &index); *clientData = (ClientData) INT2PTR(index + 1); *outObjPtr = objPtr; return result; } -enum MethodpropertyIdx {MethodpropertyNULL, MethodpropertyProtectedIdx, MethodpropertyRedefine_protectedIdx, MethodpropertyReturnsIdx, MethodpropertySlotobjIdx}; +enum MethodpropertyIdx {MethodpropertyNULL, MethodpropertyClass_onlyIdx, MethodpropertyProtectedIdx, MethodpropertyRedefine_protectedIdx, MethodpropertyReturnsIdx, MethodpropertySlotobjIdx}; static int convertToObjectkind(Tcl_Interp *interp, Tcl_Obj *objPtr, XOTclParam CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { Index: generic/xotcl.c =================================================================== diff -u -r496dfc7bd5088b8a90f1fe532cd22336c151b06d -r84af56591a1cc4ac7a3779ec44f6978203ef016a --- generic/xotcl.c (.../xotcl.c) (revision 496dfc7bd5088b8a90f1fe532cd22336c151b06d) +++ generic/xotcl.c (.../xotcl.c) (revision 84af56591a1cc4ac7a3779ec44f6978203ef016a) @@ -4011,40 +4011,54 @@ */ /*CmdListPrint(interp, "MixinSearch CL = \n", cmdList);*/ - while (cmdList) { + /*xxxx*/ + + for (; cmdList; cmdList = cmdList->nextPtr) { + if (Tcl_Command_cmdEpoch(cmdList->cmdPtr)) { - cmdList = cmdList->nextPtr; - } else { - cls = XOTclGetClassFromCmdPtr(cmdList->cmdPtr); - /* - fprintf(stderr, "+++ MixinSearch %s->%s in %p cmdPtr %p clientData %p\n", - objectName(object), methodName, cmdList, - cmdList->cmdPtr, cmdList->clientData); - */ - if (cls) { - cmd = FindMethod(cls->nsPtr, methodName); - if (cmd && cmdList->clientData) { - if (!RUNTIME_STATE(interp)->guardCount) { - result = GuardCall(object, cls, (Tcl_Command) cmd, interp, - (Tcl_Obj*)cmdList->clientData, NULL); - } - } - if (cmd && result == TCL_OK) { - /* - * on success: compute mixin call data - */ - *cl = cls; - *currentCmdPtr = cmdList->cmdPtr; - break; - } else if (result == TCL_ERROR) { - break; - } else { - if (result == XOTCL_CHECK_FAILED) result = TCL_OK; - cmd = NULL; - cmdList = cmdList->nextPtr; - } + continue; + } + cls = XOTclGetClassFromCmdPtr(cmdList->cmdPtr); + assert(cls); + /* + fprintf(stderr, "+++ MixinSearch %s->%s in %p cmdPtr %p clientData %p\n", + objectName(object), methodName, cmdList, + cmdList->cmdPtr, cmdList->clientData); + */ + cmd = FindMethod(cls->nsPtr, methodName); + if (cmd == NULL) { + continue; + } + + if (Tcl_Command_flags(cmd) & XOTCL_CMD_CLASS_SPECIFIC_METHOD) { + /*fprintf(stderr, "we found class specific method %s on class %s object %s, isclass %d\n", + methodName, className(cls), objectName(object), XOTclObjectIsClass(object));*/ + if (!XOTclObjectIsClass(object)) { + /* the command is not for us; skip it */ + cmd = NULL; + continue; } } + + if (cmdList->clientData) { + if (!RUNTIME_STATE(interp)->guardCount) { + result = GuardCall(object, cls, (Tcl_Command) cmd, interp, + (Tcl_Obj*)cmdList->clientData, NULL); + } + } + if (result == TCL_OK) { + /* + * on success: compute mixin call data + */ + *cl = cls; + *currentCmdPtr = cmdList->cmdPtr; + break; + } else if (result == TCL_ERROR) { + break; + } else { + if (result == XOTCL_CHECK_FAILED) result = TCL_OK; + cmd = NULL; + } } *cmdPtr = cmd; @@ -11429,7 +11443,7 @@ {-argName "object" -required 1 -type object} {-argName "-per-object"} {-argName "methodName" -required 1 -type tclobj} - {-argName "methodproperty" -required 1 -type "protected|redefine-protected|returns|slotobj"} + {-argName "methodproperty" -required 1 -type "class-only|protected|redefine-protected|returns|slotobj"} {-argName "value" -type tclobj} } */ @@ -11476,12 +11490,15 @@ } switch (methodproperty) { + case MethodpropertyClass_onlyIdx: /* fall through */ case MethodpropertyProtectedIdx: /* fall through */ case MethodpropertyRedefine_protectedIdx: { int flag = methodproperty == MethodpropertyProtectedIdx ? XOTCL_CMD_PROTECTED_METHOD : - XOTCL_CMD_REDEFINE_PROTECTED_METHOD; + methodproperty == MethodpropertyRedefine_protectedIdx ? + XOTCL_CMD_REDEFINE_PROTECTED_METHOD + :XOTCL_CMD_CLASS_SPECIFIC_METHOD; if (valueObj) { int bool, result; Index: generic/xotclInt.h =================================================================== diff -u -r39a142bba1228a228ab72054aa7a7bd64333db3c -r84af56591a1cc4ac7a3779ec44f6978203ef016a --- generic/xotclInt.h (.../xotclInt.h) (revision 39a142bba1228a228ab72054aa7a7bd64333db3c) +++ generic/xotclInt.h (.../xotclInt.h) (revision 84af56591a1cc4ac7a3779ec44f6978203ef016a) @@ -329,7 +329,7 @@ #define XOTCL_CMD_REDEFINE_PROTECTED_METHOD 0x00020000 /* XOTCL_CMD_NONLEAF_METHOD is used to flag, if a Method implemented via cmd calls "next" */ #define XOTCL_CMD_NONLEAF_METHOD 0x00040000 - +#define XOTCL_CMD_CLASS_SPECIFIC_METHOD 0x00080000 /* * object flags ... */ Index: library/nx/nx.tcl =================================================================== diff -u -r496dfc7bd5088b8a90f1fe532cd22336c151b06d -r84af56591a1cc4ac7a3779ec44f6978203ef016a --- library/nx/nx.tcl (.../nx.tcl) (revision 496dfc7bd5088b8a90f1fe532cd22336c151b06d) +++ library/nx/nx.tcl (.../nx.tcl) (revision 84af56591a1cc4ac7a3779ec44f6978203ef016a) @@ -409,16 +409,17 @@ # register method "info" on Object and Class Object forward info -onerror ::nsf::infoError ::nx::objectInfo %1 {%@2 %self} - #Class forward info -onerror ::nsf::infoError ::nx::classInfo %1 {%@2 %self} - Class method info args { - # In case Class.info is applied on an object (via mixins), do "next" - if {![::nsf::objectproperty [::nsf::current object] class]} next else { - if {[catch {::nx::classInfo [lindex $args 0] [::nsf::current object] {*}[lrange $args 1 end]} result]} { - ::nsf::infoError $result - } - return $result - } - } + Class forward info -onerror ::nsf::infoError ::nx::classInfo %1 {%@2 %self} + ::nsf::methodproperty nx::Class info class-only true + #Class method info args { + # # In case Class.info is applied on an object (via mixins), do "next" + # if {![::nsf::objectproperty [::nsf::current object] class]} next else { + # if {[catch {::nx::classInfo [lindex $args 0] [::nsf::current object] {*}[lrange $args 1 end]} result]} { +# ::nsf::infoError $result +# } +# return $result +# } +# } Class method filterguard {filter guard} { # In case Class.filterguard is applied on an object (via mixins), do "next"