Index: TODO =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- TODO (.../TODO) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ TODO (.../TODO) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -2709,10 +2709,15 @@ - nsf.c * first version of c-bases "info slots" for classes * switch "-closure" just for class info method + * added switch "-source" to "info slots -closure" + and "info lookup slots" + (similar to "info lookup methods") + * extended regression test TODO: - missing in c-based "info slots": * handling of pattern (needed?) + * handle source (as well in "info lookup slots") * regression tests (eg. "$cls class info slots" vs. "$cls info slots", "-closure") * base objectparameter on "info slots" Index: generic/gentclAPI.decls =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -318,6 +318,7 @@ {-argName "pattern" -required 0} } objectInfoMethod lookupslots NsfObjInfoLookupSlotsMethod { + {-argName "-source" -nrargs 1 -type "all|application|baseclasses" -default all} {-argName "-type" -required 0 -nrargs 1 -type class} } objectInfoMethod method NsfObjInfoMethodMethod { @@ -401,8 +402,9 @@ } classInfoMethod slots NsfClassInfoSlotsMethod { {-argName "-closure"} + {-argName "-source" -nrargs 1 -type "all|application|baseclasses" -default all} {-argName "-type" -required 0 -nrargs 1 -type class} -} + } classInfoMethod subclass NsfClassInfoSubclassMethod { {-argName "-closure"} {-argName "pattern" -type objpattern} Index: generic/nsf.c =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- generic/nsf.c (.../nsf.c) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ generic/nsf.c (.../nsf.c) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -286,6 +286,7 @@ static void NsfCommandRelease(Tcl_Command cmd); static Tcl_Command GetOriginalCommand(Tcl_Command cmd); void NsfDStringArgv(Tcl_DString *dsPtr, int objc, Tcl_Obj *CONST objv[]); +static int MethodSourceMatches(int withSource, NsfClass *cl, NsfObject *object); /* @@ -10355,6 +10356,7 @@ return body; } + /* *---------------------------------------------------------------------- * ComputeSlotObjects -- @@ -10370,7 +10372,8 @@ *---------------------------------------------------------------------- */ static NsfObjects * -ComputeSlotObjects(Tcl_Interp *interp, NsfClasses *precedenceList, NsfClass *type) { +ComputeSlotObjects(Tcl_Interp *interp, NsfClasses *precedenceList, + int withSource, NsfClass *type) { NsfObjects *slotObjects = NULL, **npl = &slotObjects; NsfObject *childObject, *tmpObject; Tcl_HashTable slotTable; @@ -10381,6 +10384,8 @@ for (clPtr = precedenceList; clPtr; clPtr = clPtr->nextPtr) { Tcl_DString ds, *dsPtr = &ds; + + if (!MethodSourceMatches(withSource, clPtr->cl, NULL)) continue; DSTRING_INIT(dsPtr); Tcl_DStringAppend(dsPtr, ClassName(clPtr->cl), -1); @@ -14319,21 +14324,23 @@ return TCL_OK; } -static int -ProtectionMatches(int withCallprotection, Tcl_Command cmd) { - int result, isProtected = Tcl_Command_flags(cmd) & NSF_CMD_PROTECTED_METHOD; - if (withCallprotection == CallprotectionNULL) { - withCallprotection = CallprotectionPublicIdx; - } - switch (withCallprotection) { - case CallprotectionAllIdx: result = 1; break; - case CallprotectionPublicIdx: result = (isProtected == 0); break; - case CallprotectionProtectedIdx: result = (isProtected != 0); break; - default: result = 1; - } - return result; -} +/* + *---------------------------------------------------------------------- + * MethodSourceMatches -- + * + * Check, whether the provided class or object (mutually exclusive) matches + * with the required method source (typically all|application|baseclasses). + * + * Results: + * Returns true or false + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + static int MethodSourceMatches(int withSource, NsfClass *cl, NsfObject *object) { int isBaseClass; @@ -14357,6 +14364,24 @@ return 0; } + +/* + *---------------------------------------------------------------------- + * MethodTypeMatches -- + * + * Check, whether the provided method (specified as a cmd) matches with the + * required method type (typically + * all|scripted|builtin|alias|forwarder|object|setter). + * + * Results: + * Returns true or false + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + static int MethodTypeMatches(Tcl_Interp *interp, int methodType, Tcl_Command cmd, NsfObject *object, CONST char *methodName, int withPer_object, int *isObject) { @@ -14404,7 +14429,38 @@ /* *---------------------------------------------------------------------- + * ProtectionMatches -- * + * Check, whether the provided method (specified as a cmd) matches with the + * required call-protection (typically all|protected|public). + * + * Results: + * Returns true or false + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +ProtectionMatches(int withCallprotection, Tcl_Command cmd) { + int result, isProtected = Tcl_Command_flags(cmd) & NSF_CMD_PROTECTED_METHOD; + if (withCallprotection == CallprotectionNULL) { + withCallprotection = CallprotectionPublicIdx; + } + switch (withCallprotection) { + case CallprotectionAllIdx: result = 1; break; + case CallprotectionPublicIdx: result = (isProtected == 0); break; + case CallprotectionProtectedIdx: result = (isProtected != 0); break; + default: result = 1; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * * ListMethodKeys -- * * List the method names contained in the specified hash table @@ -18735,17 +18791,19 @@ /* objectInfoMethod lookupslots NsfObjInfoLookupSlotsMethod { + {-argName "-source" -nrargs 1 -type "all|application|baseclasses" -default all} {-argName "-type" -required 0 -nrargs 1 -type class} } */ static int -NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *object, NsfClass *type) { +NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *object, int withSource, NsfClass *type) { NsfObjects *pl, *slotObjects; Tcl_Obj *list = Tcl_NewListObj(0, NULL); NsfClasses *fullPrecendenceList; fullPrecendenceList = ComputePrecedenceList(interp, object, NULL /* pattern*/, 1, 1); - slotObjects = ComputeSlotObjects(interp, fullPrecendenceList, type); + if (withSource == 0) {withSource = 1;} + slotObjects = ComputeSlotObjects(interp, fullPrecendenceList, withSource, type); for (pl=slotObjects; pl; pl = pl->nextPtr) { Tcl_ListObjAppendElement(interp, list, pl->obj->cmdName); @@ -19198,11 +19256,13 @@ /* classInfoMethod slots NsfClassInfoSlotsMethod { {-argName "-closure"} + {-argName "-source" -nrargs 1 -type "all|application|baseclasses"} {-argName "-type" -required 0 -nrargs 1 -type class} } */ static int -NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *class, int withClosure, NsfClass *type) { +NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *class, + int withClosure, int withSource, NsfClass *type) { NsfClasses *clPtr, *intrinsic, *checkList = NULL, *mixinClasses = NULL, *precedenceList = NULL; Tcl_Obj *list = Tcl_NewListObj(0, NULL); @@ -19219,15 +19279,17 @@ NsfClassListAdd(&precedenceList, clPtr->cl, NULL); } } + NsfClassListAdd(&precedenceList, class, NULL); for (clPtr = intrinsic->nextPtr; clPtr; clPtr = clPtr->nextPtr) { NsfClassListAdd(&precedenceList, clPtr->cl, NULL); } } else { NsfClassListAdd(&precedenceList, class, NULL); } + //NsfClassListPrint("precedence", precedenceList); + if (withSource == 0) {withSource = 1;} + slotObjects = ComputeSlotObjects(interp, precedenceList, withSource, type); - slotObjects = ComputeSlotObjects(interp, precedenceList, type); - for (pl = slotObjects; pl; pl = pl->nextPtr) { Tcl_ListObjAppendElement(interp, list, pl->obj->cmdName); } Index: generic/tclAPI.h =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- generic/tclAPI.h (.../tclAPI.h) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ generic/tclAPI.h (.../tclAPI.h) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -51,6 +51,19 @@ return result; } +enum SourceIdx {SourceNULL, SourceAllIdx, SourceApplicationIdx, SourceBaseclassesIdx}; + +static int ConvertToSource(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, + ClientData *clientData, Tcl_Obj **outObjPtr) { + int index, result; + static CONST char *opts[] = {"all", "application", "baseclasses", NULL}; + (void)pPtr; + result = Tcl_GetIndexFromObj(interp, objPtr, opts, "-source", 0, &index); + *clientData = (ClientData) INT2PTR(index + 1); + *outObjPtr = objPtr; + return result; +} + enum FrameIdx {FrameNULL, FrameMethodIdx, FrameObjectIdx, FrameDefaultIdx}; static int ConvertToFrame(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, @@ -142,20 +155,7 @@ return result; } -enum SourceIdx {SourceNULL, SourceAllIdx, SourceApplicationIdx, SourceBaseclassesIdx}; -static int ConvertToSource(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, - ClientData *clientData, Tcl_Obj **outObjPtr) { - int index, result; - static CONST char *opts[] = {"all", "application", "baseclasses", NULL}; - (void)pPtr; - result = Tcl_GetIndexFromObj(interp, objPtr, opts, "-source", 0, &index); - *clientData = (ClientData) INT2PTR(index + 1); - *outObjPtr = objPtr; - return result; -} - - static enumeratorConverterEntry enumeratorConverterEntries[] = { {ConvertToScope, "all|class|object"}, {ConvertToInfomethodsubcmd, "args|body|definition|exists|handle|parameter|parametersyntax|type|precondition|postcondition|submethods"}, @@ -290,7 +290,7 @@ static int NsfClassInfoMixinOfMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, int withScope, CONST char *patternString, NsfObject *patternObj); static int NsfClassInfoMixinclassesMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, int withGuards, int withHeritage, CONST char *patternString, NsfObject *patternObj); static int NsfClassInfoMixinguardMethod(Tcl_Interp *interp, NsfClass *cl, CONST char *mixin); -static int NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, NsfClass *withType); +static int NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, int withSource, NsfClass *withType); static int NsfClassInfoSubclassMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, CONST char *patternString, NsfObject *patternObj); static int NsfClassInfoSuperclassMethod(Tcl_Interp *interp, NsfClass *cl, int withClosure, Tcl_Obj *pattern); static int NsfAliasCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, CONST char *methodName, int withFrame, Tcl_Obj *cmdName); @@ -353,7 +353,7 @@ static int NsfObjInfoLookupFilterMethod(Tcl_Interp *interp, NsfObject *obj, CONST char *filter); static int NsfObjInfoLookupMethodMethod(Tcl_Interp *interp, NsfObject *obj, Tcl_Obj *name); static int NsfObjInfoLookupMethodsMethod(Tcl_Interp *interp, NsfObject *obj, int withCallprotection, int withIncontext, int withMethodtype, int withNomixins, int withPath, int withSource, CONST char *pattern); -static int NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *obj, NsfClass *withType); +static int NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *obj, int withSource, NsfClass *withType); static int NsfObjInfoMethodMethod(Tcl_Interp *interp, NsfObject *obj, int infomethodsubcmd, Tcl_Obj *name); static int NsfObjInfoMethodsMethod(Tcl_Interp *interp, NsfObject *obj, int withCallprotection, int withIncontext, int withMethodtype, int withNomixins, int withPath, CONST char *pattern); static int NsfObjInfoMixinclassesMethod(Tcl_Interp *interp, NsfObject *obj, int withGuards, int withHeritage, CONST char *patternString, NsfObject *patternObj); @@ -858,10 +858,11 @@ return TCL_ERROR; } else { int withClosure = (int )PTR2INT(pc.clientData[0]); - NsfClass *withType = (NsfClass *)pc.clientData[1]; + int withSource = (int )PTR2INT(pc.clientData[1]); + NsfClass *withType = (NsfClass *)pc.clientData[2]; assert(pc.status == 0); - return NsfClassInfoSlotsMethod(interp, cl, withClosure, withType); + return NsfClassInfoSlotsMethod(interp, cl, withClosure, withSource, withType); } } @@ -2026,10 +2027,11 @@ &pc) != TCL_OK) { return TCL_ERROR; } else { - NsfClass *withType = (NsfClass *)pc.clientData[0]; + int withSource = (int )PTR2INT(pc.clientData[0]); + NsfClass *withType = (NsfClass *)pc.clientData[1]; assert(pc.status == 0); - return NsfObjInfoLookupSlotsMethod(interp, obj, withType); + return NsfObjInfoLookupSlotsMethod(interp, obj, withSource, withType); } } @@ -2261,8 +2263,9 @@ {"::nsf::methods::class::info::mixinguard", NsfClassInfoMixinguardMethodStub, 1, { {"mixin", NSF_ARG_REQUIRED, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::methods::class::info::slots", NsfClassInfoSlotsMethodStub, 2, { +{"::nsf::methods::class::info::slots", NsfClassInfoSlotsMethodStub, 3, { {"-closure", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-source", 0|NSF_ARG_IS_ENUMERATION, 1, ConvertToSource, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-type", 0, 1, Nsf_ConvertToClass, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::nsf::methods::class::info::subclass", NsfClassInfoSubclassMethodStub, 2, { @@ -2521,7 +2524,8 @@ {"-source", 0|NSF_ARG_IS_ENUMERATION, 1, ConvertToSource, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"pattern", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::methods::object::info::lookupslots", NsfObjInfoLookupSlotsMethodStub, 1, { +{"::nsf::methods::object::info::lookupslots", NsfObjInfoLookupSlotsMethodStub, 2, { + {"-source", 0|NSF_ARG_IS_ENUMERATION, 1, ConvertToSource, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-type", 0, 1, Nsf_ConvertToClass, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::nsf::methods::object::info::method", NsfObjInfoMethodMethodStub, 2, { Index: library/nx/nx.tcl =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- library/nx/nx.tcl (.../nx.tcl) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ library/nx/nx.tcl (.../nx.tcl) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -538,9 +538,12 @@ :alias "info mixin guard" ::nsf::methods::class::info::mixinguard :alias "info mixin classes" ::nsf::methods::class::info::mixinclasses :alias "info mixinof" ::nsf::methods::class::info::mixinof - :method "info slots" {{-type ::nx::Slot} pattern:optional} { + :method "info slots" {{-type ::nx::Slot} -closure:switch -source pattern:optional} { set cmd [list ::nsf::methods::class::info::slots -type $type] + if {[info exists source]} {lappend cmd -source $source} + if {$closure} {lappend cmd -closure} if {[info exists pattern]} {lappend cmd $pattern} + puts stderr XXXXCMD=[list $cmd] ::nsf::my {*}$cmd } :alias "info subclass" ::nsf::methods::class::info::subclass @@ -970,6 +973,8 @@ # Collect the object parameter slots in per-position lists to # ensure partial ordering and avoid sorting. # + #set class [::nsf::relation [self] class] + #foreach slot [nsf::dispatch $class ::nsf::methods::class::info::slots -closure -type ::nx::Slot] {} foreach slot [nsf::dispatch [self] ::nsf::methods::object::info::lookupslots -type ::nx::Slot] { lappend defs([$slot position]) [$slot getParameterSpec] } Index: tests/info-method.test =================================================================== diff -u -re9d5dd4af67bdeeaa3052f5c010d135d899a6dd6 -r164610e4ee54aad4403b5c8940b22ee6ee4ec58a --- tests/info-method.test (.../info-method.test) (revision e9d5dd4af67bdeeaa3052f5c010d135d899a6dd6) +++ tests/info-method.test (.../info-method.test) (revision 164610e4ee54aad4403b5c8940b22ee6ee4ec58a) @@ -233,11 +233,24 @@ :class attribute a2 :method "sub foo" args {;} } + + ? {D info lookup slots} "::nx::Class::slot::superclass ::nx::Class::slot::object-mixin ::nx::Class::slot::mixin ::nx::Class::slot::object-filter ::nx::Class::slot::filter ::nx::Class::slot::attributes ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::__initcmd ::nx::Object::slot::class" + + C create c1 + ? {c1 info precedence} "::C ::nx::Object" + ? {C info heritage} "::nx::Object" + ? {C info slots -closure -source application} "::C::slot::a ::C::slot::b" + ? {C info slots -closure} "::C::slot::a ::C::slot::b ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {C info slots} "::C::slot::a ::C::slot::b" D create d1 - ? {D info lookup slots} "::nx::Class::slot::superclass ::nx::Class::slot::object-mixin ::nx::Class::slot::mixin ::nx::Class::slot::object-filter ::nx::Class::slot::filter ::nx::Class::slot::attributes ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::__initcmd ::nx::Object::slot::class" ? {D info slots} "::D::slot::b ::D::slot::a2 ::D::slot::c" + ? {D info slots -closure -source application} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a" + ? {::nx::Object info method parameter info} "" + + ? {d1 info precedence} "::D ::C ::nx::Object" + ? {d1 info lookup slots} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" } #