Index: generic/nsf.c =================================================================== diff -u -r9ab7249b16aeb0ea906e3d614fee429edab1cfda -rbef777ff411770b97736e35a87cb23e23c7d7f83 --- generic/nsf.c (.../nsf.c) (revision 9ab7249b16aeb0ea906e3d614fee429edab1cfda) +++ generic/nsf.c (.../nsf.c) (revision bef777ff411770b97736e35a87cb23e23c7d7f83) @@ -15784,6 +15784,13 @@ Tcl_SetObjResult(interp, MethodHandleObj(regObject, withPer_object, methodName)); return TCL_OK; } + case InfomethodsubcmdOriginIdx: + { + Tcl_SetObjResult(interp, MethodHandleObj(defObject, + NsfObjectIsClass(defObject) ? withPer_object : 1, + Tcl_GetCommandName(interp, cmd))); + return TCL_OK; + } case InfomethodsubcmdExistsIdx: { Tcl_SetObjResult(interp, Tcl_NewIntObj(1)); @@ -20933,11 +20940,10 @@ /* objectInfoMethod method NsfObjInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|exists|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} + {-argName "infomethodsubcmd" -type "args|body|exists|definition|handle|origin|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name" -required 1 -type tclobj} } */ - static int NsfObjInfoMethodMethod(Tcl_Interp *interp, NsfObject *object, int subcmd, Tcl_Obj *methodNameObj) { @@ -21230,11 +21236,10 @@ /* classInfoMethod method NsfClassInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|exists|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} + {-argName "infomethodsubcmd" -type "args|body|exists|definition|handle|origin|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name" -required 1 -type tclobj} } */ - static int NsfClassInfoMethodMethod(Tcl_Interp *interp, NsfClass *class, int subcmd, Tcl_Obj *methodNameObj) { @@ -21248,8 +21253,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 method %s\n", - &class->object, regObject, defObject, fromClassNS, cmd, methodName1);*/ + "NsfClassInfoMethodMethod object %p regObject %p defObject %p %s fromClass %d cmd %p method %s\n", + &class->object, regObject, defObject, ObjectName(defObject), fromClassNS, cmd, methodName1);*/ result = ListMethod(interp, regObject ? regObject : &class->object, defObject ? defObject : &class->object, Index: generic/nsfAPI.decls =================================================================== diff -u -r9b6d912b4fa7ce4cfa982e28b511b9e104985809 -rbef777ff411770b97736e35a87cb23e23c7d7f83 --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision 9b6d912b4fa7ce4cfa982e28b511b9e104985809) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision bef777ff411770b97736e35a87cb23e23c7d7f83) @@ -349,7 +349,7 @@ {-argName "pattern" -required 0} } objectInfoMethod method NsfObjInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|exists|handle|parameter|parametersyntax|type|precondition|postcondition|submethods"} + {-argName "infomethodsubcmd" -type "args|body|definition|exists|handle|origin|parameter|parametersyntax|type|precondition|postcondition|submethods"} {-argName "name" -required 1 -type tclobj} } objectInfoMethod methods NsfObjInfoMethodsMethod { @@ -404,7 +404,7 @@ } classInfoMethod method NsfClassInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|exists|handle|parameter|parametersyntax|type|precondition|postcondition|submethods"} + {-argName "infomethodsubcmd" -type "args|body|definition|exists|handle|origin|parameter|parametersyntax|type|precondition|postcondition|submethods"} {-argName "name" -required 1 -type tclobj} } classInfoMethod methods NsfClassInfoMethodsMethod { Index: generic/nsfAPI.h =================================================================== diff -u -r9b6d912b4fa7ce4cfa982e28b511b9e104985809 -rbef777ff411770b97736e35a87cb23e23c7d7f83 --- generic/nsfAPI.h (.../nsfAPI.h) (revision 9b6d912b4fa7ce4cfa982e28b511b9e104985809) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision bef777ff411770b97736e35a87cb23e23c7d7f83) @@ -1,10 +1,10 @@ -enum InfomethodsubcmdIdx {InfomethodsubcmdNULL, InfomethodsubcmdArgsIdx, InfomethodsubcmdBodyIdx, InfomethodsubcmdDefinitionIdx, InfomethodsubcmdExistsIdx, InfomethodsubcmdHandleIdx, InfomethodsubcmdParameterIdx, InfomethodsubcmdParametersyntaxIdx, InfomethodsubcmdTypeIdx, InfomethodsubcmdPreconditionIdx, InfomethodsubcmdPostconditionIdx, InfomethodsubcmdSubmethodsIdx}; +enum InfomethodsubcmdIdx {InfomethodsubcmdNULL, InfomethodsubcmdArgsIdx, InfomethodsubcmdBodyIdx, InfomethodsubcmdDefinitionIdx, InfomethodsubcmdExistsIdx, InfomethodsubcmdHandleIdx, InfomethodsubcmdOriginIdx, InfomethodsubcmdParameterIdx, InfomethodsubcmdParametersyntaxIdx, InfomethodsubcmdTypeIdx, InfomethodsubcmdPreconditionIdx, InfomethodsubcmdPostconditionIdx, InfomethodsubcmdSubmethodsIdx}; static int ConvertToInfomethodsubcmd(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { int index, result; - static CONST char *opts[] = {"args", "body", "definition", "exists", "handle", "parameter", "parametersyntax", "type", "precondition", "postcondition", "submethods", NULL}; + static CONST char *opts[] = {"args", "body", "definition", "exists", "handle", "origin", "parameter", "parametersyntax", "type", "precondition", "postcondition", "submethods", NULL}; (void)pPtr; result = Tcl_GetIndexFromObj(interp, objPtr, opts, "infomethodsubcmd", 0, &index); *clientData = (ClientData) INT2PTR(index + 1); @@ -185,7 +185,7 @@ static enumeratorConverterEntry enumeratorConverterEntries[] = { {ConvertToScope, "all|class|object"}, {ConvertToInfoobjectparametersubcmd, "list|name|parameter|parametersyntax"}, - {ConvertToInfomethodsubcmd, "args|body|definition|exists|handle|parameter|parametersyntax|type|precondition|postcondition|submethods"}, + {ConvertToInfomethodsubcmd, "args|body|definition|exists|handle|origin|parameter|parametersyntax|type|precondition|postcondition|submethods"}, {ConvertToCallprotection, "all|protected|public"}, {ConvertToMethodtype, "all|scripted|builtin|alias|forwarder|object|setter|nsfproc"}, {ConvertToFrame, "method|object|default"}, Index: tests/info-method.test =================================================================== diff -u -rd15bb1fa36c4f2cf118b2ce915928294e762d336 -rbef777ff411770b97736e35a87cb23e23c7d7f83 --- tests/info-method.test (.../info-method.test) (revision d15bb1fa36c4f2cf118b2ce915928294e762d336) +++ tests/info-method.test (.../info-method.test) (revision bef777ff411770b97736e35a87cb23e23c7d7f83) @@ -956,4 +956,26 @@ ? [list ::nsf::method::registered $h1] ::o } +} + +# +# Testing "... info method orgin ..." (in contrast to "... info method +# handle ..."). "origin" always points to the definintion handle, +# "handle" alone is the registration handle. +# + +nx::Test case method-origin { + nx::Class create C + ? {set implHandle [C public method "foo bar" {x} {;}]} "::C::slot::__foo::bar" + ? {set regHandle [C info method handle "foo bar"]} "::nsf::classes::C::foo bar" + ? {set origin [C info method origin "foo bar"]} "::C::slot::__foo::bar" + + ? {set implHandle [C public class method "foo bar" {x} {;}]} "::C::foo::bar" + ? {set regHandle [C class info method handle "foo bar"]} "::C::foo bar" + ? {set origin [C class info method origin "foo bar"]} "::C::foo::bar" + + Object create o + ? {set implHandle [o public method "foo bar" {x} {;}]} "::o::foo::bar" + ? {set regHandle [o info method handle "foo bar"]} "::o::foo bar" + ? {set origin [o info method origin "foo bar"]} "::o::foo::bar" } \ No newline at end of file