Index: TODO =================================================================== diff -u -N -r563d2de98a63e09432eb9b0840434ea5e9b20052 -r0378d1c22ef6e05c54af07058a0315d7a9f20cab --- TODO (.../TODO) (revision 563d2de98a63e09432eb9b0840434ea5e9b20052) +++ TODO (.../TODO) (revision 0378d1c22ef6e05c54af07058a0315d7a9f20cab) @@ -3390,6 +3390,11 @@ * added transparency for per-object private methods * extended regression test +- nsf.c: + * allow protected and private methods to be used as filters + * added regression tests + * some cleanup in regression tests + TODO: - fix interp.test for tcl 8.6 - fix xocomm.test for tcl 8.6 @@ -3400,6 +3405,7 @@ * tests for private + mixins * tests for object-specific private methods * flag "-local" in dispatch is maybe confusing + * -local and filter - nx: * maybe provide a replacement for -attributes, but without the magic variable. Index: generic/nsf.c =================================================================== diff -u -N -rb57f4b6701eadc6f177da91291638d26da3322ba -r0378d1c22ef6e05c54af07058a0315d7a9f20cab --- generic/nsf.c (.../nsf.c) (revision b57f4b6701eadc6f177da91291638d26da3322ba) +++ generic/nsf.c (.../nsf.c) (revision 0378d1c22ef6e05c54af07058a0315d7a9f20cab) @@ -9477,15 +9477,16 @@ cmd = FilterSearchProc(interp, object, &object->filterStack->currentCmdPtr, &cl); if (cmd) { - /*fprintf(stderr, "filterSearchProc returned cmd %p\n", cmd);*/ + /*fprintf(stderr, "*** filterSearchProc returned cmd %p\n", cmd);*/ frameType = NSF_CSC_TYPE_ACTIVE_FILTER; methodName = (char *)Tcl_GetCommandName(interp, cmd); + flags |= NSF_CM_IGNORE_PERMISSIONS; } } } } - if ((flags & NSF_CM_LOCAL_METHOD)) { + if (cmd == NULL && (flags & NSF_CM_LOCAL_METHOD)) { /* * We require a local method. If the local method is found, we set always * the cmd and sometimes the class (if it is a class specific method). Index: tests/protected.test =================================================================== diff -u -N -rb57f4b6701eadc6f177da91291638d26da3322ba -r0378d1c22ef6e05c54af07058a0315d7a9f20cab --- tests/protected.test (.../protected.test) (revision b57f4b6701eadc6f177da91291638d26da3322ba) +++ tests/protected.test (.../protected.test) (revision 0378d1c22ef6e05c54af07058a0315d7a9f20cab) @@ -26,24 +26,24 @@ ? {c1 bar-foo} {foo} ::nsf::method::property C SET call-protected true - ? {catch {c1 SET x 1} errorMsg; set errorMsg} {::c1: unable to dispatch method 'SET'} + ? {c1 SET x 1} {::c1: unable to dispatch method 'SET'} ? {::nsf::object::dispatch c1 SET x 2} {2} "dispatch of protected methods works" ? {c1 foo} {foo} ? {c1 bar} {bar} ? {c1 bar-SET} {1} ? {c1 bar-foo} {foo} - ? {catch {c2 bar-SET} errorMsg; set errorMsg} {::c1: unable to dispatch method 'SET'} + ? {c2 bar-SET} {::c1: unable to dispatch method 'SET'} ? {c2 bar-foo} {foo} ::nsf::method::property C foo call-protected true - ? {catch {c1 SET x 1} errorMsg; set errorMsg} {::c1: unable to dispatch method 'SET'} + ? {c1 SET x 1} {::c1: unable to dispatch method 'SET'} ? {::nsf::object::dispatch c1 SET x 2} {2} "dispatch of protected methods works" ? {c1 bar} {bar} "other method work" - ? {catch {c1 foo} errorMsg; set errorMsg} {::c1: unable to dispatch method 'foo'} + ? {c1 foo} {::c1: unable to dispatch method 'foo'} ? {c1 bar-SET} {1} "internal call of protected C implementend method" ? {c1 bar-foo} {foo} "internal call of protected Tcl implemented method" - ? {catch {c2 bar-SET} errorMsg; set errorMsg} {::c1: unable to dispatch method 'SET'} - ? {catch {c2 bar-foo} errorMsg; set errorMsg} {::c1: unable to dispatch method 'foo'} + ? {c2 bar-SET} {::c1: unable to dispatch method 'SET'} + ? {c2 bar-foo} {::c1: unable to dispatch method 'foo'} # unset call protected ? {::nsf::method::property C SET call-protected} 1 @@ -64,17 +64,44 @@ # define a protected method C protected method foo {} {return [current method]} + ? {::nsf::method::property C SET call-protected} 0 ? {c1 SET x 3} 3 ? {::nsf::object::dispatch c1 SET x 4} {4} - ? {catch {c1 foo} errorMsg; set errorMsg} {::c1: unable to dispatch method 'foo'} + ? {c1 foo} {::c1: unable to dispatch method 'foo'} ? {c1 bar} {bar} ? {c1 bar-SET} {1} ? {c1 bar-foo} foo ? {c2 bar-SET} 1 - ? {catch {c2 bar-foo} errorMsg; set errorMsg} {::c1: unable to dispatch method 'foo'} + ? {c2 bar-foo} {::c1: unable to dispatch method 'foo'} } +# +# Check protection + filter +# +# Allow to call methods as filters even if these are protected or +# private. +# +nx::Test case protected+filter { + nx::Class create C { + :method f1 args { next } + :private method f2 args { next } + :public method foo {} { return foo} + } + + C create c1 + ? {c1 foo} foo + + # add a protected filter + c1 filter add f1 + ? {c1 foo} foo + + # add a private filter + c1 filter add f2 + ? {c1 foo} foo +} + + nx::Test case redefined-protected { nx::Class create C { :public alias SET ::set