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