/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="thisObject"></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> public static string Replace(string thisObject, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObject.IndexOf(substr, StringComparison.Ordinal); if (start == -1) { return(thisObject); } int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, substr, start, thisObject)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObject.Length + (replaceText.Length - substr.Length)); result.Append(thisObject, 0, start); result.Append(replaceText); result.Append(thisObject, end, thisObject.Length - end); return(result.ToString()); }
/// <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> public string Replace(string input, FunctionInstance replaceFunction) { return(this.m_value.Replace(input, match => { // Set the deprecated RegExp properties. this.Engine.RegExp.SetDeprecatedProperties(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.CallFromNative("replace", null, parameters)); }, this.Global ? int.MaxValue : 1)); }
/// <summary> /// Returns a copy of this string with text replaced using a regular expression and a /// replacement function. /// </summary> /// <param name="thisObject"></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> public static string Replace(string thisObject, RegExpInstance regExp, FunctionInstance replaceFunction) { return(regExp.Replace(thisObject, replaceFunction)); }
/// <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"])) { 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"])) { 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) { attributes |= PropertyAttributes.Configurable; } if (writable) { attributes |= PropertyAttributes.Writable; } if (enumerable) { attributes |= PropertyAttributes.Enumerable; } // Either a value or an accessor is possible. object descriptorValue = value; if (isAccessor) { descriptorValue = new PropertyAccessorValue(getter, setter); } // Create the new property descriptor. return(new PropertyDescriptor(descriptorValue, 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.m_getter = getter; this.m_setter = setter; }
// INITIALIZATION //_________________________________________________________________________________________ /// <summary> /// Creates a new Function object. /// </summary> /// <param name="prototype"> The next object in the prototype chain. </param> /// <param name="instancePrototype"> The prototype for instances created by this function. </param> internal FunctionConstructor(ObjectInstance prototype, FunctionInstance instancePrototype) : base(prototype, "Function", instancePrototype) { }