Index: TODO =================================================================== diff -u -rd8d920f2976691dcf8e2a68b336eb253385030f6 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- TODO (.../TODO) (revision d8d920f2976691dcf8e2a68b336eb253385030f6) +++ TODO (.../TODO) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -1064,6 +1064,10 @@ - extended regression test - updated migration guide +- made Class.info, Class.mixin, Class.filter robust against per-object + mixins from meta-classes +- extended regression test + TODO: - nameing * self/current: Index: generic/gentclAPI.decls =================================================================== diff -u -rd8d920f2976691dcf8e2a68b336eb253385030f6 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision d8d920f2976691dcf8e2a68b336eb253385030f6) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -851,7 +851,7 @@ {-argName "name"} } infoClassMethod methods XOTclClassInfoMethodsMethod { - {-argName "object" -type class} + {-argName "class" -type class} {-argName "-methodtype" -nrargs 1 -type "all|scripted|builtin|alias|forwarder|object|setter"} {-argName "-callprotection" -nrargs 1 -type "all|protected|public" -default public} {-argName "-nomixins"} Index: generic/tclAPI.h =================================================================== diff -u -rd8d920f2976691dcf8e2a68b336eb253385030f6 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- generic/tclAPI.h (.../tclAPI.h) (revision d8d920f2976691dcf8e2a68b336eb253385030f6) +++ generic/tclAPI.h (.../tclAPI.h) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -236,7 +236,7 @@ static int XOTclClassInfoHeritageMethod(Tcl_Interp *interp, XOTclClass *class, CONST char *pattern); static int XOTclClassInfoInstancesMethod(Tcl_Interp *interp, XOTclClass *class, int withClosure, CONST char *patternString, XOTclObject *patternObj); static int XOTclClassInfoMethodMethod(Tcl_Interp *interp, XOTclClass *class, int infomethodsubcmd, CONST char *name); -static int XOTclClassInfoMethodsMethod(Tcl_Interp *interp, XOTclClass *object, int withMethodtype, int withCallprotection, int withNomixins, int withIncontext, CONST char *pattern); +static int XOTclClassInfoMethodsMethod(Tcl_Interp *interp, XOTclClass *class, int withMethodtype, int withCallprotection, int withNomixins, int withIncontext, CONST char *pattern); static int XOTclClassInfoMixinMethod(Tcl_Interp *interp, XOTclClass *class, int withClosure, int withGuards, CONST char *patternString, XOTclObject *patternObj); static int XOTclClassInfoMixinOfMethod(Tcl_Interp *interp, XOTclClass *class, int withClosure, int withScope, CONST char *patternString, XOTclObject *patternObj); static int XOTclClassInfoMixinguardMethod(Tcl_Interp *interp, XOTclClass *class, CONST char *mixin); @@ -675,15 +675,15 @@ &pc) != TCL_OK) { return TCL_ERROR; } else { - XOTclClass *object = (XOTclClass *)pc.clientData[0]; + XOTclClass *class = (XOTclClass *)pc.clientData[0]; int withMethodtype = (int )PTR2INT(pc.clientData[1]); int withCallprotection = (int )PTR2INT(pc.clientData[2]); int withNomixins = (int )PTR2INT(pc.clientData[3]); int withIncontext = (int )PTR2INT(pc.clientData[4]); CONST char *pattern = (CONST char *)pc.clientData[5]; parseContextRelease(&pc); - return XOTclClassInfoMethodsMethod(interp, object, withMethodtype, withCallprotection, withNomixins, withIncontext, pattern); + return XOTclClassInfoMethodsMethod(interp, class, withMethodtype, withCallprotection, withNomixins, withIncontext, pattern); } } @@ -1959,7 +1959,7 @@ {"name", 0, 0, convertToString}} }, {"::nsf::cmd::ClassInfo::methods", XOTclClassInfoMethodsMethodStub, 6, { - {"object", 0, 0, convertToClass}, + {"class", 0, 0, convertToClass}, {"-methodtype", 0, 1, convertToMethodtype}, {"-callprotection", 0, 1, convertToCallprotection}, {"-nomixins", 0, 0, convertToString}, Index: generic/xotcl.c =================================================================== diff -u -rd8d920f2976691dcf8e2a68b336eb253385030f6 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- generic/xotcl.c (.../xotcl.c) (revision d8d920f2976691dcf8e2a68b336eb253385030f6) +++ generic/xotcl.c (.../xotcl.c) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -11973,9 +11973,21 @@ XOTclClassOpt *clopt = NULL, *nclopt = NULL; int i; - /*fprintf(stderr, "XOTclRelationCmd %s rel=%d val='%s'\n", - objectName(object), relationtype, valueObj ? ObjStr(valueObj) : "NULL");*/ + /* fprintf(stderr, "XOTclRelationCmd %s rel=%d val='%s'\n", + objectName(object), relationtype, valueObj ? ObjStr(valueObj) : "NULL");*/ + if (relationtype == RelationtypeClass_mixinIdx || + relationtype == RelationtypeClass_filterIdx) { + if (XOTclObjectIsClass(object)) { + cl = (XOTclClass *)object; + } else { + /* fall back to per-object case */ + relationtype = (relationtype == RelationtypeClass_mixinIdx) ? + RelationtypeObject_mixinIdx : + RelationtypeObject_filterIdx ; + } + } + switch (relationtype) { case RelationtypeObject_filterIdx: case RelationtypeObject_mixinIdx: @@ -11995,11 +12007,6 @@ case RelationtypeClass_mixinIdx: case RelationtypeClass_filterIdx: - if (XOTclObjectIsClass(object)) { - cl = (XOTclClass *)object; - } else { - return XOTclObjErrType(interp, object->cmdName, "class", ""); - } if (valueObj == NULL) { clopt = cl->opt; @@ -12018,7 +12025,7 @@ case RelationtypeSuperclassIdx: if (!XOTclObjectIsClass(object)) - return XOTclObjErrType(interp, object->cmdName, "class", ""); + return XOTclObjErrType(interp, object->cmdName, "class", "relationtype"); cl = (XOTclClass *)object; if (valueObj == NULL) { return ListSuperclasses(interp, cl, NULL, 0); @@ -12041,7 +12048,7 @@ XOTclClass *metaClass; if (!XOTclObjectIsClass(object)) - return XOTclObjErrType(interp, object->cmdName, "class", ""); + return XOTclObjErrType(interp, object->cmdName, "class", "relationtype"); cl = (XOTclClass *)object; if (valueObj == NULL) { Index: library/nx/nx.tcl =================================================================== diff -u -re548a952433b4d26794f535995c9ed1ababe8807 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- library/nx/nx.tcl (.../nx.tcl) (revision e548a952433b4d26794f535995c9ed1ababe8807) +++ library/nx/nx.tcl (.../nx.tcl) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -393,7 +393,16 @@ # 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 forward info -onerror ::nsf::infoError ::nx::classInfo %1 {%@2 %self} + Class method info args { + # In case, the Class-info is applied on an object (via mixins) + if {![::nsf::objectproperty [self] class]} next else { + if {[catch {::nx::classInfo [lindex $args 0] [self] {*}[lrange $args 1 end]} result]} { + ::nsf::infoError $result + } + return $result + } + } # # definition of "abstract method foo ...." Index: tests/info-method.tcl =================================================================== diff -u -rd8d920f2976691dcf8e2a68b336eb253385030f6 -rfb10f773e288e5a05cf0e04c5fd8cf0514fdf963 --- tests/info-method.tcl (.../info-method.tcl) (revision d8d920f2976691dcf8e2a68b336eb253385030f6) +++ tests/info-method.tcl (.../info-method.tcl) (revision fb10f773e288e5a05cf0e04c5fd8cf0514fdf963) @@ -82,4 +82,8 @@ ? {o info callable method bar} "::nsf::classes::nx::Class::bar" ? {o info callable methods bar} bar ? {o bar} Class.bar + + ? {o method foo {} {return o.foo}} "::o::foo" + ? {o info methods} "foo" + ? {o mixin ""} "" }