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

DefineProperty() public method

Defines or redefines the value and attributes of a property. The prototype chain is not searched so if the property exists but only in the prototype chain a new property will be created.
public DefineProperty ( object key, PropertyDescriptor descriptor, bool throwOnError ) : bool
key object The property key of the property to modify.
descriptor PropertyDescriptor The property value and attributes.
throwOnError bool true to throw an exception if the property could not /// be set. This can happen if the property is not configurable or the object is sealed.
return bool
        public virtual bool DefineProperty(object key, PropertyDescriptor descriptor, bool throwOnError)
        {
            // Retrieve info on the property.
            var current = this.schema.GetPropertyIndexAndAttributes(key);

            if (current.Exists == false)
            {
                // Create a new property.
                return AddProperty(key, descriptor.Value, descriptor.Attributes, throwOnError);
            }

            // If the current property is not configurable, then the only change that is allowed is
            // a change from one simple value to another (i.e. accessors are not allowed) and only
            // if the writable attribute is set.
            if (current.IsConfigurable == false)
            {
                // Get the current value of the property.
                object currentValue = this.propertyValues[current.Index];
                object getter = null, setter = null;
                if (currentValue is PropertyAccessorValue)
                {
                    getter = ((PropertyAccessorValue)currentValue).Getter;
                    setter = ((PropertyAccessorValue)currentValue).Setter;
                }

                // Check if the modification is allowed.
                if (descriptor.Attributes != current.Attributes ||
                    (descriptor.IsAccessor == true && (getter != descriptor.Getter || setter != descriptor.Setter)) ||
                    (descriptor.IsAccessor == false && current.IsWritable == false && TypeComparer.SameValue(currentValue, descriptor.Value) == false))
                {
                    if (throwOnError == true)
                        throw new JavaScriptException(this.Engine, ErrorType.TypeError, string.Format("The property '{0}' is non-configurable.", key));
                    return false;
                }
            }

            // Set the property attributes.
            if (descriptor.Attributes != current.Attributes)
                this.schema = this.schema.SetPropertyAttributes(key, descriptor.Attributes);

            // Set the property value.
            this.propertyValues[current.Index] = descriptor.Value;

            return true;
        }

Usage Example

Esempio n. 1
0
        /// <summary>
        /// Defines or redefines the value and attributes of a property.  The prototype chain is
        /// not searched so if the property exists but only in the prototype chain a new property
        /// will be created.
        /// </summary>
        /// <param name="key"> The property key of the property to modify. </param>
        /// <param name="descriptor"> The property value and attributes. </param>
        /// <param name="throwOnError"> <c>true</c> to throw an exception if the property could not
        /// be set.  This can happen if the property is not configurable or the object is sealed. </param>
        /// <returns> <c>true</c> if the property was successfully modified; <c>false</c> otherwise. </returns>
        public override bool DefineProperty(object key, PropertyDescriptor descriptor, bool throwOnError)
        {
            // Check for revocation.
            if (target == null || handler == null)
            {
                throw new JavaScriptException(ErrorType.TypeError, "Cannot call 'defineProperty' on a proxy that has been revoked.");
            }

            // Call the handler, if one exists.
            var trap = handler.GetMethod("defineProperty");

            if (trap == null)
            {
                return(target.DefineProperty(key, descriptor, throwOnError));
            }
            var result = TypeConverter.ToBoolean(trap.CallLateBound(handler, target, key, descriptor.ToObject(Engine)));

            // Validate.
            if (!result)
            {
                if (throwOnError)
                {
                    throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned falsish for property '{TypeConverter.ToString(key)}'.");
                }
                return(false);
            }
            var targetDescriptor = target.GetOwnPropertyDescriptor(key);

            if (targetDescriptor.Exists)
            {
                if (!IsCompatiblePropertyDescriptor(target.IsExtensible, descriptor, targetDescriptor))
                {
                    throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned truish for adding property '{TypeConverter.ToString(key)}' that is incompatible with the existing property in the proxy target.");
                }
                if (descriptor.Exists && !descriptor.IsConfigurable && targetDescriptor.IsConfigurable)
                {
                    throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned truish for defining non-configurable property '{TypeConverter.ToString(key)}' which is either non-existent or configurable in the proxy target.");
                }
                if (!targetDescriptor.IsAccessor && !targetDescriptor.IsConfigurable && targetDescriptor.IsWritable)
                {
                    if (descriptor.Exists && !descriptor.IsWritable)
                    {
                        throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned truish for defining non-configurable property '{TypeConverter.ToString(key)}' which cannot be non-writable, unless there exists a corresponding non-configurable, non-writable own property of the target object.");
                    }
                }
            }
            else
            {
                if (!target.IsExtensible)
                {
                    throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned truish for adding property '{TypeConverter.ToString(key)}' to the non-extensible proxy target.");
                }
                if (descriptor.Exists && !descriptor.IsConfigurable)
                {
                    throw new JavaScriptException(ErrorType.TypeError, $"'defineProperty' on proxy: trap returned truish for defining non-configurable property '{TypeConverter.ToString(key)}' which is either non-existent or configurable in the proxy target.");
                }
            }
            return(true);
        }
All Usage Examples Of Jurassic.Library.ObjectInstance::DefineProperty