/// <summary> /// Returns a copy of the given string with text replaced using a regular expression. /// </summary> /// <param name="input"> The string on which to perform the search. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of the given string with text replaced using a regular expression. </returns> internal string Replace(string input, FunctionInstance replaceFunction) { return(this.value.Replace(input, match => { object[] parameters = new object[match.Groups.Count + 2]; for (int i = 0; i < match.Groups.Count; i++) { if (match.Groups[i].Success == false) { parameters[i] = Undefined.Value; } else { parameters[i] = match.Groups[i].Value; } } parameters[match.Groups.Count] = match.Index; parameters[match.Groups.Count + 1] = input; return TypeConverter.ToString(replaceFunction.CallLateBound(null, parameters)); }, this.Global == true ? int.MaxValue : 1)); }
/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="thisObj"> The string that is being operated on. </param> /// <param name="substr"> The text to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced. </returns> internal static string Replace(string thisObj, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObj.IndexOf(substr, StringComparison.Ordinal); if (start == -1) { return(thisObj); } int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallLateBound(null, substr, start, thisObj)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObj.Length + (replaceText.Length - substr.Length)); result.Append(thisObj, 0, start); result.Append(replaceText); result.Append(thisObj, end, thisObj.Length - end); return(result.ToString()); }
/// <summary> /// Creates a new PropertyDescriptor instance with a getter function and, optionally, a /// setter function. /// </summary> /// <param name="getter"> The function to call to retrieve the property value. </param> /// <param name="setter"> The function to call to set the property value. </param> /// <param name="attributes"> The property attributes (whether the property is writable or /// not is implied by whether there is a setter function). </param> public PropertyDescriptor(FunctionInstance getter, FunctionInstance setter, PropertyAttributes attributes) : this(new PropertyAccessorValue(getter, setter), attributes) { }
// OBJECT SERIALIZATION AND DESERIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a property descriptor from an object containing any of the following /// properties: configurable, writable, enumerable, value, get, set. /// </summary> /// <param name="obj"> The object to get the property values from. </param> /// <param name="defaults"> The values to use if the relevant value is not specified. </param> /// <returns> A PropertyDescriptor that corresponds to the object. </returns> 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, "TypeError", "Property descriptors cannot have both 'get' and 'value' set"); } if (obj.HasProperty("writable")) { throw new JavaScriptException(obj.Engine, "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, "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, "TypeError", "Property descriptors cannot have both 'set' and 'value' set"); } if (obj.HasProperty("writable")) { throw new JavaScriptException(obj.Engine, "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, "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)); }
/// <summary> /// Returns a copy of this string with text replaced using a regular expression and a /// replacement function. /// </summary> /// <param name="thisObj"> The string that is being operated on. </param> /// <param name="regExp"> The regular expression to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced using a regular expression. </returns> internal static string Replace(string thisObj, RegExp regExp, FunctionInstance replaceFunction) { return(regExp.Replace(thisObj, replaceFunction)); }
/// <summary> /// Returns a Promise. It takes two arguments: callback functions for the success and /// failure cases of the Promise. /// </summary> /// <param name="onFulfilled"> A Function called when the Promise is fulfilled. This /// function has one argument, the fulfillment value. </param> /// <param name="onRejected"> A Function called when the Promise is rejected. This function /// has one argument, the rejection reason. </param> /// <returns></returns> public Promise Then(FunctionInstance onFulfilled, FunctionInstance onRejected) { throw new NotImplementedException(); }
// JAVASCRIPT FUNCTIONS //_________________________________________________________________________________________ /// <summary> /// Returns a Promise and deals with rejected cases only. It behaves the same as calling /// Promise.prototype.then(undefined, onRejected). /// </summary> /// <param name="onRejected"> A Function called when the Promise is rejected. This function /// has one argument, the rejection reason. </param> /// <returns></returns> public Promise Catch(FunctionInstance onRejected) { return(Then(null, onRejected)); }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal Promise(FunctionInstance executor) { Executor = executor; }
// JAVASCRIPT FUNCTIONS //_________________________________________________________________________________________ /// <summary> /// Creates a new typed array from an array-like or iterable object. /// </summary> /// <param name="source"> An array-like or iterable object to convert to a typed array. </param> /// <param name="mapFn"> Optional. Map function to call on every element of the typed array. </param> /// <param name="thisArg"> Optional. Value to use as this when executing mapFn. </param> /// <returns></returns> public static TypedArray From(object source, FunctionInstance mapFn, object thisArg) { throw new NotImplementedException(); }
/// <summary> /// Initializes a getter/setter property. /// </summary> /// <param name="name"> The name of the property. </param> /// <param name="getter"> The function to call to retrieve the property value. </param> /// <param name="setter"> The function to call to set the property value. </param> /// <param name="attributes"> Indicates whether the property is readable, writable and/or enumerable. </param> public PropertyNameAndValue(string name, FunctionInstance getter, FunctionInstance setter, PropertyAttributes attributes) { this.name = name; this.descriptor = new PropertyDescriptor(getter, setter, attributes); }
/// <summary> /// Creates a new PropertyAccessorValue instance. /// </summary> /// <param name="getter"> The getter function, or <c>null</c> if no getter was provided. </param> /// <param name="setter"> The setter function, or <c>null</c> if no setter was provided. </param> public PropertyAccessorValue(FunctionInstance getter, FunctionInstance setter) { this.getter = getter; this.setter = setter; }