Index: TODO =================================================================== diff -u -r46f5a635968d0c3dfe4c81f80e4ac21350096394 -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- TODO (.../TODO) (revision 46f5a635968d0c3dfe4c81f80e4ac21350096394) +++ TODO (.../TODO) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -5131,7 +5131,10 @@ nsf.c: - improve handling of space in object names - +- added methods + "info lookup filters ?-guards? ?/pattern/?" and + "info lookup methods *-guards? ?/pattern/?" +- extended regression test ======================================================================== TODO: - TODO: update tutorial and migration guide Index: generic/nsf.c =================================================================== diff -u -r9ab3a1839485aefab2e7f412e3cdc89c3cd3adac -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- generic/nsf.c (.../nsf.c) (revision 9ab3a1839485aefab2e7f412e3cdc89c3cd3adac) +++ generic/nsf.c (.../nsf.c) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -10034,7 +10034,9 @@ assert(interp); assert(object); - if (object->filterOrder) FilterResetOrder(object); + if (object->filterOrder) { + FilterResetOrder(object); + } /* fprintf(stderr, " List: ", ObjectName(object)); */ @@ -28173,7 +28175,26 @@ return TCL_OK; } + /* +objectInfoMethod lookupfilters NsfObjInfoLookupFiltersMethod { + {-argName "-guards" -nrargs 0 -type switch} + {-argName "pattern"} +} +*/ +static int +NsfObjInfoLookupFiltersMethod(Tcl_Interp *interp, NsfObject *object, int withGuards, CONST char *pattern) { + + assert(interp); + assert(object); + + if (!(object->flags & NSF_FILTER_ORDER_VALID)) { + FilterComputeDefined(interp, object); + } + return FilterInfo(interp, object->filterOrder, pattern, withGuards, 1); +} + +/* objectInfoMethod lookupmethod NsfObjInfoLookupMethodMethod { {-argName "name" -required 1 -type tclobj} } @@ -28329,6 +28350,25 @@ } /* +objectInfoMethod lookupmixins NsfObjInfoLookupMixinsMethod { + {-argName "-guards" -nrargs 0 -type switch} + {-argName "pattern" -type objpattern} +} +*/ +static int +NsfObjInfoLookupMixinsMethod(Tcl_Interp *interp, NsfObject *object, int withGuards, + CONST char *patternString, NsfObject *patternObj) { + assert(interp); + assert(object); + + if (!(object->flags & NSF_MIXIN_ORDER_VALID)) { + MixinComputeDefined(interp, object); + } + return MixinInfo(interp, object->mixinOrder, patternString, withGuards, patternObj); +} + + +/* objectInfoMethod lookupslots NsfObjInfoLookupSlotsMethod { {-argName "-source" -nrargs 1 -type "all|application|system" -default all} {-argName "-type" -required 0 -nrargs 1 -type class} @@ -28444,13 +28484,11 @@ {-argName "-heritage"} {-argName "pattern" -type objpattern} } -} */ static int NsfObjInfoMixinclassesMethod(Tcl_Interp *interp, NsfObject *object, int withGuards, int withHeritage, CONST char *patternString, NsfObject *patternObj) { - assert(interp); assert(object); Index: generic/nsfAPI.decls =================================================================== diff -u -r0a38046eb4aac6c36ac7c72dc8b0fe6da43f7c6e -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision 0a38046eb4aac6c36ac7c72dc8b0fe6da43f7c6e) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -414,6 +414,10 @@ objectInfoMethod lookupfilter NsfObjInfoLookupFilterMethod { {-argName "filter" -required 1} } +objectInfoMethod lookupfilters NsfObjInfoLookupFiltersMethod { + {-argName "-guards" -nrargs 0 -type switch} + {-argName "pattern"} +} objectInfoMethod lookupmethod NsfObjInfoLookupMethodMethod { {-argName "name" -required 1 -type tclobj} } @@ -426,6 +430,10 @@ {-argName "-source" -type "all|application|system" -default all} {-argName "pattern" -required 0} } +objectInfoMethod lookupmixins NsfObjInfoLookupMixinsMethod { + {-argName "-guards" -nrargs 0 -type switch} + {-argName "pattern" -type objpattern} +} objectInfoMethod lookupslots NsfObjInfoLookupSlotsMethod { {-argName "-source" -type "all|application|system" -default all} {-argName "-type" -required 0 -type class} Index: generic/nsfAPI.h =================================================================== diff -u -r0a38046eb4aac6c36ac7c72dc8b0fe6da43f7c6e -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- generic/nsfAPI.h (.../nsfAPI.h) (revision 0a38046eb4aac6c36ac7c72dc8b0fe6da43f7c6e) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -281,7 +281,7 @@ /* just to define the symbol */ -static Nsf_methodDefinition method_definitions[108]; +static Nsf_methodDefinition method_definitions[110]; static CONST char *method_command_namespace_names[] = { "::nsf::methods::object::info", @@ -477,10 +477,14 @@ NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); static int NsfObjInfoLookupFilterMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); +static int NsfObjInfoLookupFiltersMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) + NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); static int NsfObjInfoLookupMethodMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); static int NsfObjInfoLookupMethodsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); +static int NsfObjInfoLookupMixinsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) + NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); static int NsfObjInfoLookupSlotsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4); static int NsfObjInfoMethodMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []) @@ -692,10 +696,14 @@ NSF_nonnull(1) NSF_nonnull(2); static int NsfObjInfoLookupFilterMethod(Tcl_Interp *interp, NsfObject *obj, CONST char *filter) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(3); +static int NsfObjInfoLookupFiltersMethod(Tcl_Interp *interp, NsfObject *obj, int withGuards, CONST char *pattern) + NSF_nonnull(1) NSF_nonnull(2); static int NsfObjInfoLookupMethodMethod(Tcl_Interp *interp, NsfObject *obj, Tcl_Obj *name) NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(3); static int NsfObjInfoLookupMethodsMethod(Tcl_Interp *interp, NsfObject *obj, int withCallprotection, int withIncontext, int withType, int withNomixins, int withPath, int withSource, CONST char *pattern) NSF_nonnull(1) NSF_nonnull(2); +static int NsfObjInfoLookupMixinsMethod(Tcl_Interp *interp, NsfObject *obj, int withGuards, CONST char *patternString, NsfObject *patternObject) + NSF_nonnull(1) NSF_nonnull(2); static int NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *obj, int withSource, NsfClass *withType, CONST char *pattern) NSF_nonnull(1) NSF_nonnull(2); static int NsfObjInfoMethodMethod(Tcl_Interp *interp, NsfObject *obj, int subcmd, Tcl_Obj *name) @@ -814,8 +822,10 @@ NsfObjInfoHasnamespaceMethodIdx, NsfObjInfoIsMethodIdx, NsfObjInfoLookupFilterMethodIdx, + NsfObjInfoLookupFiltersMethodIdx, NsfObjInfoLookupMethodMethodIdx, NsfObjInfoLookupMethodsMethodIdx, + NsfObjInfoLookupMixinsMethodIdx, NsfObjInfoLookupSlotsMethodIdx, NsfObjInfoMethodMethodIdx, NsfObjInfoMethodsMethodIdx, @@ -2800,6 +2810,29 @@ } static int +NsfObjInfoLookupFiltersMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + ParseContext pc; + NsfObject *obj = (NsfObject *)clientData; + + assert(clientData); + assert(objc > 0); + if (unlikely(obj == NULL)) return NsfDispatchClientDataError(interp, clientData, "object", ObjStr(objv[0])); + if (likely(ArgumentParse(interp, objc, objv, obj, objv[0], + method_definitions[NsfObjInfoLookupFiltersMethodIdx].paramDefs, + method_definitions[NsfObjInfoLookupFiltersMethodIdx].nrParameters, 0, NSF_ARGPARSE_BUILTIN, + &pc) == TCL_OK)) { + int withGuards = (int )PTR2INT(pc.clientData[0]); + CONST char *pattern = (CONST char *)pc.clientData[1]; + + assert(pc.status == 0); + return NsfObjInfoLookupFiltersMethod(interp, obj, withGuards, pattern); + + } else { + return TCL_ERROR; + } +} + +static int NsfObjInfoLookupMethodMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { NsfObject *obj = (NsfObject *)clientData; @@ -2847,6 +2880,43 @@ } static int +NsfObjInfoLookupMixinsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + ParseContext pc; + NsfObject *obj = (NsfObject *)clientData; + + assert(clientData); + assert(objc > 0); + if (unlikely(obj == NULL)) return NsfDispatchClientDataError(interp, clientData, "object", ObjStr(objv[0])); + if (likely(ArgumentParse(interp, objc, objv, obj, objv[0], + method_definitions[NsfObjInfoLookupMixinsMethodIdx].paramDefs, + method_definitions[NsfObjInfoLookupMixinsMethodIdx].nrParameters, 0, NSF_ARGPARSE_BUILTIN, + &pc) == TCL_OK)) { + int withGuards = (int )PTR2INT(pc.clientData[0]); + CONST char *patternString = NULL; + NsfObject *patternObject = NULL; + Tcl_Obj *pattern = (Tcl_Obj *)pc.clientData[1]; + int returnCode; + + if (GetMatchObject(interp, pattern, objc>1 ? objv[1] : NULL, &patternObject, &patternString) == -1) { + if (pattern) { + DECR_REF_COUNT2("patternObj", pattern); + } + return TCL_OK; + } + + assert(pc.status == 0); + returnCode = NsfObjInfoLookupMixinsMethod(interp, obj, withGuards, patternString, patternObject); + + if (pattern) { + DECR_REF_COUNT2("patternObj", pattern); + } + return returnCode; + } else { + return TCL_ERROR; + } +} + +static int NsfObjInfoLookupSlotsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ParseContext pc; NsfObject *obj = (NsfObject *)clientData; @@ -3107,7 +3177,7 @@ } } -static Nsf_methodDefinition method_definitions[108] = { +static Nsf_methodDefinition method_definitions[110] = { {"::nsf::methods::class::alloc", NsfCAllocMethodStub, 1, { {"objectName", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, @@ -3511,6 +3581,10 @@ {"::nsf::methods::object::info::lookupfilter", NsfObjInfoLookupFilterMethodStub, 1, { {"filter", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::methods::object::info::lookupfilters", NsfObjInfoLookupFiltersMethodStub, 2, { + {"-guards", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, + {"pattern", 0, 1, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::methods::object::info::lookupmethod", NsfObjInfoLookupMethodMethodStub, 1, { {"name", NSF_ARG_REQUIRED, 1, Nsf_ConvertTo_Tclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, @@ -3523,6 +3597,10 @@ {"-source", 0|NSF_ARG_IS_ENUMERATION, 1, ConvertToSource, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"pattern", 0, 1, Nsf_ConvertTo_String, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::methods::object::info::lookupmixins", NsfObjInfoLookupMixinsMethodStub, 2, { + {"-guards", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, + {"pattern", 0, 1, ConvertToObjpattern, NULL,NULL,"objpattern",NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::methods::object::info::lookupslots", NsfObjInfoLookupSlotsMethodStub, 3, { {"-source", 0|NSF_ARG_IS_ENUMERATION, 1, ConvertToSource, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-type", 0, 1, Nsf_ConvertTo_Class, NULL,NULL,"class",NULL,NULL,NULL,NULL,NULL}, Index: generic/nsfAPI.nxdocindex =================================================================== diff -u -r3cbf24ff95e38976cdc905ec0e8014d9d754ad6f -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- generic/nsfAPI.nxdocindex (.../nsfAPI.nxdocindex) (revision 3cbf24ff95e38976cdc905ec0e8014d9d754ad6f) +++ generic/nsfAPI.nxdocindex (.../nsfAPI.nxdocindex) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -79,8 +79,10 @@ set ::nxdoc::include(::nsf::methods::object::info::hastype) 0 set ::nxdoc::include(::nsf::methods::object::info::is) 0 set ::nxdoc::include(::nsf::methods::object::info::lookupfilter) 0 +set ::nxdoc::include(::nsf::methods::object::info::lookupfilters) 0 set ::nxdoc::include(::nsf::methods::object::info::lookupmethod) 0 set ::nxdoc::include(::nsf::methods::object::info::lookupmethods) 0 +set ::nxdoc::include(::nsf::methods::object::info::lookupmixins) 0 set ::nxdoc::include(::nsf::methods::object::info::lookupslots) 0 set ::nxdoc::include(::nsf::methods::object::info::method) 0 set ::nxdoc::include(::nsf::methods::object::info::methods) 0 Index: library/nx/nx.tcl =================================================================== diff -u -r46f5a635968d0c3dfe4c81f80e4ac21350096394 -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- library/nx/nx.tcl (.../nx.tcl) (revision 46f5a635968d0c3dfe4c81f80e4ac21350096394) +++ library/nx/nx.tcl (.../nx.tcl) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -704,8 +704,10 @@ Object eval { :alias "info lookup filter" ::nsf::methods::object::info::lookupfilter + :alias "info lookup filters" ::nsf::methods::object::info::lookupfilters :alias "info lookup method" ::nsf::methods::object::info::lookupmethod :alias "info lookup methods" ::nsf::methods::object::info::lookupmethods + :alias "info lookup mixins" ::nsf::methods::object::info::lookupmixins :method "info lookup slots" {{-type:class ::nx::Slot} -source pattern:optional} { set cmd [list ::nsf::methods::object::info::lookupslots -type $type] if {[info exists source]} {lappend cmd -source $source} Index: tests/info-method.test =================================================================== diff -u -rf671281a240219965d436e2bfa762baf85274ca6 -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- tests/info-method.test (.../info-method.test) (revision f671281a240219965d436e2bfa762baf85274ca6) +++ tests/info-method.test (.../info-method.test) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -747,15 +747,15 @@ ? {::nx::Object info methods "info"} "info" ? {::nx::Object info methods -path "info"} "" ? {lsort [::nx::Object info methods -path "info lookup *"]} \ - "{info lookup configure parameters} {info lookup configure syntax} {info lookup filter} {info lookup method} {info lookup methods} {info lookup slots} {info lookup variables}" + "{info lookup configure parameters} {info lookup configure syntax} {info lookup filter} {info lookup filters} {info lookup method} {info lookup methods} {info lookup mixins} {info lookup slots} {info lookup variables}" ? {lsort [::nx::Object info methods -path "info *parameter*"]} \ "{info lookup configure parameters} {info object method parameters} {info parameter default} {info parameter name} {info parameter syntax} {info parameter type} {info variable parameter}" ? {lsort [::nx::Object info methods "slots"]} "" ? {lsort [::nx::Object info methods "*slots*"]} "" ? {lsort [::nx::Object info methods -path "*slot*"]} \ "{info lookup slots} {info object slots}" ? {lsort [::nx::Object info methods -path "*filter*"]} \ - "{info lookup filter} {info object filter guard} {info object filter methods} {object filter}" + "{info lookup filter} {info lookup filters} {info object filter guard} {info object filter methods} {object filter}" ::nx::Class create C { :public method "string length" {s} {puts length} Index: tests/interceptor-slot.test =================================================================== diff -u -r46f5a635968d0c3dfe4c81f80e4ac21350096394 -r994c14a5b0e1d662fc4f903f097ed0ee7a130986 --- tests/interceptor-slot.test (.../interceptor-slot.test) (revision 46f5a635968d0c3dfe4c81f80e4ac21350096394) +++ tests/interceptor-slot.test (.../interceptor-slot.test) (revision 994c14a5b0e1d662fc4f903f097ed0ee7a130986) @@ -565,6 +565,10 @@ r leave Uwe r configure -name "Office" ? {set ::_} "enter leave" + ? {r info lookup filters} "::nsf::classes::Room::loggingFilter" + ? {r info lookup filters -guards} {{loggingFilter -guard { + [current calledmethod] in {enter leave} + }}} # Now we define a subclass DangerRoom, which refines the filter by # logging into a "dangerRoomLog". We want here entries for all @@ -589,11 +593,39 @@ ? {set ::_} "enter leave" ? {expr [llength $::dangerRoomLog] > 2} 1 + ? {d info lookup filters} "::nsf::classes::DangerRoom::loggingFilter ::nsf::classes::Room::loggingFilter" + d destroy } # +# Test info lookup mixins (with guards) +# + +nx::test case filter-guard-separately { + nx::Class create M1 + nx::Class create M2 + nx::Class create M3 + nx::Class create C + nx::Class create D -superclass C + + D create d1 -object-mixin M1 + ? {d1 info lookup mixins} ::M1 + + D mixin add {M2 -guard 1} + ? {d1 info lookup mixins} "::M1 ::M2" + + C mixin add M3 + ? {d1 info lookup mixins} "::M1 ::M2 ::M3" + ? {d1 info lookup mixins -guards} "::M1 {::M2 -guard 1} ::M3" + ? {d1 info lookup mixins -guards *2*} "{::M2 -guard 1}" + + d1 object mixin clear + ? {d1 info lookup mixins} "::M2 ::M3" +} + +# # Local variables: # mode: tcl # tcl-indent-level: 2