Index: TODO =================================================================== diff -u -r3d4cb79342d1f74cdcc39d6d8b87e9c475f2706a -re756bf87414d3f6376327b3a126e5e8ae619302d --- TODO (.../TODO) (revision 3d4cb79342d1f74cdcc39d6d8b87e9c475f2706a) +++ TODO (.../TODO) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -2103,6 +2103,9 @@ - deactivated automatic namespace path copying for child-objects - extended regression test +- added deletion functionality to nsf::mixin +- moved handling of methodNames of c-cmds to ResolveMethodName() +- extended regression test TODO: - info method definition for attributes? Index: generic/nsf.c =================================================================== diff -u -r8c7cda91db207490f2d401595cec6cf784460bb6 -re756bf87414d3f6376327b3a126e5e8ae619302d --- generic/nsf.c (.../nsf.c) (revision 8c7cda91db207490f2d401595cec6cf784460bb6) +++ generic/nsf.c (.../nsf.c) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -1365,10 +1365,11 @@ referencedObject = GetRegObject(interp, cmd, methodName, methodName1, fromClassNS); *regObject = referencedObject; *defObject = referencedObject; + *methodName1 = Tcl_GetCommandName(interp, cmd); if (referencedObject == NULL) { /* * The cmd was not registered on an object or class, but we - * still report back the cmd (might be e.g. a primitive cmd. + * still report back the cmd (might be e.g. a primitive cmd). */ } } else { @@ -12263,6 +12264,9 @@ static int ListCmdParams(Tcl_Interp *interp, Tcl_Command cmd, CONST char *methodName, int withVarnames) { Proc *procPtr = GetTclProcFromCommand(cmd); + + assert(methodName); + if (procPtr) { NsfParamDefs *paramDefs = procPtr ? ParamDefsGet((Tcl_Command)procPtr->cmdPtr) : NULL; Tcl_Obj *list; @@ -12360,16 +12364,7 @@ Tcl_DStringAppend(dsPtr, cmdPtr->nsPtr->fullName, -1); } Tcl_DStringAppend(dsPtr, "::", 2); - - if (methodName != NULL) { - Tcl_DStringAppend(dsPtr, methodName, -1); - } else { - /* - This branch is enter for C-implemented commands, - such as ::nsf::xotclnext - */ - Tcl_DStringAppend(dsPtr, Tcl_GetCommandName(interp,cmd), -1); - } + Tcl_DStringAppend(dsPtr, methodName, -1); /*fprintf(stderr,"Looking up ::nsf::parametersyntax(%s) ...\n",Tcl_DStringValue(dsPtr));*/ parameterSyntaxObj = Tcl_GetVar2Ex(interp, "::nsf::parametersyntax", @@ -12467,6 +12462,8 @@ CONST char *methodName, Tcl_Command cmd, int subcmd, int withPer_object) { + assert(methodName); + /*fprintf(stderr, "ListMethod %s %s cmd %p subcmd %d per-object %d\n", ObjectName(regObject), methodName, cmd, subcmd, withPer_object);*/ @@ -14586,8 +14583,8 @@ NsfClassOpt *clopt = NULL, *nclopt = NULL; int i; - /* fprintf(stderr, "NsfRelationCmd %s rel=%d val='%s'\n", - ObjectName(object), relationtype, valueObj ? ObjStr(valueObj) : "NULL");*/ + /*fprintf(stderr, "NsfRelationCmd %s rel=%d val='%s'\n", + ObjectName(object), relationtype, valueObj ? ObjStr(valueObj) : "NULL");*/ if (relationtype == RelationtypeClass_mixinIdx || relationtype == RelationtypeClass_filterIdx) { @@ -16867,8 +16864,8 @@ cmd = ResolveMethodName(interp, object->nsPtr, methodNameObj, dsPtr, ®Object, &defObject, &methodName1, &fromClassNS); /*fprintf(stderr, - "NsfObjInfoMethodMethod method %s object %p regObject %p defObject %p fromClass %d\n", - ObjStr(methodNameObj), object,regObject,defObject,fromClassNS);*/ + "NsfObjInfoMethodMethod method %s / %s object %p regObject %p defObject %p fromClass %d\n", + ObjStr(methodNameObj), methodName1, object,regObject,defObject,fromClassNS);*/ result = ListMethod(interp, regObject ? regObject : object, defObject ? defObject : object, @@ -17121,8 +17118,8 @@ cmd = ResolveMethodName(interp, class->nsPtr, methodNameObj, dsPtr, ®Object, &defObject, &methodName1, &fromClassNS); /*fprintf(stderr, - "NsfClassInfoMethodMethod object %p regObject %p defObject %p fromClass %d cmd %p\n", - &class->object,regObject,defObject,fromClassNS, cmd);*/ + "NsfClassInfoMethodMethod object %p regObject %p defObject %p fromClass %d cmd %p method %s\n", + &class->object,regObject,defObject,fromClassNS, cmd, methodName1);*/ result = ListMethod(interp, regObject ? regObject : &class->object, defObject ? defObject : &class->object, Index: generic/nsf.tcl =================================================================== diff -u -r8c7cda91db207490f2d401595cec6cf784460bb6 -re756bf87414d3f6376327b3a126e5e8ae619302d --- generic/nsf.tcl (.../nsf.tcl) (revision 8c7cda91db207490f2d401595cec6cf784460bb6) +++ generic/nsf.tcl (.../nsf.tcl) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -40,7 +40,10 @@ # # ::nsf::mixin # - # provide a similar interface as for ::nsf::method, ::nsf::alias, ... + # Provide a similar interface as for ::nsf::method, ::nsf::alias, + # etc.. Semantically, ::nsf::mxiin behaves like a "mixin add", but + # can be used as well for deleting the mixin list (empty last + # argument). # set ::nsf::parametersyntax(::nsf::mixin) "object ?-per-object? classes" @@ -52,9 +55,14 @@ } else { set rel "class-mixin" } - set oldSetting [::nsf::relation $object $rel] - # use uplevel to avoid namespace surprises - uplevel [list ::nsf::relation $object $rel [linsert $oldSetting end $args]] + puts stderr LL=[llength $args]-$args + if {[lindex $args 0] ne ""} { + set oldSetting [::nsf::relation $object $rel] + # use uplevel to avoid namespace surprises + uplevel [list ::nsf::relation $object $rel [linsert $oldSetting 0 $args]] + } else { + uplevel [list ::nsf::relation $object $rel ""] + } } # Index: generic/predefined.h =================================================================== diff -u -r8c7cda91db207490f2d401595cec6cf784460bb6 -re756bf87414d3f6376327b3a126e5e8ae619302d --- generic/predefined.h (.../predefined.h) (revision 8c7cda91db207490f2d401595cec6cf784460bb6) +++ generic/predefined.h (.../predefined.h) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -21,8 +21,11 @@ "set rel \"object-mixin\"\n" "set args [lrange $args 1 end]} else {\n" "set rel \"class-mixin\"}\n" +"puts stderr LL=[llength $args]-$args\n" +"if {[lindex $args 0] ne \"\"} {\n" "set oldSetting [::nsf::relation $object $rel]\n" -"uplevel [list ::nsf::relation $object $rel [linsert $oldSetting end $args]]}\n" +"uplevel [list ::nsf::relation $object $rel [linsert $oldSetting 0 $args]]} else {\n" +"uplevel [list ::nsf::relation $object $rel \"\"]}}\n" "::nsf::provide_method autoname {::nsf::alias autoname ::nsf::methods::object::autoname}\n" "::nsf::provide_method exists {::nsf::alias exists ::nsf::methods::object::exists}\n" "proc ::nsf::exithandler {args} {\n" Index: tests/info-method.test =================================================================== diff -u -rb8b81d5258a35f294599bb755a0cc15cf363972b -re756bf87414d3f6376327b3a126e5e8ae619302d --- tests/info-method.test (.../info-method.test) (revision b8b81d5258a35f294599bb755a0cc15cf363972b) +++ tests/info-method.test (.../info-method.test) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -406,4 +406,7 @@ ? {::nx::Object info method parametersyntax method} "name arguments ?-returns value? body ?-precondition value? ?-postcondition value?" # a forwarder to ::nsf::relation; definition comes via ::nsf::parametersyntax ? {::nx::Object info method parametersyntax mixin} "?classes?|?add class?|?delete class?" + + ? {::nx::Object info method parametersyntax ::nx::next} "?arguments?" + ? {::nx::Object info method parametersyntax ::nsf::xotclnext} "?--noArgs? ?arg ...?" } \ No newline at end of file Index: tests/interceptor-slot.test =================================================================== diff -u -r84c5ee62a46e8fab7b9cc481c87290d387baced9 -re756bf87414d3f6376327b3a126e5e8ae619302d --- tests/interceptor-slot.test (.../interceptor-slot.test) (revision 84c5ee62a46e8fab7b9cc481c87290d387baced9) +++ tests/interceptor-slot.test (.../interceptor-slot.test) (revision e756bf87414d3f6376327b3a126e5e8ae619302d) @@ -22,7 +22,21 @@ C mixin delete M2 ? {c1 info precedence} "::M ::C ::nx::Object" C mixin delete M +? {C info mixin classes} "" +C mixin ::M +C mixin {} +? {C info mixin classes} "" +# +# test nsf::mixin interface +# +::nsf::mixin C ::M +? {C info mixin classes} "::M" +::nsf::mixin C ::M2 +? {C info mixin classes} "::M2 ::M" +::nsf::mixin C "" +? {C info mixin classes} "" + # per-object mixins ? {c1 info precedence} "::C ::nx::Object" c1 mixin add M