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

1.7       paf         1: /**    @file
                      2:        Parser: @b class parser class impl.
1.1       paf         3: 
1.20      paf         4:        Copyright (c) 2001-2004 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.24    ! paf         8: static const char * const IDENT_VCLASS_C="$Date: 2005/07/25 08:53:12 $";
1.7       paf         9: 
1.1       paf        10: #include "pa_vclass.h"
                     11: 
1.24    ! paf        12: Property& VClass::add_property(const String& aname) {
        !            13:        String prop_name=aname.mid(4, aname.length());
        !            14:        
        !            15:        Property* result;
        !            16:        if(Value* value=ffields.get(prop_name)) {
        !            17:                result=value->get_property();
        !            18:                if(!result) // can occur in ^process
        !            19:                        throw Exception("parser.compile",
        !            20:                                &prop_name,
        !            21:                                "property can not be created, already exists field (%s) with that name", value->get_class()->name_cstr());
        !            22:        } else {
        !            23:                VProperty* vproperty=new VProperty();
        !            24:                ffields.put(prop_name, vproperty);
        !            25:                result=&vproperty->get();
        !            26:        }
        !            27:        return *result;
        !            28: }
        !            29: 
1.22      paf        30: /// preparing property accessors to fields
1.24    ! paf        31: void VClass::add_method(const String& aname, Method& amethod)
1.22      paf        32: {
1.24    ! paf        33:        if(aname.starts_with("get_"))
        !            34:                add_property(aname).getter=&amethod;
        !            35:        else if(aname.starts_with("put_") )
        !            36:                add_property(aname).setter=&amethod;
        !            37:        // support non-backward compatiblilty: 
        !            38:        // if someone used @get_xxx names to name regular methods
        !            39:        // still register method:
        !            40: 
        !            41:        VStateless_class::add_method(aname, amethod);
1.22      paf        42: }
                     43: 
1.17      paf        44: Value* VClass::as(const char* atype, bool looking_up) {
                     45:        if(Value* result=Value::as(atype, looking_up))
1.12      paf        46:                return result;
1.11      paf        47:        else
1.12      paf        48:                return fbase?fbase->as(atype, looking_up):0;
1.11      paf        49: }
                     50: 
1.22      paf        51: /// VClass: $CLASS, (field/property)=STATIC value;(method)=method_ref with self=object_class
1.17      paf        52: Value* VClass::get_element(const String& aname, Value& aself, bool looking_up) {
1.22      paf        53:        // simple things first: $field=static field/property
                     54:        if(Value* result=ffields.get(aname)) {
                     55:                if(Property* prop=result->get_property()) // it is property?
                     56:                {
                     57:                        Method* method=prop->getter;
                     58:                        if(!method)
                     59:                                throw Exception("parser.runtime",
                     60:                                        &aname,
                     61:                                        "this property has no getter method (get_%s)", aname.cstr());
1.21      paf        62: 
1.22      paf        63:                        return new VJunction(new Junction(aself, method, true /*is_getter*/));
                     64:                }
1.21      paf        65:                return result;
                     66:        }
                     67: 
1.14      paf        68:        // $CLASS, $method, or other base element
1.17      paf        69:        if(Value* result=VStateless_class::get_element(aname, aself, looking_up))
1.22      paf        70:                return result; // TODO: this can be SIGNIFICANTLY sped up by caching in ffields! [THOUGH decide about different aself] // what REALLY would speed up things is to join storage of properties/methods/fields of all vobject parents into last descenant [sort of vmt + all fields as in other langs]
1.7       paf        71: 
                     72:        return 0;
                     73: }
                     74: 
                     75: /// VClass: (field)=value - static values only
1.21      paf        76: const Method* VClass::put_element(const String& aname, Value* avalue, bool replace) {
1.7       paf        77:        try {
                     78:                if(fbase && fbase->put_element(aname, avalue, true))
1.21      paf        79:                        return PUT_ELEMENT_REPLACED_ELEMENT; // replaced in base
1.10      paf        80:        } catch(Exception) {  /* allow override parent variables, useful for form descendants */ }
1.7       paf        81: 
                     82:        if(replace)
1.21      paf        83:                return ffields.put_replace(aname, avalue)? PUT_ELEMENT_REPLACED_ELEMENT: 0;
1.7       paf        84:        else {
                     85:                ffields.put(aname, avalue);
1.21      paf        86:                return 0;
1.7       paf        87:        }
                     88: }
                     89: 
                     90: /// @returns object of this class
1.18      paf        91: Value* VClass::create_new_value(Pool& apool) { 
                     92:        return new VObject(apool, *this);
1.1       paf        93: }

E-mail: