--- parser3/src/classes/reflection.C 2012/06/05 10:30:32 1.28 +++ parser3/src/classes/reflection.C 2014/06/29 23:00:50 1.31 @@ -9,7 +9,7 @@ #include "pa_request.h" #include "pa_vbool.h" -volatile const char * IDENT_REFLECTION_C="$Id: reflection.C,v 1.28 2012/06/05 10:30:32 misha Exp $"; +volatile const char * IDENT_REFLECTION_C="$Id: reflection.C,v 1.31 2014/06/29 23:00:50 misha Exp $"; static const String class_type_methoded("methoded"); @@ -24,6 +24,9 @@ static const String method_call_type_dyn static const String method_min_params("min_params"); static const String method_max_params("max_params"); +static const String method_extra_param("extra_param"); + +static const String def_class("class"); // class @@ -184,6 +187,16 @@ static void store_method_info( result->put(key, new VString(method->native_code?method_type_native:method_type_parser)); } +static void _def(Request& r, MethodParams& params) { + const String& type=params.as_string(0, "type must be string"); + if(type == def_class) { + const String& name=params.as_string(1, "name must be string"); + r.write_no_lang(VBool::get(r.get_class(name)!=0)); + } else { + throw Exception(PARSER_RUNTIME, &type, "is invalid type, must be '%s'", def_class.cstr()); + } +} + static void _methods(Request& r, MethodParams& params) { const String& class_name=params.as_string(0, "class_name must be string"); Value* class_value=r.get_class(class_name); @@ -267,29 +280,36 @@ static void _method_info(Request& r, Met hash->put((base_method==method) ? method_inherited : method_overridden, new VString(c->name())); } + Value* call_type=0; + switch(method->call_type){ + case Method::CT_DYNAMIC: + call_type=new VString(method_call_type_dynamic); + break; + case Method::CT_STATIC: + call_type=new VString(method_call_type_static); + break; + } + if(call_type) + hash->put(method_call_type, call_type); + if(method->native_code){ // native code hash->put(method_min_params, new VInt(method->min_numbered_params_count)); hash->put(method_max_params, new VInt(method->max_numbered_params_count)); - Value* call_type=0; - switch(method->call_type){ - case Method::CT_DYNAMIC: - call_type=new VString(method_call_type_dynamic); - break; - case Method::CT_STATIC: - call_type=new VString(method_call_type_static); - break; - } - if(call_type) - hash->put(method_call_type, call_type); } else { // parser code const String* filespec = r.get_method_filename(method); if( filespec ) hash->put("file", new VString(*filespec)); + + hash->put(method_max_params, new VInt(method->params_names ? method->params_names->count() : 0)); + if(method->params_names) for(size_t i=0; iparams_names->count(); i++) hash->put(String::Body::Format(i), new VString(*method->params_names->get(i))); + + if(method->extra_params) + hash->put(method_extra_param, new VString(*method->extra_params)); } r.write_no_lang(result); @@ -353,6 +373,9 @@ MReflection::MReflection(): Methoded("re // ^reflection:base_class_name[object] add_native_method("base_name", Method::CT_STATIC, _base_name, 1, 1); + // ^reflection:def[class|...;name] + add_native_method("def", Method::CT_STATIC, _def, 2, 2); + // ^reflection:methods[class_name] add_native_method("methods", Method::CT_STATIC, _methods, 1, 1);