Annotation of parser3/src/types/pa_vclass.C, revision 1.47
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.47 ! misha 10: volatile const char * IDENT_PA_VCLASS_C="$Id: pa_vclass.C,v 1.46 2012-05-29 23:22:11 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:
1.47 ! misha 103: HashStringValue* VClass::get_hash() {
1.43 misha 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: