From b525f68ff64294735ce584254ee8bed37387acf2 Mon Sep 17 00:00:00 2001 From: HalidOdat Date: Sat, 25 Apr 2020 18:41:11 +0200 Subject: [PATCH] Added documentation to RegExp --- boa/src/builtins/array/mod.rs | 46 ++++----- boa/src/builtins/json.rs | 8 +- boa/src/builtins/number/mod.rs | 8 +- boa/src/builtins/regexp/mod.rs | 170 +++++++++++++++++++++++++++++++-- boa/src/builtins/string/mod.rs | 60 ++++++++++-- 5 files changed, 249 insertions(+), 43 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 118ee2be9e..0aa9a09576 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -48,8 +48,10 @@ pub(crate) fn new_array(interpreter: &Interpreter) -> ResultValue { Ok(array) } -/// Utility function for creating array objects: `array_obj` can be any array with -/// prototype already set (it will be wiped and recreated from `array_contents`) +/// Utility function for creating array objects. +/// +/// `array_obj` can be any array with prototype already set (it will be wiped and +/// recreated from `array_contents`) pub fn construct_array(array_obj: &Value, array_contents: &[Value]) -> ResultValue { let array_obj_ptr = array_obj.clone(); @@ -128,7 +130,7 @@ pub fn make_array(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result Ok(this.clone()) } -/// Array.isArray ( arg ) +/// `Array.isArray( arg )` /// /// The isArray function takes one argument arg, and returns the Boolean value true /// if the argument is an object whose class internal property is "Array"; otherwise it returns false. @@ -162,7 +164,7 @@ pub fn is_array(_this: &Value, args: &[Value], _interpreter: &mut Interpreter) - } } -/// Array.prototype.concat(...arguments) +/// `Array.prototype.concat(...arguments)` /// /// When the concat method is called with zero or more arguments, it returns an /// array containing the array elements of the object followed by the array @@ -201,7 +203,7 @@ pub fn concat(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue construct_array(this, &new_values) } -/// Array.prototype.push ( ...items ) +/// `Array.prototype.push( ...items )` /// /// The arguments are appended to the end of the array, in the order in which /// they appear. The new length of the array is returned as the result of the @@ -218,7 +220,7 @@ pub fn push(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(new_array.get_field_slice("length")) } -/// Array.prototype.pop ( ) +/// `Array.prototype.pop()` /// /// The last element of the array is removed from the array and returned. /// @@ -241,7 +243,7 @@ pub fn pop(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(pop_value) } -/// Array.prototype.forEach ( callbackFn [ , thisArg ] ) +/// `Array.prototype.forEach( callbackFn [ , thisArg ] )` /// /// This method executes the provided callback function for each element in the array. /// @@ -274,7 +276,7 @@ pub fn for_each(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Ok(Gc::new(ValueData::Undefined)) } -/// Array.prototype.join ( separator ) +/// `Array.prototype.join( separator )` /// /// The elements of the array are converted to Strings, and these Strings are /// then concatenated, separated by occurrences of the separator. If no @@ -304,7 +306,7 @@ pub fn join(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(to_value(elem_strs.join(&separator))) } -/// Array.prototype.toString ( separator ) +/// `Array.prototype.toString( separator )` /// /// The toString function is intentionally generic; it does not require that /// its this value be an Array object. Therefore it can be transferred to @@ -346,7 +348,7 @@ pub fn to_string(this: &Value, _args: &[Value], _ctx: &mut Interpreter) -> Resul Ok(to_value(match_string)) } -/// Array.prototype.reverse ( ) +/// `Array.prototype.reverse()` /// /// The elements of the array are rearranged so as to reverse their order. /// The object is returned as the result of the call. @@ -387,7 +389,7 @@ pub fn reverse(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(this.clone()) } -/// Array.prototype.shift ( ) +/// `Array.prototype.shift()` /// /// The first element of the array is removed from the array and returned. /// @@ -428,7 +430,7 @@ pub fn shift(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(first) } -/// Array.prototype.unshift ( ...items ) +/// `Array.prototype.unshift( ...items )` /// /// The arguments are prepended to the start of the array, such that their order /// within the array is the same as the order in which they appear in the @@ -472,7 +474,7 @@ pub fn unshift(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue Ok(to_value(temp)) } -/// Array.prototype.every ( callback, [ thisArg ] ) +/// `Array.prototype.every( callback, [ thisArg ] )` /// /// The every method executes the provided callback function once for each /// element present in the array until it finds the one where callback returns @@ -513,7 +515,7 @@ pub fn every(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Res Ok(to_value(true)) } -/// Array.prototype.map ( callback, [ thisArg ] ) +/// `Array.prototype.map( callback, [ thisArg ] )` /// /// For each element in the array the callback function is called, and a new /// array is constructed from the return values of these calls. @@ -554,7 +556,7 @@ pub fn map(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Resul construct_array(&new, &values) } -/// Array.prototype.indexOf ( searchElement[, fromIndex ] ) +/// `Array.prototype.indexOf( searchElement[, fromIndex ] )` /// /// /// indexOf compares searchElement to the elements of the array, in ascending order, @@ -610,7 +612,7 @@ pub fn index_of(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValu Ok(to_value(-1)) } -/// Array.prototype.lastIndexOf ( searchElement[, fromIndex ] ) +/// `Array.prototype.lastIndexOf( searchElement[, fromIndex ] )` /// /// /// lastIndexOf compares searchElement to the elements of the array in descending order @@ -665,7 +667,7 @@ pub fn last_index_of(this: &Value, args: &[Value], _: &mut Interpreter) -> Resul Ok(to_value(-1)) } -/// Array.prototype.find ( callback, [thisArg] ) +/// `Array.prototype.find( callback, [thisArg] )` /// /// The find method executes the callback function once for each index of the array /// until the callback returns a truthy value. If so, find immediately returns the value @@ -701,7 +703,7 @@ pub fn find(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Resu Ok(Gc::new(ValueData::Undefined)) } -/// Array.prototype.findIndex ( predicate [ , thisArg ] ) +/// `Array.prototype.findIndex( predicate [ , thisArg ] )` /// /// This method executes the provided predicate function for each element of the array. /// If the predicate function returns `true` for an element, this method returns the index of the element. @@ -744,7 +746,7 @@ pub fn find_index(this: &Value, args: &[Value], interpreter: &mut Interpreter) - Ok(Gc::new(ValueData::Number(f64::from(-1)))) } -/// Array.prototype.fill ( value[, start[, end]] ) +/// `Array.prototype.fill( value[, start[, end]] )` /// /// The method fills (modifies) all the elements of an array from start index (default 0) /// to an end index (default array length) with a static value. It returns the modified array. @@ -784,7 +786,7 @@ pub fn fill(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(this.clone()) } -/// Array.prototype.includes( valueToFind [, fromIndex] ) +/// `Array.prototype.includes( valueToFind [, fromIndex] )` /// /// Determines whether an array includes a certain value among its entries, returning `true` or `false` as appropriate. /// @@ -814,7 +816,7 @@ pub fn includes_value(this: &Value, args: &[Value], _: &mut Interpreter) -> Resu Ok(to_value(false)) } -/// Array.prototype.slice ( [begin[, end]] ) +/// `Array.prototype.slice( [begin[, end]] )` /// /// The slice method takes two arguments, start and end, and returns an array containing the /// elements of the array from element start up to, but not including, element end (or through the @@ -866,7 +868,7 @@ pub fn slice(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Res Ok(new_array) } -/// Array.prototype.filter ( callback, [ thisArg ] ) +/// `Array.prototype.filter( callback, [ thisArg ] )` /// /// For each element in the array the callback function is called, and a new /// array is constructed for every value whose callback returned a truthy value. diff --git a/boa/src/builtins/json.rs b/boa/src/builtins/json.rs index f44399c4bb..72c8c6b33a 100644 --- a/boa/src/builtins/json.rs +++ b/boa/src/builtins/json.rs @@ -19,7 +19,9 @@ use crate::builtins::value::{to_value, ResultValue, Value, ValueData}; use crate::exec::Interpreter; use serde_json::{self, Value as JSONValue}; -/// The `JSON` method parses a JSON string, constructing the JavaScript value or object described by the string. +/// `JSON.parse( text[, reviver] )` +/// +/// This `JSON` method parses a JSON string, constructing the JavaScript value or object described by the string. /// /// An optional `reviver` function can be provided to perform a transformation on the resulting object before it is returned. /// @@ -43,7 +45,9 @@ pub fn parse(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { } } -/// The `JSON` method converts a JavaScript object or value to a JSON string. +/// `JSON.stringify( value[, replacer[, space]] )` +/// +/// This `JSON` method converts a JavaScript object or value to a JSON string. /// /// This medhod optionally replaces values if a `replacer` function is specified or /// optionally including only the specified properties if a replacer array is specified. diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index f7c0f79645..b8a34cd600 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -117,7 +117,7 @@ pub fn to_fixed(this: &Value, args: &[Value], _ctx: &mut Interpreter) -> ResultV /// /// Note that while this technically conforms to the Ecma standard, it does no actual /// internationalization logic. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] @@ -131,7 +131,7 @@ pub fn to_locale_string(this: &Value, _args: &[Value], _ctx: &mut Interpreter) - } /// The `toPrecision()` method returns a string representing the Number object to the specified precision. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] @@ -153,7 +153,7 @@ pub fn to_precision(this: &Value, args: &[Value], _ctx: &mut Interpreter) -> Res } /// The `toString()` method returns a string representing the specified Number object. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] @@ -165,7 +165,7 @@ pub fn to_string(this: &Value, _args: &[Value], _ctx: &mut Interpreter) -> Resul } /// The `valueOf()` method returns the wrapped primitive value of a Number object. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index c822acdbc3..fb8467e06b 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -1,3 +1,14 @@ +//! This module implements the global `RegExp` object. +//! +//! `The `RegExp` object is used for matching text with a pattern. +//! +//! More information: +//! - [ECMAScript reference][spec] +//! - [MDN documentation][mdn] +//! +//! [spec]: https://tc39.es/ecma262/#sec-regexp-constructor +//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp + use std::ops::Deref; use gc::Gc; @@ -13,30 +24,40 @@ use crate::{ exec::Interpreter, }; +/// The internal representation on a `RegExp` object. #[derive(Debug)] struct RegExp { /// Regex matcher. matcher: Regex, + /// Update last_index, set if global or sticky flags are set. use_last_index: bool, + /// String of parsed flags. flags: String, + /// Flag 's' - dot matches newline characters. dot_all: bool, + /// Flag 'g' global: bool, + /// Flag 'i' - ignore case. ignore_case: bool, + /// Flag 'm' - '^' and '$' match beginning/end of line. multiline: bool, + /// Flag 'y' sticky: bool, + /// Flag 'u' - Unicode. unicode: bool, } impl InternalState for RegExp {} +/// Helper function for getting an argument. fn get_argument(args: &[Value], idx: usize) -> Result { match args.get(idx) { Some(arg) => from_value(arg.clone()).map_err(to_value), @@ -150,43 +171,138 @@ pub fn make_regexp(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultV Ok(this.clone()) } +/// `RegExp.prototype.dotAll` +/// +/// The `dotAll` property indicates whether or not the "`s`" flag is used with the regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.dotAll +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll fn get_dot_all(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.dot_all))) } +/// `RegExp.prototype.flags` +/// +/// The `flags` property returns a string consisting of the [`flags`][flags] of the current regular expression object. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.flags +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags +/// [flags]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2 fn get_flags(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.flags.clone()))) } +/// `RegExp.prototype.global` +/// +/// The `global` property indicates whether or not the "`g`" flag is used with the regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.global +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global fn get_global(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.global))) } +/// `RegExp.prototype.ignoreCase` +/// +/// The `ignoreCase` property indicates whether or not the "`i`" flag is used with the regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.ignorecase +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase fn get_ignore_case(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.ignore_case))) } +/// `RegExp.prototype.multiline` +/// +/// The multiline property indicates whether or not the "m" flag is used with the regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.multiline +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline fn get_multiline(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.multiline))) } +/// `RegExp.prototype.source` +/// +/// The `source` property returns a `String` containing the source text of the regexp object, +/// and it doesn't contain the two forward slashes on both sides and any flags. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.source +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source fn get_source(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(this.get_internal_slot("OriginalSource")) } +/// `RegExp.prototype.sticky` +/// +/// The `flags` property returns a string consisting of the [`flags`][flags] of the current regular expression object. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.sticky +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky fn get_sticky(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.sticky))) } +/// `RegExp.prototype.unicode` +/// +/// The unicode property indicates whether or not the "`u`" flag is used with a regular expression. +/// unicode is a read-only property of an individual regular expression instance. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.unicode +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode fn get_unicode(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { this.with_internal_state_ref(|regex: &RegExp| Ok(to_value(regex.unicode))) } +/// Helper function. fn _make_prop(getter: NativeFunctionData) -> Property { Property::default().get(to_value(getter)) } -/// Search for a match between this regex and a specified string +/// `RegExp.prototype.test( string )` +/// +/// The `test()` method executes a search for a match between a regular expression and a specified string. +/// +/// Returns `true` or `false`. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.test +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test pub fn test(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { let arg_str = get_argument::(args, 0)?; let mut last_index = @@ -209,7 +325,18 @@ pub fn test(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { result } -/// Search for a match between this regex and a specified string +/// `RegExp.prototype.exec( string )` +/// +/// The exec() method executes a search for a match in a specified string. +/// +/// Returns a result array, or `null`. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.exec +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec pub fn exec(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { let arg_str = get_argument::(args, 0)?; let mut last_index = @@ -250,8 +377,16 @@ pub fn exec(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { result } -/// RegExp.prototype[Symbol.match] -/// Returns matches of the regular expression against a string +/// `RegExp.prototype[ @@match ]( string )` +/// +/// This method retrieves the matches when matching a string against a regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype-@@match +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match pub fn r#match(this: &Value, arg: String, ctx: &mut Interpreter) -> ResultValue { let (matcher, flags) = this.with_internal_state_ref(|regex: &RegExp| (regex.matcher.clone(), regex.flags.clone())); @@ -269,16 +404,33 @@ pub fn r#match(this: &Value, arg: String, ctx: &mut Interpreter) -> ResultValue } } -/// Return a string representing the regular expression +/// `RegExp.prototype.toString()` +/// +/// Return a string representing the regular expression. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.tostring +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toString pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { let body = from_value::(this.get_internal_slot("OriginalSource")).map_err(to_value)?; let flags = this.with_internal_state_ref(|regex: &RegExp| regex.flags.clone()); Ok(to_value(format!("/{}/{}", body, flags))) } -/// RegExp.prototype[Symbol.matchAll] -/// Returns all matches of the regular expression against a string -/// TODO: it's returning an array, it should return an iterator +/// `RegExp.prototype[ @@matchAll ]( string )` +/// +/// The `[@@matchAll]` method returns all matches of the regular expression against a string. +/// +/// More information: +/// - [ECMAScript reference][spec] +/// - [MDN documentation][mdn] +/// +/// [spec]: https://tc39.es/ecma262/#sec-regexp-prototype-matchall +/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll +// TODO: it's returning an array, it should return an iterator pub fn match_all(this: &Value, arg_str: String) -> ResultValue { let matches: Vec = this.with_internal_state_ref(|regex: &RegExp| { let mut matches = Vec::new(); @@ -319,7 +471,7 @@ pub fn match_all(this: &Value, arg_str: String) -> ResultValue { Ok(result) } -/// Create a new `RegExp` object +/// Create a new `RegExp` object. pub fn create_constructor(global: &Value) -> Value { // Create constructor function let mut regexp_constructor = Object::default(); diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index d059e8e3d6..5c0e3aca21 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -73,6 +73,8 @@ pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue Ok(to_value(format!("{}", primitive_val))) } +/// `String.prototype.charAt( index )` +/// /// The `String` object's `charAt()` method returns a new string consisting of the single UTF-16 code unit located at the specified offset into the string. /// /// Characters in a string are indexed from left to right. The index of the first character is `0`, @@ -80,7 +82,7 @@ pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue /// If the `index` you supply is out of this range, JavaScript returns an empty string. /// /// If no index is provided to `charAt()`, the default is `0`. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] @@ -117,6 +119,8 @@ pub fn char_at(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal )) } +/// `String.prototype.charCodeAt( index )` +/// /// The `charCodeAt()` method returns an integer between `0` and `65535` representing the UTF-16 code unit at the given index. /// /// Unicode code points range from `0` to `1114111` (`0x10FFFF`). The first 128 Unicode code points are a direct match of the ASCII character encoding. @@ -157,12 +161,14 @@ pub fn char_code_at(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Resu Ok(to_value(f64::from(utf16_val))) } +/// `String.prototype.concat( str1[, ...strN] )` +/// /// The `concat()` method concatenates the string arguments to the calling string and returns a new string. /// /// Changes to the original string or the returned string don't affect the other. -/// +/// /// If the arguments are not of the type string, they are converted to string values before concatenating. -/// +/// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] @@ -182,6 +188,8 @@ pub fn concat(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValu Ok(to_value(new_str)) } +/// `String.prototype.repeat( count )` +/// /// The `repeat()` method constructs and returns a new string which contains the specified number of /// copies of the string on which it was called, concatenated together. /// @@ -205,6 +213,8 @@ pub fn repeat(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValu Ok(to_value(primitive_val.repeat(repeat_times))) } +/// `String.prototype.slice( beginIndex [, endIndex] )` +/// /// The `slice()` method extracts a section of a string and returns it as a new string, without modifying the original string. /// /// More information: @@ -260,6 +270,8 @@ pub fn slice(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue Ok(to_value(new_str)) } +/// `String.prototype.startWith( searchString[, position] )` +/// /// The `startsWith()` method determines whether a string begins with the characters of a specified string, returning `true` or `false` as appropriate. /// /// More information: @@ -303,6 +315,8 @@ pub fn starts_with(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Resul } } +/// `String.prototype.endsWith( searchString[, length] )` +/// /// The `endsWith()` method determines whether a string ends with the characters of a specified string, returning `true` or `false` as appropriate. /// /// More information: @@ -348,6 +362,8 @@ pub fn ends_with(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultV } } +/// `String.prototype.includes( searchString[, position] )` +/// /// The `includes()` method determines whether one string may be found within another string, returning `true` or `false` as appropriate. /// /// More information: @@ -406,11 +422,13 @@ fn get_regex_string(value: &Value) -> String { } } +/// `String.prototype.replace( regexp|substr, newSubstr|function )` +/// /// The `replace()` method returns a new string with some or all matches of a `pattern` replaced by a `replacement`. /// /// The `pattern` can be a string or a `RegExp`, and the `replacement` can be a string or a function to be called for each match. /// If `pattern` is a string, only the first occurrence will be replaced. -/// +/// /// The original string is left unchanged. /// /// More information: @@ -509,6 +527,8 @@ pub fn replace(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal ))) } +/// `String.prototype.indexOf( searchValue[, fromIndex] )` +/// /// The `indexOf()` method returns the index within the calling `String` object of the first occurrence of the specified value, starting the search at `fromIndex`. /// /// Returns -1 if the value is not found. @@ -559,7 +579,9 @@ pub fn index_of(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa Ok(to_value(-1)) } -//// The `lastIndexOf()` method returns the index within the calling `String` object of the last occurrence of the specified value, searching backwards from `fromIndex`. +/// `String.prototype.lastIndexOf( searchValue[, fromIndex] )` +/// +/// The `lastIndexOf()` method returns the index within the calling `String` object of the last occurrence of the specified value, searching backwards from `fromIndex`. /// /// Returns -1 if the value is not found. /// @@ -610,6 +632,8 @@ pub fn last_index_of(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Res Ok(to_value(highest_index)) } +/// `String.prototype.match( regexp )` +/// /// The `match()` method retrieves the result of matching a **string** against a [`regular expression`][regex]. /// /// More information: @@ -624,7 +648,8 @@ pub fn r#match(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal regexp_match(&re, ctx.value_to_rust_string(this), ctx) } -/// Abstract method `StringPad` +/// Abstract method `StringPad`. +/// /// Performs the actual string padding for padStart/End. /// fn string_pad( @@ -664,6 +689,8 @@ fn string_pad( } } +/// `String.prototype.padEnd( targetLength[, padString] )` +/// /// The `padEnd()` method pads the current string with a given string (repeated, if needed) so that the resulting string reaches a given length. /// /// The padding is applied from the end of the current string. @@ -696,6 +723,8 @@ pub fn pad_end(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal string_pad(primitive_val, max_length, fill_string, false) } +/// `String.prototype.padStart( targetLength [, padString] )` +/// /// The `padStart()` method pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length. /// /// The padding is applied from the start of the current string. @@ -728,6 +757,7 @@ pub fn pad_start(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultV string_pad(primitive_val, max_length, fill_string, true) } +/// Helper function to check if a `char` is trimmable. fn is_trimmable_whitespace(c: char) -> bool { // The rust implementation of `trim` does not regard the same characters whitespace as ecma standard does // @@ -746,6 +776,8 @@ fn is_trimmable_whitespace(c: char) -> bool { } } +/// String.prototype.trim() +/// /// The `trim()` method removes whitespace from both ends of a string. /// /// Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.). @@ -761,6 +793,8 @@ pub fn trim(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue { Ok(to_value(this_str.trim_matches(is_trimmable_whitespace))) } +/// `String.prototype.trimStart()` +/// /// The `trimStart()` method removes whitespace from the beginning of a string. /// /// Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.). @@ -778,6 +812,8 @@ pub fn trim_start(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultVal )) } +/// String.prototype.trimEnd() +/// /// The `trimEnd()` method removes whitespace from the end of a string. /// /// Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.). @@ -793,6 +829,8 @@ pub fn trim_end(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue Ok(to_value(this_str.trim_end_matches(is_trimmable_whitespace))) } +/// `String.prototype.toLowerCase()` +/// /// The `toLowerCase()` method returns the calling string value converted to lower case. /// /// More information: @@ -810,6 +848,8 @@ pub fn to_lowercase(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultV Ok(to_value(this_str.to_lowercase())) } +/// `String.prototype.toUpperCase()` +/// /// The `toUpperCase()` method returns the calling string value converted to uppercase. /// /// The value will be **converted** to a string if it isn't one @@ -829,6 +869,8 @@ pub fn to_uppercase(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultV Ok(to_value(this_str.to_uppercase())) } +/// `String.prototype.substring( indexStart[, indexEnd] )` +/// /// The `substring()` method returns the part of the `string` between the start and end indexes, or to the end of the string. /// /// More information: @@ -877,6 +919,8 @@ pub fn substring(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultV Ok(to_value(extracted_string)) } +/// `String.prototype.substr( start[, length] )` +/// /// The `substr()` method returns a portion of the string, starting at the specified index and extending for a given number of characters afterward. /// /// More information: @@ -933,6 +977,8 @@ pub fn substr(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValu } } +/// String.prototype.valueOf() +/// /// The `valueOf()` method returns the primitive value of a `String` object. /// /// More information: @@ -946,6 +992,8 @@ pub fn value_of(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa to_string(this, args, ctx) } +/// `String.prototype.matchAll( regexp )` +/// /// The `matchAll()` method returns an iterator of all results matching a string against a [`regular expression`][regex], including [capturing groups][cg]. /// /// More information: