Jurassic.Library.ObjectInstance.SetPropertyValueIfExists C# (CSharp) Method

SetPropertyValueIfExists() public method

Sets the value of the given property. If a property with the given name exists, but only in the prototype chain, then a new property is created (unless the property is a setter, in which case the setter is called and no property is created). If the property does not exist at all, then no property is created and the method returns false. This method is used to set the value of a variable reference within a with statement.
public SetPropertyValueIfExists ( object key, object value, bool throwOnError ) : bool
key object The property key (either a string or a Symbol). Cannot be an array index.
value object The desired value of the property. This must be a javascript /// primitive (double, string, etc) or a class derived from .
throwOnError bool true to throw an exception if the property could not /// be set (i.e. if the property is read-only or if the object is not extensible and a new /// property needs to be created).
return bool
        public bool SetPropertyValueIfExists(object key, object value, bool throwOnError)
        {
            // Do not store nulls - null represents a non-existant value.
            value = value ?? Undefined.Value;

            // Retrieve information about the property.
            var property = this.schema.GetPropertyIndexAndAttributes(key);
            if (property.Exists == true)
            {
                // Check if the property is read-only.
                if (property.IsWritable == false)
                {
                    // The property is read-only.
                    if (throwOnError == true)
                        throw new JavaScriptException(this.Engine, ErrorType.TypeError, string.Format("The property '{0}' is read-only.", key));
                    return true;
                }

                if ((property.Attributes & (PropertyAttributes.IsAccessorProperty | PropertyAttributes.IsLengthProperty)) == 0)
                {
                    // The property contains a simple value.  Set the property value.
                    this.propertyValues[property.Index] = value;
                }
                else if (property.IsAccessor == true)
                {
                    // The property contains an accessor function.  Set the property value by calling the accessor.
                    ((PropertyAccessorValue)this.propertyValues[property.Index]).SetValue(this, value);
                }
                else
                {
                    // Otherwise, the property is the "magic" length property.
                    double length = TypeConverter.ToNumber(value);
                    uint lengthUint32 = TypeConverter.ToUint32(length);
                    if (length != (double)lengthUint32)
                        throw new JavaScriptException(this.Engine, ErrorType.RangeError, "Invalid array length");
                    ((ArrayInstance)this).Length = lengthUint32;
                }
                return true;
            }

            // Search the prototype chain for a accessor function.  If one is found, it will
            // prevent the creation of a new property.
            bool propertyExistsInPrototype = false;
            ObjectInstance prototypeObject = this.prototype;
            while (prototypeObject != null)
            {
                property = prototypeObject.schema.GetPropertyIndexAndAttributes(key);
                if (property.Exists == true)
                {
                    if (property.IsAccessor == true)
                    {
                        // The property contains an accessor function.  Set the property value by calling the accessor.
                        ((PropertyAccessorValue)prototypeObject.propertyValues[property.Index]).SetValue(this, value);
                        return true;
                    }
                    propertyExistsInPrototype = true;
                    break;
                }
                prototypeObject = prototypeObject.prototype;
            }

            // If the property exists in the prototype, create a new property.
            if (propertyExistsInPrototype == true)
            {
                AddProperty(key, value, PropertyAttributes.FullAccess, throwOnError);
                return true;
            }

            // The property does not exist.
            return false;
        }