public static PropertyDescriptor FromObject(ObjectInstance obj, PropertyDescriptor defaults)
{
if (obj == null)
return PropertyDescriptor.Undefined;
// Read configurable attribute.
bool configurable = defaults.IsConfigurable;
if (obj.HasProperty("configurable"))
configurable = TypeConverter.ToBoolean(obj["configurable"]);
// Read writable attribute.
bool writable = defaults.IsWritable;
if (obj.HasProperty("writable"))
writable = TypeConverter.ToBoolean(obj["writable"]);
// Read enumerable attribute.
bool enumerable = defaults.IsEnumerable;
if (obj.HasProperty("enumerable"))
enumerable = TypeConverter.ToBoolean(obj["enumerable"]);
// Read property value.
object value = defaults.Value;
if (obj.HasProperty("value"))
value = obj["value"];
// The descriptor is an accessor if get or set is present.
bool isAccessor = false;
// Read get accessor.
FunctionInstance getter = defaults.Getter;
if (obj.HasProperty("get"))
{
if (obj.HasProperty("value"))
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors cannot have both 'get' and 'value' set");
if (obj.HasProperty("writable"))
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors with 'get' or 'set' defined must not have 'writable' set");
if (obj["get"] is FunctionInstance)
getter = (FunctionInstance)obj["get"];
else if (TypeUtilities.IsUndefined(obj["get"]) == true)
getter = null;
else
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptor 'get' must be a function");
isAccessor = true;
}
// Read set accessor.
FunctionInstance setter = defaults.Setter;
if (obj.HasProperty("set"))
{
if (obj.HasProperty("value"))
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors cannot have both 'set' and 'value' set");
if (obj.HasProperty("writable"))
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptors with 'get' or 'set' defined must not have 'writable' set");
if (obj["set"] is FunctionInstance)
setter = (FunctionInstance)obj["set"];
else if (TypeUtilities.IsUndefined(obj["set"]) == true)
setter = null;
else
throw new JavaScriptException(obj.Engine, ErrorType.TypeError, "Property descriptor 'set' must be a function");
isAccessor = true;
}
// Build up the attributes enum.
PropertyAttributes attributes = PropertyAttributes.Sealed;
if (configurable == true)
attributes |= PropertyAttributes.Configurable;
if (writable == true)
attributes |= PropertyAttributes.Writable;
if (enumerable == true)
attributes |= PropertyAttributes.Enumerable;
// Either a value or an accessor is possible.
object descriptorValue = value;
if (isAccessor == true)
descriptorValue = new PropertyAccessorValue(getter, setter);
// Create the new property descriptor.
return new PropertyDescriptor(descriptorValue, attributes);
}