comparison 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
comparison
equal deleted inserted replaced
18346:b0e8cc676396 18347:81c1edd70bfd
303 303
304 return get_class_context (dummy_string, dummy_bool); 304 return get_class_context (dummy_string, dummy_bool);
305 } 305 }
306 306
307 static bool 307 static bool
308 check_access (const cdef_class& cls, const octave_value& acc) 308 check_access (const cdef_class& cls, const octave_value& acc,
309 const std::string& meth_name = std::string (),
310 const std::string& prop_name = std::string (),
311 bool is_prop_set = false)
309 { 312 {
310 if (acc.is_string ()) 313 if (acc.is_string ())
311 { 314 {
312 std::string acc_s = acc.string_value (); 315 std::string acc_s = acc.string_value ();
313 316
322 if (! error_state && ctx.ok ()) 325 if (! error_state && ctx.ok ())
323 { 326 {
324 if (acc_s == "private") 327 if (acc_s == "private")
325 return (ctx == cls); 328 return (ctx == cls);
326 else if (acc_s == "protected") 329 else if (acc_s == "protected")
327 return is_superclass (cls, ctx); 330 {
331 if (is_superclass (cls, ctx))
332 // Calling a protected method in a superclass.
333 return true;
334 else if (is_strict_superclass (ctx, cls))
335 {
336 // Calling a protected method or property in a derived class.
337 // This is only allowed if the context class knows about it
338 // and has access to it.
339
340 if (! meth_name.empty ())
341 {
342 cdef_method m = ctx.find_method (meth_name);
343
344 if (m.ok ())
345 return check_access (ctx, m.get ("Access"), meth_name);
346
347 return false;
348 }
349 else if (! prop_name.empty ())
350 {
351 cdef_property p = ctx.find_property (prop_name);
352
353 if (p.ok ())
354 {
355 octave_value p_access = p.get (is_prop_set ?
356 "SetAccess" :
357 "GetAccess");
358
359 return check_access (ctx, p_access, meth_name,
360 prop_name, is_prop_set);
361 }
362
363 return false;
364 }
365 else
366 panic_impossible ();
367 }
368
369 return false;
370 }
328 else 371 else
329 panic_impossible (); 372 panic_impossible ();
330 } 373 }
331 } 374 }
332 else if (acc.is_cell ()) 375 else if (acc.is_cell ())
2888 cdef_property::cdef_property_rep::check_get_access (void) const 2931 cdef_property::cdef_property_rep::check_get_access (void) const
2889 { 2932 {
2890 cdef_class cls (to_cdef (get ("DefiningClass"))); 2933 cdef_class cls (to_cdef (get ("DefiningClass")));
2891 2934
2892 if (! error_state) 2935 if (! error_state)
2893 return ::check_access (cls, get ("GetAccess")); 2936 return ::check_access (cls, get ("GetAccess"), std::string (),
2937 get_name (), false);
2894 2938
2895 return false; 2939 return false;
2896 } 2940 }
2897 2941
2898 bool 2942 bool
2899 cdef_property::cdef_property_rep::check_set_access (void) const 2943 cdef_property::cdef_property_rep::check_set_access (void) const
2900 { 2944 {
2901 cdef_class cls (to_cdef (get ("DefiningClass"))); 2945 cdef_class cls (to_cdef (get ("DefiningClass")));
2902 2946
2903 if (! error_state) 2947 if (! error_state)
2904 return ::check_access (cls, get ("SetAccess")); 2948 return ::check_access (cls, get ("SetAccess"), std::string (),
2949 get_name (), true);
2905 2950
2906 return false; 2951 return false;
2907 } 2952 }
2908 2953
2909 void 2954 void
3036 cdef_method::cdef_method_rep::check_access (void) const 3081 cdef_method::cdef_method_rep::check_access (void) const
3037 { 3082 {
3038 cdef_class cls (to_cdef (get ("DefiningClass"))); 3083 cdef_class cls (to_cdef (get ("DefiningClass")));
3039 3084
3040 if (! error_state) 3085 if (! error_state)
3041 return ::check_access (cls, get ("Access")); 3086 return ::check_access (cls, get ("Access"), get_name ());
3042 3087
3043 return false; 3088 return false;
3044 } 3089 }
3045 3090
3046 octave_value_list 3091 octave_value_list