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: