Annotation of parser3/src/types/pa_vclass.C, revision 1.46

1.7       paf         1: /**    @file
                      2:        Parser: @b class parser class impl.
1.1       paf         3: 
1.45      moko        4:        Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.7       paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         6: */
                      7: 
1.45      moko        8: #include "pa_vclass.h"
1.7       paf         9: 
1.46    ! moko       10: volatile const char * IDENT_PA_VCLASS_C="$Id: pa_vclass.C,v 1.45 2012-03-16 09:24:16 moko Exp $" IDENT_PA_VCLASS_H;
1.1       paf        11: 
1.39      misha      12: Property& VClass::get_property(const String& aname) {
1.40      misha      13:        Property* result=ffields.get(aname);
                     14:        if (result) {
1.39      misha      15:                if (!result->getter && !result->setter) {
                     16:                        // can occur in ^process
                     17:                        Value *v=result->value;
1.24      paf        18:                        throw Exception("parser.compile",
1.39      misha      19:                                &aname,
                     20:                                "property can not be created, already exists field (%s) with that name", v ? v->get_class()->name_cstr() : "unknown");
                     21:                }
1.40      misha      22: 
                     23:                // cloning existing property
                     24:                result=new Property(*result);
1.24      paf        25:        } else {
1.39      misha      26:                result=new Property();
1.24      paf        27:        }
1.40      misha      28:        ffields.put(aname, result);
1.24      paf        29:        return *result;
                     30: }
                     31: 
1.41      misha      32: void VClass::real_set_method(const String& aname, Method* amethod) {
1.35      misha      33:        if(aname.starts_with("GET_")){
1.36      misha      34:                if(aname=="GET_DEFAULT")
1.40      misha      35:                        set_default_getter(amethod);
1.35      misha      36:                else
1.40      misha      37:                        get_property(aname.mid(4, aname.length())).getter=amethod;
1.36      misha      38:        } else if(aname.starts_with("SET_")){
1.44      moko       39:                if(aname=="SET_DEFAULT")
                     40:                        set_default_setter(amethod);
                     41:                else
                     42:                        get_property(aname.mid(4, aname.length())).setter=amethod;
1.36      misha      43:        } else if(aname=="GET"){
1.40      misha      44:                set_scalar(amethod);
1.36      misha      45:        }
                     46: 
1.41      misha      47:        // NOT under 'else' for backward compatiblilty: 
1.25      paf        48:        // if someone used get_xxx names to name regular methods
1.24      paf        49:        // still register method:
1.41      misha      50:        VStateless_class::real_set_method(aname, amethod);
1.39      misha      51: }
                     52: 
                     53: void VClass::set_base(VStateless_class* abase){
                     54:        VStateless_class::set_base(abase);
1.42      misha      55:        if(abase)
                     56:                if(HashStringProperty *props=abase->get_properties())
1.39      misha      57:                        ffields.merge_dont_replace(*props);
1.42      misha      58:                else 
                     59:                        throw Exception("parser.compile",
                     60:                                0,
                     61:                                "Class %s base class (%s) is not user-defined", name_cstr(), abase->name_cstr());
1.39      misha      62: }
                     63: 
                     64: Value* VClass::as(const char* atype) {
                     65:        Value* result=Value::as(atype);
                     66:        return result!=0 ? result : fbase ? fbase->as(atype) : 0;
1.11      paf        67: }
                     68: 
1.22      paf        69: /// VClass: $CLASS, (field/property)=STATIC value;(method)=method_ref with self=object_class
1.39      misha      70: Value* VClass::get_element(Value& aself, const String& aname) {
1.22      paf        71:        // simple things first: $field=static field/property
1.43      misha      72:        if(Property* prop=ffields.get(aname)) {
                     73:                if(prop->getter)
1.39      misha      74:                        return new VJunction(aself, prop->getter, true /*is_getter*/);
1.35      misha      75: 
1.46    ! moko       76:                if(prop->setter){
        !            77:                        if(Value *result=get_default_getter(aself, aname))
        !            78:                                return result;
        !            79:                        throw Exception(PARSER_RUNTIME, 0, "this property has no getter method (@GET_%s[])", aname.cstr());
        !            80:                }
1.39      misha      81:                 
                     82:                // just field, can be 0 as we don't remove 
                     83:                return prop->value;
1.21      paf        84:        }
                     85: 
1.14      paf        86:        // $CLASS, $method, or other base element
1.43      misha      87:        if(Value* result=VStateless_class::get_element(aself, aname))
1.39      misha      88:                return result;
1.7       paf        89: 
1.35      misha      90:        // no field or method found: looking for default getter
1.44      moko       91:        return get_default_getter(aself, aname);
1.7       paf        92: }
                     93: 
1.43      misha      94: static void add_field(
                     95:                HashStringProperty::key_type key, 
                     96:                HashStringProperty::value_type prop,
                     97:                HashStringValue* result
                     98: ){
                     99:        if(prop->value)
                    100:                result->put(key, prop->value);
                    101: }
                    102: 
                    103: HashStringValue* VClass::get_fields(){
                    104:        HashStringValue* result=new HashStringValue();
                    105:        ffields.for_each(add_field, result);
                    106:        return result;
                    107: }
                    108: 
1.25      paf       109: /// VClass: (field/property)=value - static values only
1.32      paf       110: const VJunction* VClass::put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
1.40      misha     111:        if(Property* prop=ffields.get(aname)) {
1.39      misha     112:                if (prop->setter)
                    113:                        return new VJunction(aself, prop->setter);
1.29      paf       114: 
1.46    ! moko      115:                if(prop->getter){
        !           116:                        if(VJunction *result=get_default_setter(aself, aname))
        !           117:                                return result;
        !           118:                        throw Exception(PARSER_RUNTIME, 0, "this property has no setter method (@SET_%s[value])", aname.cstr());
        !           119:                }
1.39      misha     120:                
                    121:                // just field, value can be 0 and unlike usual we don't remove it
                    122:                prop->value=avalue;
                    123:        } else {
1.40      misha     124:                if(areplace)
1.39      misha     125:                        return 0;
                    126: 
1.40      misha     127:                prop=new Property();
                    128:                prop->value=avalue;
                    129:                ffields.put(aname, prop);
                    130: 
                    131:                Array_iterator<VStateless_class *> i(fderived);
                    132:                while(i.has_next()) {
                    133:                        HashStringProperty *props=i.next()->get_properties();
                    134:                        if(props)
                    135:                                props->put_dont_replace(aname, prop);
                    136:                }
1.39      misha     137:        }
1.29      paf       138: 
1.39      misha     139:        return PUT_ELEMENT_REPLACED_ELEMENT;
1.7       paf       140: }
                    141: 
                    142: /// @returns object of this class
1.39      misha     143: Value* VClass::create_new_value(Pool&) { 
                    144:        return new VObject(*this);
1.1       paf       145: }

E-mail: