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

1.7       paf         1: /**    @file
                      2:        Parser: @b class parser class impl.
1.1       paf         3: 
1.37      misha       4:        Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
1.7       paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         6: */
                      7: 
1.39    ! misha       8: static const char * const IDENT_VCLASS_C="$Date: 2009-06-14 00:33:54 $";
1.7       paf         9: 
1.1       paf        10: #include "pa_vclass.h"
                     11: 
1.39    ! misha      12: Property& VClass::get_property(const String& aname) {
1.24      paf        13:        Property* result;
1.39    ! misha      14:        if (result=ffields.get(aname)) {
        !            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.24      paf        22:        } else {
1.39    ! misha      23:                result=new Property();
        !            24:                ffields.put(aname, result);
        !            25: 
        !            26:                Array_iterator<VStateless_class *> i(fderived);
        !            27:                while (i.has_next()) {
        !            28:                        VStateless_class *c=i.next();
        !            29:                        c->add_property(aname, *result);
        !            30:                }
1.24      paf        31:        }
                     32:        return *result;
                     33: }
                     34: 
1.22      paf        35: /// preparing property accessors to fields
1.35      misha      36: void VClass::add_method(const String& aname, Method& amethod) {
                     37:        if(aname.starts_with("GET_")){
1.36      misha      38:                if(aname=="GET_DEFAULT")
1.35      misha      39:                        set_default_getter(&amethod);
                     40:                else
1.39    ! misha      41:                        get_property(aname.mid(4, aname.length())).getter=&amethod;
1.36      misha      42:        } else if(aname.starts_with("SET_")){
1.39    ! misha      43:                get_property(aname.mid(4, aname.length())).setter=&amethod;
1.36      misha      44:        } else if(aname=="GET"){
                     45:                set_scalar(&amethod);
                     46:        }
                     47: 
1.25      paf        48:        // NOT under 'else' for backward compatiblilty: 
                     49:        // if someone used get_xxx names to name regular methods
1.24      paf        50:        // still register method:
                     51:        VStateless_class::add_method(aname, amethod);
1.22      paf        52: }
                     53: 
1.39    ! misha      54: void VClass::add_property(const String& aname, Property& aprop){
        !            55:        ffields.put_dont_replace(aname, &aprop);
        !            56: }
        !            57: 
        !            58: void VClass::set_base(VStateless_class* abase){
        !            59:        VStateless_class::set_base(abase);
        !            60:        if (abase)
        !            61:                if (HashStringProperty *props=abase->get_properties())
        !            62:                        ffields.merge_dont_replace(*props);
        !            63: }
        !            64: 
        !            65: Value* VClass::as(const char* atype) {
        !            66:        Value* result=Value::as(atype);
        !            67:        return result!=0 ? result : fbase ? fbase->as(atype) : 0;
1.11      paf        68: }
                     69: 
1.22      paf        70: /// VClass: $CLASS, (field/property)=STATIC value;(method)=method_ref with self=object_class
1.39    ! misha      71: Value* VClass::get_element(Value& aself, const String& aname) {
1.22      paf        72:        // simple things first: $field=static field/property
1.39    ! misha      73:        if (Property* prop=ffields.get(aname)) {
        !            74:                if (prop->getter)
        !            75:                        return new VJunction(aself, prop->getter, true /*is_getter*/);
1.35      misha      76: 
1.39    ! misha      77:                if (prop->setter)
        !            78:                        throw Exception(PARSER_RUNTIME,
        !            79:                                0,
        !            80:                                "this property has no getter method (@GET_%s[])", aname.cstr());
        !            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.39    ! misha      87:        if (Value* result=VStateless_class::get_element(aself, aname))
        !            88:                return result;
1.7       paf        89: 
1.35      misha      90:        // no field or method found: looking for default getter
1.39    ! misha      91:        if (Value* result=get_default_getter(aself, aname))
        !            92:                return result;
1.35      misha      93: 
1.7       paf        94:        return 0;
                     95: }
                     96: 
1.25      paf        97: /// VClass: (field/property)=value - static values only
1.32      paf        98: const VJunction* VClass::put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
1.39    ! misha      99:        if (Property* prop=ffields.get(aname)) {
        !           100:                if (prop->setter)
        !           101:                        return new VJunction(aself, prop->setter);
1.29      paf       102: 
1.39    ! misha     103:                if (prop->getter)
1.34      misha     104:                        throw Exception(PARSER_RUNTIME,
1.29      paf       105:                                0,
1.31      paf       106:                                "this property has no setter method (@SET_%s[value])", aname.cstr());
1.39    ! misha     107:                
        !           108:                // just field, value can be 0 and unlike usual we don't remove it
        !           109:                prop->value=avalue;
        !           110:        } else {
        !           111:                if (areplace)
        !           112:                        return 0;
        !           113: 
        !           114:                get_property(aname).value=avalue;
        !           115:        }
1.29      paf       116: 
1.39    ! misha     117:        return PUT_ELEMENT_REPLACED_ELEMENT;
1.7       paf       118: }
                    119: 
                    120: /// @returns object of this class
1.39    ! misha     121: Value* VClass::create_new_value(Pool&) { 
        !           122:        return new VObject(*this);
1.1       paf       123: }

E-mail: