Index: generic/nsf.c =================================================================== diff -u -r770232a210b63fdafc5e5e4a2caf45fa5097c6fe -r9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4 --- generic/nsf.c (.../nsf.c) (revision 770232a210b63fdafc5e5e4a2caf45fa5097c6fe) +++ generic/nsf.c (.../nsf.c) (revision 9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4) @@ -20622,7 +20622,7 @@ case RelationtypeClass_mixinIdx: return clopt ? MixinInfo(interp, clopt->classMixins, NULL, 1, NULL) : TCL_OK; case RelationtypeClass_filterIdx: - return objopt ? FilterInfo(interp, clopt->classFilters, NULL, 1, 0) : TCL_OK; + return clopt ? FilterInfo(interp, clopt->classFilters, NULL, 1, 0) : TCL_OK; } } @@ -20748,19 +20748,27 @@ break; } - case RelationtypeObject_filterIdx: + case RelationtypeObject_filterIdx: + { + NsfCmdList *newFilterCmdList = NULL; - if (objopt->objFilters) { - CmdListFree(&objopt->objFilters, GuardDel); - } - object->flags &= ~NSF_FILTER_ORDER_VALID; - for (i = 0; i < oc; i ++) { - if (FilterAdd(interp, &objopt->objFilters, ov[i], object, 0) != TCL_OK) { - return TCL_ERROR; + for (i = 0; i < oc; i ++) { + if (FilterAdd(interp, &newFilterCmdList, ov[i], object, 0) != TCL_OK) { + CmdListFree(&newFilterCmdList, GuardDel); + return TCL_ERROR; + } } + + if (objopt->objFilters) { + CmdListFree(&objopt->objFilters, GuardDel); + } + + object->flags &= ~NSF_FILTER_ORDER_VALID; + objopt->objFilters = newFilterCmdList; + + /*FilterComputeDefined(interp, object);*/ + break; } - /*FilterComputeDefined(interp, object);*/ - break; case RelationtypeClass_mixinIdx: { @@ -20808,22 +20816,31 @@ break; } - case RelationtypeClass_filterIdx: + case RelationtypeClass_filterIdx: + { + NsfCmdList *newFilterCmdList = NULL; - if (clopt->classFilters) { - CmdListFree(&clopt->classFilters, GuardDel); - } - if (FiltersDefined(interp) > 0) { - NsfClasses *subClasses = TransitiveSubClasses(cl); - FilterInvalidateObjOrders(interp, cl, subClasses); - NsfClassListFree(subClasses); - } - for (i = 0; i < oc; i ++) { - if (FilterAdd(interp, &clopt->classFilters, ov[i], 0, cl) != TCL_OK) { - return TCL_ERROR; + for (i = 0; i < oc; i ++) { + if (FilterAdd(interp, &newFilterCmdList, ov[i], 0, cl) != TCL_OK) { + CmdListFree(&newFilterCmdList, GuardDel); + return TCL_ERROR; + } } + + if (clopt->classFilters) { + CmdListFree(&clopt->classFilters, GuardDel); + } + + if (FiltersDefined(interp) > 0) { + NsfClasses *subClasses = TransitiveSubClasses(cl); + FilterInvalidateObjOrders(interp, cl, subClasses); + NsfClassListFree(subClasses); + } + + clopt->classFilters = newFilterCmdList; + + break; } - break; } NsfRelationCmd(interp, object, relationtype, NULL); Index: tests/info-method.test =================================================================== diff -u -rf61ee3dfc17d8cf04a0dc9ada9cb0f939514a511 -r9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4 --- tests/info-method.test (.../info-method.test) (revision f61ee3dfc17d8cf04a0dc9ada9cb0f939514a511) +++ tests/info-method.test (.../info-method.test) (revision 9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4) @@ -394,7 +394,7 @@ nx::Class create Foo ? {Foo method f args ::nx::next} "::nsf::classes::Foo::f" ? {Foo method f2 args ::nx::next} "::nsf::classes::Foo::f2" - ? {Foo filter {f f2}} "" + ? {Foo filter {f f2}} "f f2" ? {Foo info filter methods} "f f2" ? {Foo filter guard f {2 == 2}} "" ? {Foo info filter guard f} "2 == 2" Index: tests/interceptor-slot.test =================================================================== diff -u -r3f398b58b5e8342bf3bed0e325e29b8c811ef7e2 -r9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4 --- tests/interceptor-slot.test (.../interceptor-slot.test) (revision 3f398b58b5e8342bf3bed0e325e29b8c811ef7e2) +++ tests/interceptor-slot.test (.../interceptor-slot.test) (revision 9124d823b4eb4a8b5969b9fa1b6eab7252ba83b4) @@ -151,6 +151,62 @@ ? {O info precedence} "::M1 ::nx::Class ::nx::Object" } +Test case filter-relation { + nx::Class create CC { + :public method filterA args {next} + :public method filterB args {next} + :public class method filterC args {next} + :create cc { + :public method filterD args {next} + } + } + + ? {::nsf::relation cc object-filter} "" + ? {cc info filter methods} "" + ? {::nsf::relation cc object-filter filterA} filterA + ? {cc info filter methods} "filterA" + ? {cc filter filterB} "filterB" + ? {::nsf::relation cc object-filter} "filterB" + ? {cc info filter methods} "filterB" + ? {cc filter add filterD} "filterD filterB" + ? {::nsf::relation cc object-filter} "filterD filterB" + ? {cc info filter methods} "filterD filterB" + ? {cc filter delete filterB} "filterD" + ? {::nsf::relation cc object-filter} "filterD" + ? {cc info filter methods} "filterD" + ? {catch {::nsf::relation cc object-filter UNKNOWN}} 1 + ? {::nsf::relation cc object-filter} "filterD" + ? {cc info filter methods} "filterD" + + ? {::nsf::relation CC object-filter} "" + ? {CC class info filter methods} "" + ? {::nsf::relation CC object-filter filterC} "filterC" + ? {::nsf::relation CC object-filter} "filterC" + ? {CC class info filter methods} "filterC" + ? {::nsf::relation CC object-filter ""} "" + ? {::nsf::relation CC object-filter} "" + ? {CC class info filter methods} "" + + ? {::nsf::relation CC class-filter} "" + ? {CC info filter methods} "" + ? {::nsf::relation CC class-filter filterA} "filterA" + ? {::nsf::relation CC class-filter} "filterA" + ? {CC info filter methods} "filterA" + ? {CC filter add filterB} "filterB filterA" + ? {::nsf::relation CC class-filter} "filterB filterA" + ? {CC info filter methods} "filterB filterA" + ? {CC filter delete filterA} "filterB" + ? {::nsf::relation CC class-filter} "filterB" + ? {CC info filter methods} "filterB" + ? {catch {::nsf::relation CC class-filter UNKNOWN}} 1 + ? {::nsf::relation CC class-filter} "filterB" + ? {CC info filter methods} "filterB" + ? {::nsf::relation CC class-filter ""} "" + ? {::nsf::relation CC class-filter} "" + ? {CC info filter methods} "" +} + + Test parameter count 3 Test case "filter-and-creation" { Class create Foo {