Exemplo n.º 1
0
        public IObjField this[string field_name]
        {
            // TODO: 2010/04/08
            // Determined that get and set BOTH need to ALWAYS auto-vivify the field.
            // This is because someobj["some_field"].iv = 42 calls OBJ indexer property GET, and then FIELD property SET on the field that returns.
            //
            // In future, maybe some means of avoiding "needless" auto-vivification on get can be found,
            // but it may be a non-critical optimization anyways -- that needs study to justify optimization effort
            get
            {
                if (field_name == null)
                {
                    Error.BadArg("Got null field_name");
                }
                if (!Token.is_bare_multi_word(field_name))
                {
                    Error.BadArg("Got invalid field_name '{0}'", field_name);
                }

                if (!fields.ContainsKey(field_name))
                {
                    // If the field is not present, auto-vivify the field from the Archetype's corresponding field
                    IArchetypeField arch_field = archetype[field_name];
                    if (arch_field == null)
                    {
                        // TODO: Policy control over behavior upon .get of a field not present in the Archetype.
                        // Default will likely be to auto-vivify and return default value?
                        //Form1.stdout.print("ObjField.get: found null archetype field for field_name '{0}', auto-vivifying.\n", field_name);
                        fields[field_name] = new FieldTempNull(this, field_name);
                        // Let's see if the FieldTempNull approach works...wow, surprisingly well at near-first test!

                        // Hmmm...if we don't have an Archetype field to get an IObjField from, how do we know what type to instantiate?
                        // Seems it will have to be fatal?  I'd rather be able to auto-vivify, but this gets called _before_ the .set ...argh...
                        //Error.Throw("Somehow got null archetype arch_field for field_name '{0}'", field_name);
                    }
                    else
                    {
                        fields[field_name] = arch_field.default_value;  // TODO: Verify that this is a "deep" copy, or deep enough at any rate...
                    }
                }
                return(fields[field_name]);
            }
            set
            {
                if (field_name == null)
                {
                    Error.BadArg("Got null field_name");
                }
                if (!Token.is_bare_multi_word(field_name))
                {
                    Error.BadArg("Got invalid field_name '{0}'", field_name);
                }

                if (archetype[field_name] != null)
                {
                    SemanticTypes type_of_new_field  = value.type.semantic_type;
                    SemanticTypes type_of_arch_field = archetype[field_name].type.semantic_type;
                    if (type_of_new_field != type_of_arch_field)
                    {
                        Error.BadArg("ObjField.set: Called for Obj '{0}' with Archetype '{1}' on field_name '{2}', " +
                                     "with strange IObjField having semantic type '{3}' " +
                                     "which differs from the archetype field semantic type '{4}'",
                                     autotag, archetype.tag, field_name, type_of_new_field, type_of_arch_field);
                    }
                }
                //else
                //{
                //    Form1.stdout.print("Obj.this[].set called for field '{0}', archetype does not contain that field\n", field_name);
                //}

                if (fields.ContainsKey(field_name) && fields[field_name].type != FieldType.EMPTY)
                {
                    // Call to set for an already-present field.
                    // This is OK if the already-present field is a FieldTempNull... ???

                    // TODO: Should be controlled by a policy variable.
                    // A likely default would be to warn and replace the existing attribute.
                    Error.BadArg("Got already-present Obj parse_field_name '{0}'", field_name);
                }
                fields[field_name] = value;
            }
        } // this[field_name]
Exemplo n.º 2
0
        public IObjField this[string field_name]
        {
            // TODO: 2010/04/08
            // Determined that get and set BOTH need to ALWAYS auto-vivify the field.
            // This is because someobj["some_field"].iv = 42 calls OBJ indexer property GET, and then FIELD property SET on the field that returns.
            //
            // In future, maybe some means of avoiding "needless" auto-vivification on get can be found,
            // but it may be a non-critical optimization anyways -- that needs study to justify optimization effort
            get
            {
                if (field_name == null)                    { Error.BadArg("Got null field_name"); }
                if (!Token.is_bare_multi_word(field_name)) { Error.BadArg("Got invalid field_name '{0}'", field_name); }

                if (!fields.ContainsKey(field_name))
                {
                    // If the field is not present, auto-vivify the field from the Archetype's corresponding field
                    IArchetypeField arch_field = archetype[field_name];
                    if (arch_field == null)
                    {
                        // TODO: Policy control over behavior upon .get of a field not present in the Archetype.
                        // Default will likely be to auto-vivify and return default value?
                        //Form1.stdout.print("ObjField.get: found null archetype field for field_name '{0}', auto-vivifying.\n", field_name);
                        fields[field_name] = new FieldTempNull(this, field_name);
                        // Let's see if the FieldTempNull approach works...wow, surprisingly well at near-first test!

                        // Hmmm...if we don't have an Archetype field to get an IObjField from, how do we know what type to instantiate?
                        // Seems it will have to be fatal?  I'd rather be able to auto-vivify, but this gets called _before_ the .set ...argh...
                        //Error.Throw("Somehow got null archetype arch_field for field_name '{0}'", field_name);
                    }
                    else
                    {
                        fields[field_name] = arch_field.default_value;  // TODO: Verify that this is a "deep" copy, or deep enough at any rate...
                    }
                }
                return fields[field_name];
            }
            set
            {
                if (field_name == null)                    { Error.BadArg("Got null field_name"); }
                if (!Token.is_bare_multi_word(field_name)) { Error.BadArg("Got invalid field_name '{0}'", field_name); }

                if (archetype[field_name] != null)
                {
                    SemanticTypes type_of_new_field = value.type.semantic_type;
                    SemanticTypes type_of_arch_field = archetype[field_name].type.semantic_type;
                    if (type_of_new_field != type_of_arch_field)
                    {
                        Error.BadArg("ObjField.set: Called for Obj '{0}' with Archetype '{1}' on field_name '{2}', " +
                                     "with strange IObjField having semantic type '{3}' " +
                                     "which differs from the archetype field semantic type '{4}'",
                                     autotag, archetype.tag, field_name, type_of_new_field, type_of_arch_field);
                    }
                }
                //else
                //{
                //    Form1.stdout.print("Obj.this[].set called for field '{0}', archetype does not contain that field\n", field_name);
                //}

                if (fields.ContainsKey(field_name) && fields[field_name].type != FieldType.EMPTY)
                {
                    // Call to set for an already-present field.
                    // This is OK if the already-present field is a FieldTempNull... ???

                    // TODO: Should be controlled by a policy variable.
                    // A likely default would be to warn and replace the existing attribute.
                    Error.BadArg("Got already-present Obj parse_field_name '{0}'", field_name);
                }
                fields[field_name] = value;
            }
        }