Annotation of parser3/src/classes/reflection.C, revision 1.1
1.1 ! misha 1: /** @file
! 2: Parser: @b reflection parser class.
! 3:
! 4: Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
! 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
! 6: */
! 7:
! 8: static const char * const IDENT_REFLECTION_C="$Date: 2005/08/09 08:14:48 $";
! 9:
! 10: #include "pa_vmethod_frame.h"
! 11: #include "pa_request.h"
! 12: #include "pa_vbool.h"
! 13:
! 14: // class
! 15:
! 16: class MReflection: public Methoded {
! 17: public:
! 18: MReflection();
! 19: public: // Methoded
! 20: bool used_directly() { return true; }
! 21: };
! 22:
! 23: // global variable
! 24:
! 25: DECLARE_CLASS_VAR(reflection, new MReflection, 0);
! 26:
! 27: // methods
! 28:
! 29: static void _construct(Request& r, MethodParams& params) {
! 30: const String& class_name=params.as_string(0, "class_name must be string");
! 31: Value* class_value=r.classes().get(class_name);
! 32:
! 33: if(!class_value)
! 34: throw Exception(PARSER_RUNTIME,
! 35: &class_name,
! 36: "class is undefined");
! 37:
! 38: const String& constructor_name=params.as_string(1, "constructor_name must be string");
! 39: Value* constructor_value=class_value->get_element(constructor_name, *class_value, true);
! 40:
! 41: if(!constructor_value || !constructor_value->get_junction())
! 42: throw Exception(PARSER_RUNTIME,
! 43: &constructor_name,
! 44: "constructor must be declared in class '%s'",
! 45: class_name.cstr());
! 46:
! 47: Junction* junction=constructor_value->get_junction();
! 48:
! 49: VMethodFrame frame(*junction, r.get_method_frame());
! 50:
! 51: size_t nparams=params.count()-2;
! 52: Value* v[100];
! 53:
! 54: if(nparams>0){
! 55: for(size_t i=0; i<nparams; i++)
! 56: v[i]=&r.process_to_value(params[i+2]);
! 57: frame.store_params((Value**)&v, nparams);
! 58: } else {
! 59: frame.empty_params();
! 60: }
! 61: r.op_call(frame, true/*constructing*/);
! 62: r.write_pass_lang(frame.result());
! 63: }
! 64:
! 65: static void _class(Request& r, MethodParams& params) {
! 66: if(Value* lclass=params[0].get_class())
! 67: r.write_no_lang(*lclass);
! 68: else
! 69: throw Exception(PARSER_RUNTIME,
! 70: 0,
! 71: "class was not defined");
! 72: }
! 73:
! 74: static void _class_name(Request& r, MethodParams& params) {
! 75: r.write_no_lang(String(params[0].type()));
! 76: }
! 77:
! 78: static void store_method_info(
! 79: HashString<Method*>::key_type key,
! 80: HashString<Method*>::value_type value,
! 81: HashStringValue* result
! 82: ) {
! 83: VHash* method_info=new VHash;
! 84: HashStringValue* method_hash=method_info->get_hash();
! 85: bool native=false;
! 86:
! 87: if(value->native_code){
! 88: // native code
! 89: native=true;
! 90: if(value->min_numbered_params_count)
! 91: method_hash->put(String("min_params"), new VInt(value->min_numbered_params_count));
! 92:
! 93: if(value->max_numbered_params_count)
! 94: method_hash->put(String("max_params"), new VInt(value->max_numbered_params_count));
! 95: } else {
! 96: // parser code
! 97: if(value->params_names){
! 98: VHash* params=new VHash;
! 99: method_hash->put(String("params"), params);
! 100: HashStringValue* params_hash=params->get_hash();
! 101:
! 102: for(size_t i=0; i<value->params_names->count(); i++)
! 103: params_hash->put(String::Body::Format(i), new VString(*value->params_names->get(i)));
! 104: }
! 105:
! 106: if(value->locals_names){
! 107: VHash* locals=new VHash;
! 108: method_hash->put(String("locals"), locals);
! 109: HashStringValue* locals_hash=locals->get_hash();
! 110:
! 111: for(size_t i=0; i<value->locals_names->count(); i++)
! 112: locals_hash->put(String::Body::Format(i), new VString(*value->locals_names->get(i)));
! 113: }
! 114: }
! 115:
! 116: method_hash->put(String("native"), &VBool::get(native));
! 117: result->put(key, method_info);
! 118: }
! 119:
! 120: static void _methods(Request& r, MethodParams& params) {
! 121: const String& class_name=params.as_string(0, "class_name must be string");
! 122: Value* class_value=r.classes().get(class_name);
! 123:
! 124: if(!class_value)
! 125: throw Exception(PARSER_RUNTIME,
! 126: &class_name,
! 127: "class is undefined");
! 128:
! 129: VHash& result=*new VHash;
! 130: if(VStateless_class* lclass=class_value->get_class()){
! 131: HashString<Method*> methods=lclass->get_methods();
! 132: methods.for_each(store_method_info, result.get_hash());
! 133: } else {
! 134: // exception?
! 135: }
! 136: r.write_no_lang(result);
! 137: }
! 138:
! 139: // constructor
! 140: MReflection::MReflection(): Methoded("reflection") {
! 141: // ^reflection:construct[class;constructor;params[;]]
! 142: add_native_method("construct", Method::CT_STATIC, _construct, 2, 102);
! 143:
! 144: // ^reflection:class[object]
! 145: add_native_method("class", Method::CT_STATIC, _class, 1, 1);
! 146:
! 147: // ^reflection:class_name[object]
! 148: add_native_method("class_name", Method::CT_STATIC, _class_name, 1, 1);
! 149:
! 150: // ^reflection:get_methods[object]
! 151: add_native_method("methods", Method::CT_STATIC, _methods, 1, 1);
! 152: }
E-mail: