Mercurial > hg > octave-nkf
diff libinterp/octave-value/ov-classdef.cc @ 18347:81c1edd70bfd
Allow base classes to access protected members of derived classes.
* ov-classdef.cc (check_access): New members meth_name, prop_name and
is_prop_set. Allow a class to access protected methods/properties from
derived classes as long their are known and accessible from the base
class.
(cdef_method::cdef_method_rep::check_access): Use new arguments of
check_access.
(cdef_property::cdef_property_rep::check_get_access,
cdef_property::cdef_property_rep::check_set_access): Likewise.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Sat, 18 Jan 2014 15:31:23 -0500 |
parents | b5be1a2aa5ab |
children | 06eb893b9db6 |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc +++ b/libinterp/octave-value/ov-classdef.cc @@ -305,7 +305,10 @@ } static bool -check_access (const cdef_class& cls, const octave_value& acc) +check_access (const cdef_class& cls, const octave_value& acc, + const std::string& meth_name = std::string (), + const std::string& prop_name = std::string (), + bool is_prop_set = false) { if (acc.is_string ()) { @@ -324,7 +327,47 @@ if (acc_s == "private") return (ctx == cls); else if (acc_s == "protected") - return is_superclass (cls, ctx); + { + if (is_superclass (cls, ctx)) + // Calling a protected method in a superclass. + return true; + else if (is_strict_superclass (ctx, cls)) + { + // Calling a protected method or property in a derived class. + // This is only allowed if the context class knows about it + // and has access to it. + + if (! meth_name.empty ()) + { + cdef_method m = ctx.find_method (meth_name); + + if (m.ok ()) + return check_access (ctx, m.get ("Access"), meth_name); + + return false; + } + else if (! prop_name.empty ()) + { + cdef_property p = ctx.find_property (prop_name); + + if (p.ok ()) + { + octave_value p_access = p.get (is_prop_set ? + "SetAccess" : + "GetAccess"); + + return check_access (ctx, p_access, meth_name, + prop_name, is_prop_set); + } + + return false; + } + else + panic_impossible (); + } + + return false; + } else panic_impossible (); } @@ -2890,7 +2933,8 @@ cdef_class cls (to_cdef (get ("DefiningClass"))); if (! error_state) - return ::check_access (cls, get ("GetAccess")); + return ::check_access (cls, get ("GetAccess"), std::string (), + get_name (), false); return false; } @@ -2901,7 +2945,8 @@ cdef_class cls (to_cdef (get ("DefiningClass"))); if (! error_state) - return ::check_access (cls, get ("SetAccess")); + return ::check_access (cls, get ("SetAccess"), std::string (), + get_name (), true); return false; } @@ -3038,7 +3083,7 @@ cdef_class cls (to_cdef (get ("DefiningClass"))); if (! error_state) - return ::check_access (cls, get ("Access")); + return ::check_access (cls, get ("Access"), get_name ()); return false; }