From 60b7eb89340c266a2b4f180690e8781245b6a1c8 Mon Sep 17 00:00:00 2001 From: Iban Eguia Date: Thu, 3 Feb 2022 09:59:06 +0000 Subject: [PATCH] General code clean-up and new lint addition (#1809) This PR adds some Clippy lints. Mainly, it adds the list of pedantic lints excluding some lints that were causing too many warnings. I also denied some useful restriction and pedantic lints, to make sure we use `Self` all the possible times (for better maintainability), and that we pass elements by reference where possible, for example, or that the documentation is properly written. This might even have some small performance gains. I also added a perfect hash function for the CLI keywords, which should be more efficient than a `HashSet`. This is something we could use elsewhere too. --- Cargo.lock | 58 ++++- boa/src/bigint.rs | 12 +- boa/src/builtins/array/array_iterator.rs | 8 +- boa/src/builtins/array/mod.rs | 36 +-- boa/src/builtins/array/tests.rs | 2 +- boa/src/builtins/array_buffer/mod.rs | 10 +- boa/src/builtins/array_buffer/tests.rs | 4 +- boa/src/builtins/bigint/mod.rs | 21 +- boa/src/builtins/boolean/mod.rs | 2 +- boa/src/builtins/console/mod.rs | 15 +- boa/src/builtins/dataview/mod.rs | 144 +++++++----- boa/src/builtins/date/mod.rs | 105 ++++----- boa/src/builtins/date/tests.rs | 212 +++++------------- boa/src/builtins/error/syntax.rs | 2 +- boa/src/builtins/function/arguments.rs | 12 +- boa/src/builtins/function/mod.rs | 11 +- boa/src/builtins/function/tests.rs | 2 +- boa/src/builtins/intl/mod.rs | 2 +- boa/src/builtins/intrinsics.rs | 2 +- boa/src/builtins/iterable/mod.rs | 14 +- boa/src/builtins/json/mod.rs | 27 +-- boa/src/builtins/map/map_iterator.rs | 8 +- boa/src/builtins/map/mod.rs | 7 +- boa/src/builtins/map/ordered_map.rs | 12 +- boa/src/builtins/math/mod.rs | 5 +- boa/src/builtins/number/conversions.rs | 6 +- boa/src/builtins/number/mod.rs | 94 ++++---- boa/src/builtins/object/for_in_iterator.rs | 12 +- boa/src/builtins/object/mod.rs | 22 +- boa/src/builtins/object/tests.rs | 2 +- boa/src/builtins/reflect/mod.rs | 32 +-- boa/src/builtins/regexp/mod.rs | 101 +++++---- .../builtins/regexp/regexp_string_iterator.rs | 17 +- boa/src/builtins/set/mod.rs | 11 +- boa/src/builtins/set/ordered_set.rs | 39 ++-- boa/src/builtins/set/set_iterator.rs | 10 +- boa/src/builtins/string/mod.rs | 98 ++++---- boa/src/builtins/string/string_iterator.rs | 8 +- boa/src/builtins/string/tests.rs | 11 +- boa/src/builtins/symbol/mod.rs | 6 +- .../typed_array/integer_indexed_object.rs | 6 +- boa/src/builtins/typed_array/mod.rs | 38 ++-- boa/src/bytecompiler.rs | 103 +++------ boa/src/context.rs | 10 +- .../declarative_environment_record.rs | 6 +- .../environment/environment_record_trait.rs | 6 +- .../function_environment_record.rs | 8 +- .../environment/global_environment_record.rs | 11 +- .../environment/object_environment_record.rs | 15 +- boa/src/lib.rs | 29 ++- boa/src/object/internal_methods/arguments.rs | 3 +- boa/src/object/internal_methods/array.rs | 2 +- .../internal_methods/integer_indexed.rs | 15 +- boa/src/object/internal_methods/mod.rs | 35 +-- boa/src/object/internal_methods/proxy.rs | 15 +- boa/src/object/internal_methods/string.rs | 13 +- boa/src/object/jsobject.rs | 18 +- boa/src/object/mod.rs | 9 +- boa/src/object/operations.rs | 50 ++--- boa/src/object/property_map.rs | 4 +- boa/src/profiler.rs | 14 +- boa/src/property/mod.rs | 113 +++++----- boa/src/string.rs | 32 +-- boa/src/symbol.rs | 2 +- boa/src/syntax/ast/keyword.rs | 4 +- .../node/conditional/conditional_op/mod.rs | 2 +- .../ast/node/conditional/if_node/mod.rs | 2 +- boa/src/syntax/ast/node/declaration/mod.rs | 61 ++--- .../ast/node/field/get_const_field/mod.rs | 2 +- .../syntax/ast/node/field/get_field/mod.rs | 2 +- .../ast/node/iteration/break_node/mod.rs | 2 +- .../ast/node/iteration/continue_node/mod.rs | 2 +- .../ast/node/iteration/for_in_loop/mod.rs | 2 +- .../ast/node/iteration/for_of_loop/mod.rs | 2 +- boa/src/syntax/ast/node/iteration/tests.rs | 6 +- boa/src/syntax/ast/node/mod.rs | 14 +- boa/src/syntax/ast/node/object/mod.rs | 10 +- boa/src/syntax/ast/node/return_smt/mod.rs | 4 +- boa/src/syntax/ast/node/spread/mod.rs | 2 +- boa/src/syntax/ast/node/template/mod.rs | 6 +- boa/src/syntax/ast/node/throw/mod.rs | 2 +- boa/src/syntax/ast/node/yield/mod.rs | 4 +- boa/src/syntax/ast/position.rs | 6 +- boa/src/syntax/lexer/comment.rs | 7 +- boa/src/syntax/lexer/cursor.rs | 27 +-- boa/src/syntax/lexer/identifier.rs | 11 +- boa/src/syntax/lexer/mod.rs | 6 +- boa/src/syntax/lexer/number.rs | 41 ++-- boa/src/syntax/lexer/regex.rs | 5 +- boa/src/syntax/lexer/string.rs | 29 +-- boa/src/syntax/lexer/template.rs | 6 +- boa/src/syntax/lexer/tests.rs | 18 +- .../parser/cursor/buffered_lexer/mod.rs | 8 +- boa/src/syntax/parser/cursor/mod.rs | 16 +- boa/src/syntax/parser/error.rs | 4 +- .../expression/assignment/arrow_function.rs | 4 +- .../expression/assignment/exponentiation.rs | 11 +- .../parser/expression/assignment/mod.rs | 4 +- .../parser/expression/assignment/yield.rs | 4 +- .../parser/expression/left_hand_side/call.rs | 2 +- .../expression/left_hand_side/member.rs | 4 +- boa/src/syntax/parser/expression/mod.rs | 20 +- .../primary/array_initializer/mod.rs | 2 +- .../primary/async_generator_expression/mod.rs | 4 +- .../primary/function_expression/mod.rs | 4 +- .../primary/object_initializer/mod.rs | 204 +++++++++-------- .../primary/object_initializer/tests.rs | 4 +- boa/src/syntax/parser/expression/update.rs | 6 +- boa/src/syntax/parser/function/mod.rs | 4 +- boa/src/syntax/parser/statement/block/mod.rs | 2 +- .../syntax/parser/statement/break_stm/mod.rs | 2 +- .../parser/statement/continue_stm/mod.rs | 2 +- .../hoistable/async_generator_decl/mod.rs | 5 +- .../parser/statement/declaration/lexical.rs | 6 +- .../parser/statement/declaration/mod.rs | 18 +- .../syntax/parser/statement/expression/mod.rs | 2 +- .../statement/iteration/for_statement.rs | 8 +- boa/src/syntax/parser/statement/mod.rs | 34 ++- .../syntax/parser/statement/return_stm/mod.rs | 2 +- boa/src/syntax/parser/statement/switch/mod.rs | 2 +- .../syntax/parser/statement/switch/tests.rs | 2 +- boa/src/syntax/parser/statement/throw/mod.rs | 2 +- .../syntax/parser/statement/try_stm/catch.rs | 2 +- .../syntax/parser/statement/variable/mod.rs | 2 +- boa/src/tests.rs | 12 +- boa/src/value/conversions.rs | 54 ++--- boa/src/value/display.rs | 56 ++--- boa/src/value/equality.rs | 32 ++- boa/src/value/hash.rs | 3 +- boa/src/value/mod.rs | 41 ++-- boa/src/value/operations.rs | 43 ++-- boa/src/value/tests.rs | 8 +- boa/src/value/type.rs | 2 +- boa/src/vm/call_frame.rs | 5 +- boa/src/vm/code_block.rs | 46 ++-- boa/src/vm/mod.rs | 65 +++--- boa_cli/Cargo.toml | 2 +- boa_cli/src/helper.rs | 81 ++++--- boa_cli/src/main.rs | 48 +++- boa_interner/src/lib.rs | 38 +++- boa_interner/src/tests.rs | 2 +- boa_tester/src/exec/js262.rs | 6 +- boa_tester/src/exec/mod.rs | 31 ++- boa_tester/src/main.rs | 53 +++-- boa_tester/src/read.rs | 2 +- boa_tester/src/results.rs | 7 +- boa_unicode/src/lib.rs | 41 +++- boa_wasm/src/lib.rs | 29 ++- clippy.toml | 1 + docs/profiling.md | 2 +- 150 files changed, 1646 insertions(+), 1504 deletions(-) create mode 100644 clippy.toml diff --git a/Cargo.lock b/Cargo.lock index 8ac4db3abb..c4e0491db8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,7 +100,7 @@ dependencies = [ "Boa", "colored", "jemallocator", - "lazy_static", + "phf", "regex", "rustyline", "rustyline-derive", @@ -938,6 +938,50 @@ dependencies = [ "libc", ] +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "pkg-config" version = "0.3.24" @@ -1002,6 +1046,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.36" @@ -1295,6 +1345,12 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + [[package]] name = "smallvec" version = "1.8.0" diff --git a/boa/src/bigint.rs b/boa/src/bigint.rs index 504f74f40f..9fc6002132 100644 --- a/boa/src/bigint.rs +++ b/boa/src/bigint.rs @@ -77,15 +77,15 @@ impl JsBigInt { self.inner.to_str_radix(radix) } - /// Converts the BigInt to a f64 type. + /// Converts the `BigInt` to a f64 type. /// - /// Returns `f64::INFINITY` if the BigInt is too big. + /// Returns `f64::INFINITY` if the `BigInt` is too big. #[inline] pub fn to_f64(&self) -> f64 { self.inner.to_f64().unwrap_or(f64::INFINITY) } - /// Converts a string to a BigInt with the specified radix. + /// Converts a string to a `BigInt` with the specified radix. #[inline] pub fn from_string_radix(buf: &str, radix: u32) -> Option { Some(Self { @@ -93,7 +93,7 @@ impl JsBigInt { }) } - /// This function takes a string and conversts it to BigInt type. + /// This function takes a string and conversts it to `BigInt` type. /// /// More information: /// - [ECMAScript reference][spec] @@ -104,7 +104,7 @@ impl JsBigInt { string = string.trim(); if string.is_empty() { - return Some(JsBigInt::zero()); + return Some(Self::zero()); } let mut radix = 10; @@ -149,7 +149,7 @@ impl JsBigInt { /// Checks for mathematical equality. /// - /// The abstract operation BigInt::equal takes arguments x (a `BigInt`) and y (a `BigInt`). + /// The abstract operation `BigInt::equal` takes arguments x (a `BigInt`) and y (a `BigInt`). /// It returns `true` if x and y have the same mathematical integer value and false otherwise. /// /// More information: diff --git a/boa/src/builtins/array/array_iterator.rs b/boa/src/builtins/array/array_iterator.rs index 02e6377350..45a52fd71c 100644 --- a/boa/src/builtins/array/array_iterator.rs +++ b/boa/src/builtins/array/array_iterator.rs @@ -25,7 +25,7 @@ impl ArrayIterator { pub(crate) const NAME: &'static str = "ArrayIterator"; fn new(array: JsObject, kind: PropertyNameKind) -> Self { - ArrayIterator { + Self { array, kind, next_index: 0, @@ -33,7 +33,7 @@ impl ArrayIterator { } } - /// CreateArrayIterator( array, kind ) + /// `CreateArrayIterator( array, kind )` /// /// Creates a new iterator over the given array. /// @@ -62,7 +62,7 @@ impl ArrayIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut array_iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut array_iterator = this.as_object().map(JsObject::borrow_mut); let array_iterator = array_iterator .as_mut() .and_then(|obj| obj.as_array_iterator_mut()) @@ -111,7 +111,7 @@ impl ArrayIterator { } } - /// Create the %ArrayIteratorPrototype% object + /// Create the `%ArrayIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index a0ea312bc1..acec9aeea4 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -142,7 +142,7 @@ impl Array { // 4. If numberOfArgs = 0, then if number_of_args == 0 { // 4.a. Return ! ArrayCreate(0, proto). - Ok(Array::array_create(0, Some(prototype), context) + Ok(Self::array_create(0, Some(prototype), context) .unwrap() .into()) // 5. Else if numberOfArgs = 1, then @@ -150,8 +150,9 @@ impl Array { // a. Let len be values[0]. let len = &args[0]; // b. Let array be ! ArrayCreate(0, proto). - let array = Array::array_create(0, Some(prototype), context).unwrap(); + let array = Self::array_create(0, Some(prototype), context).unwrap(); // c. If Type(len) is not Number, then + #[allow(clippy::if_not_else)] let int_len = if !len.is_number() { // i. Perform ! CreateDataPropertyOrThrow(array, "0", len). array @@ -179,7 +180,7 @@ impl Array { debug_assert!(number_of_args >= 2); // b. Let array be ? ArrayCreate(numberOfArgs, proto). - let array = Array::array_create(number_of_args, Some(prototype), context)?; + let array = Self::array_create(number_of_args, Some(prototype), context)?; // c. Let k be 0. // d. Repeat, while k < numberOfArgs, for (i, item) in args.iter().cloned().enumerate() { @@ -304,13 +305,14 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-get-array-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) } /// Utility function used to specify the creation of a new Array object using a constructor - /// function that is derived from original_array. + /// function that is derived from `original_array`. /// /// see: pub(crate) fn array_species_create( @@ -414,9 +416,7 @@ impl Array { context: &mut Context, ) -> JsResult { // 1. Return ? IsArray(arg). - args.get_or_undefined(0) - .is_array(context) - .map(|ok| ok.into()) + args.get_or_undefined(0).is_array(context).map(Into::into) } /// `Array.of(...items)` @@ -448,7 +448,7 @@ impl Array { .ok_or_else(|| { context.construct_type_error("object constructor didn't return an object") })?, - _ => Array::array_create(len, None, context)?, + _ => Self::array_create(len, None, context)?, }; // 6. Let k be 0. @@ -574,7 +574,7 @@ impl Array { // iii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), E). arr.create_data_property_or_throw(n, item, context)?; // iv. Set n to n + 1. - n += 1 + n += 1; } } // 6. Perform ? Set(A, "length", 𝔽(n), true). @@ -1152,7 +1152,7 @@ impl Array { let mut k; if n >= 0 { // a. Let k be n. - k = n + k = n; // 9. Else, } else { // a. Let k be len + n. @@ -1189,7 +1189,7 @@ impl Array { /// `Array.prototype.lastIndexOf( searchElement[, fromIndex ] )` /// /// - /// lastIndexOf compares searchElement to the elements of the array in descending order + /// `lastIndexOf` compares searchElement to the elements of the array in descending order /// using the Strict Equality Comparison algorithm, and if found at one or more indices, /// returns the largest such index; otherwise, -1 is returned. /// @@ -1426,9 +1426,9 @@ impl Array { /// `Array.prototype.findLastIndex( predicate [ , thisArg ] )` /// - /// findLastIndex calls predicate once for each element of the array, in descending order, - /// until it finds one where predicate returns true. If such an element is found, findLastIndex - /// immediately returns the index of that element value. Otherwise, findLastIndex returns -1. + /// `findLastIndex` calls predicate once for each element of the array, in descending order, + /// until it finds one where predicate returns true. If such an element is found, `findLastIndex` + /// immediately returns the index of that element value. Otherwise, `findLastIndex` returns -1. /// /// More information: /// - [ECMAScript proposal][spec] @@ -1565,7 +1565,7 @@ impl Array { source_len as u64, 0, 1, - Some(mapper_function.clone()), + Some(mapper_function), args.get_or_undefined(1), context, )?; @@ -1587,7 +1587,7 @@ impl Array { source_len: u64, start: u64, depth: u64, - mapper_function: Option, + mapper_function: Option<&JsObject>, this_arg: &JsValue, context: &mut Context, ) -> JsResult { @@ -1618,7 +1618,7 @@ impl Array { let mut element = source.get(p, context)?; // ii. If mapperFunction is present, then - if let Some(ref mapper_function) = mapper_function { + if let Some(mapper_function) = mapper_function { // 1. Set element to ? Call(mapperFunction, thisArg, <>) element = mapper_function.call( this_arg, @@ -1781,7 +1781,7 @@ impl Array { let mut k; if n >= 0 { // a. Let k be n. - k = n + k = n; // 9. Else, } else { // a. Let k be len + n. diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 2374fb1363..c9fa6cd6f4 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -818,7 +818,7 @@ fn map() { // One but it uses `this` inside the callback let one_with_this = forward(&mut context, "one.map(callbackThatUsesThis, _this)[0];"); - assert_eq!(one_with_this, String::from("\"The answer to life is: 42\"")) + assert_eq!(one_with_this, String::from("\"The answer to life is: 42\"")); } #[test] diff --git a/boa/src/builtins/array_buffer/mod.rs b/boa/src/builtins/array_buffer/mod.rs index e61d433aee..39bd7c29b2 100644 --- a/boa/src/builtins/array_buffer/mod.rs +++ b/boa/src/builtins/array_buffer/mod.rs @@ -105,6 +105,7 @@ impl ArrayBuffer { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-get-arraybuffer-@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) @@ -116,6 +117,7 @@ impl ArrayBuffer { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-arraybuffer.isview + #[allow(clippy::unnecessary_wraps)] fn is_view(_: &JsValue, args: &[JsValue], _context: &mut Context) -> JsResult { // 1. If Type(arg) is not Object, return false. // 2. If arg has a [[ViewedArrayBuffer]] internal slot, return true. @@ -320,7 +322,7 @@ impl ArrayBuffer { // 3. Set obj.[[ArrayBufferData]] to block. // 4. Set obj.[[ArrayBufferByteLength]] to byteLength. - obj.borrow_mut().data = ObjectData::array_buffer(ArrayBuffer { + obj.borrow_mut().data = ObjectData::array_buffer(Self { array_buffer_data: Some(block), array_buffer_byte_length: byte_length, array_buffer_detach_key: JsValue::Undefined, @@ -600,7 +602,7 @@ impl ArrayBuffer { /// [spec]: https://tc39.es/ecma262/#sec-numerictorawbytes fn numeric_to_raw_bytes( t: TypedArrayName, - value: JsValue, + value: &JsValue, is_little_endian: bool, context: &mut Context, ) -> JsResult> { @@ -696,7 +698,7 @@ impl ArrayBuffer { &mut self, byte_index: usize, t: TypedArrayName, - value: JsValue, + value: &JsValue, _order: SharedMemoryOrder, is_little_endian: Option, context: &mut Context, @@ -804,7 +806,7 @@ fn copy_data_block_bytes( // TODO: Allow unused variants until shared array buffers are implemented. #[allow(dead_code)] -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone, Copy)] pub(crate) enum SharedMemoryOrder { Init, SeqCst, diff --git a/boa/src/builtins/array_buffer/tests.rs b/boa/src/builtins/array_buffer/tests.rs index ac776e377b..8965b8145a 100644 --- a/boa/src/builtins/array_buffer/tests.rs +++ b/boa/src/builtins/array_buffer/tests.rs @@ -4,12 +4,12 @@ use super::*; fn ut_sunnyy_day_create_byte_data_block() { let mut context = Context::default(); - assert!(create_byte_data_block(100, &mut context).is_ok()) + assert!(create_byte_data_block(100, &mut context).is_ok()); } #[test] fn ut_rainy_day_create_byte_data_block() { let mut context = Context::default(); - assert!(create_byte_data_block(usize::MAX, &mut context).is_err()) + assert!(create_byte_data_block(usize::MAX, &mut context).is_err()); } diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index 925a8e5c89..67da41cda1 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -71,7 +71,7 @@ impl BigInt { /// `BigInt()` /// - /// The `BigInt()` constructor is used to create BigInt objects. + /// The `BigInt()` constructor is used to create `BigInt` objects. /// /// More information: /// - [ECMAScript reference][spec] @@ -111,10 +111,10 @@ impl BigInt { Ok(JsBigInt::from(number.to_bigint().expect("This conversion must be safe")).into()) } - /// The abstract operation thisBigIntValue takes argument value. + /// The abstract operation `thisBigIntValue` takes argument value. /// - /// The phrase “this BigInt value” within the specification of a method refers to the - /// result returned by calling the abstract operation thisBigIntValue with the `this` value + /// The phrase “this `BigInt` value” within the specification of a method refers to the + /// result returned by calling the abstract operation `thisBigIntValue` with the `this` value /// of the method invocation passed as the argument. /// /// More information: @@ -141,7 +141,7 @@ impl BigInt { /// `BigInt.prototype.toString( [radix] )` /// - /// The `toString()` method returns a string representing the specified BigInt object. + /// The `toString()` method returns a string representing the specified `BigInt` object. /// /// More information: /// - [ECMAScript reference][spec] @@ -225,11 +225,16 @@ impl BigInt { let (modulo, bits) = Self::calculate_as_uint_n(args, context)?; if bits > 0 - && modulo >= JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(bits as i64 - 1), context)? + && modulo + >= JsBigInt::pow( + &JsBigInt::new(2), + &JsBigInt::new(i64::from(bits) - 1), + context, + )? { Ok(JsValue::new(JsBigInt::sub( &modulo, - &JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(bits as i64), context)?, + &JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(i64::from(bits)), context)?, ))) } else { Ok(JsValue::new(modulo)) @@ -270,7 +275,7 @@ impl BigInt { Ok(( JsBigInt::mod_floor( &bigint, - &JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(bits as i64), context)?, + &JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(i64::from(bits)), context)?, ), bits, )) diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 84aa2fd486..2fd7300107 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -65,7 +65,7 @@ impl Boolean { context: &mut Context, ) -> JsResult { // Get the argument, if any - let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false); + let data = args.get(0).map_or(false, JsValue::to_boolean); if new_target.is_undefined() { return Ok(JsValue::new(data)); } diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index cb569baa1c..d360129f39 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -86,13 +86,13 @@ pub fn formatter(data: &[JsValue], context: &mut Context) -> JsResult { .unwrap_or_default() .to_number(context)?; formatted.push_str(&format!("{number:.prec$}", number = arg, prec = 6)); - arg_index += 1 + arg_index += 1; } /* object, FIXME: how to render this properly? */ 'o' | 'O' => { let arg = data.get_or_undefined(arg_index); formatted.push_str(&format!("{}", arg.display())); - arg_index += 1 + arg_index += 1; } /* string */ 's' => { @@ -102,7 +102,7 @@ pub fn formatter(data: &[JsValue], context: &mut Context) -> JsResult { .unwrap_or_default() .to_string(context)?; formatted.push_str(&arg); - arg_index += 1 + arg_index += 1; } '%' => formatted.push('%'), /* TODO: %c is not implemented */ @@ -118,7 +118,7 @@ pub fn formatter(data: &[JsValue], context: &mut Context) -> JsResult { /* unformatted data */ for rest in data.iter().skip(arg_index) { - formatted.push_str(&format!(" {}", rest.to_string(context)?)) + formatted.push_str(&format!(" {}", rest.to_string(context)?)); } Ok(formatted) @@ -189,7 +189,7 @@ impl Console { args: &[JsValue], context: &mut Context, ) -> JsResult { - let assertion = args.get(0).map(JsValue::to_boolean).unwrap_or(false); + let assertion = args.get(0).map_or(false, JsValue::to_boolean); if !assertion { let mut args: Vec = args.iter().skip(1).cloned().collect(); @@ -222,6 +222,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#clear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/clear + #[allow(clippy::unnecessary_wraps)] pub(crate) fn clear(_: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { context.console_mut().groups.clear(); Ok(JsValue::undefined()) @@ -334,7 +335,7 @@ impl Console { ); let stack_trace_dump = Self::get_stack_trace(context).join("\n"); - logger(LogMessage::Log(stack_trace_dump), context.console()) + logger(LogMessage::Log(stack_trace_dump), context.console()); } Ok(JsValue::undefined()) @@ -557,6 +558,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#groupend /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/groupEnd + #[allow(clippy::unnecessary_wraps)] pub(crate) fn group_end( _: &JsValue, _: &[JsValue], @@ -577,6 +579,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#dir /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/dir + #[allow(clippy::unnecessary_wraps)] pub(crate) fn dir(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { logger( LogMessage::Info(display_obj(args.get_or_undefined(0), true)), diff --git a/boa/src/builtins/dataview/mod.rs b/boa/src/builtins/dataview/mod.rs index e57d77efa4..8fab899dd4 100644 --- a/boa/src/builtins/dataview/mod.rs +++ b/boa/src/builtins/dataview/mod.rs @@ -87,13 +87,13 @@ impl DataView { /// `25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )` /// + /// The `DataView` view provides a low-level interface for reading and writing multiple number + /// types in a binary `ArrayBuffer`, without having to care about the platform's endianness. + /// /// More information: /// - [ECMAScript reference][spec] /// - [MDN][mdn] /// - /// The DataView view provides a low-level interface for reading and writing multiple number types in a - /// binary ArrayBuffer, without having to care about the platform's endianness. - /// /// [spec]: https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/DataView pub(crate) fn constructor( @@ -142,9 +142,9 @@ impl DataView { // 8.b. If offset + viewByteLength > bufferByteLength, throw a RangeError exception. if offset + view_byte_length > buffer_byte_length { return context.throw_range_error("Invalid data view length"); - } else { - view_byte_length } + + view_byte_length }; (offset, view_byte_length) }; @@ -165,9 +165,9 @@ impl DataView { let obj = JsObject::from_proto_and_data( prototype, - ObjectData::data_view(DataView { + ObjectData::data_view(Self { // 11. Set O.[[ViewedArrayBuffer]] to buffer. - viewed_array_buffer: buffer_obj.to_owned(), + viewed_array_buffer: buffer_obj.clone(), // 12. Set O.[[ByteLength]] to viewByteLength. byte_length: view_byte_length, // 13. Set O.[[ByteOffset]] to offset. @@ -181,7 +181,8 @@ impl DataView { /// `25.3.4.1 get DataView.prototype.buffer` /// - /// The buffer accessor property represents the ArrayBuffer or SharedArrayBuffer referenced by the DataView at construction time. + /// The buffer accessor property represents the `ArrayBuffer` or `SharedArrayBuffer` referenced + /// by the `DataView` at construction time. /// /// More information: /// - [ECMAScript reference][spec] @@ -196,7 +197,7 @@ impl DataView { ) -> JsResult { // 1. Let O be the this value. // 2. Perform ? RequireInternalSlot(O, [[DataView]]). - let dataview = this.as_object().map(|obj| obj.borrow()); + let dataview = this.as_object().map(JsObject::borrow); let dataview = dataview .as_ref() .and_then(|obj| obj.as_data_view()) @@ -210,7 +211,7 @@ impl DataView { /// `25.3.4.1 get DataView.prototype.byteLength` /// - /// The byteLength accessor property represents the length (in bytes) of the dataview. + /// The `byteLength` accessor property represents the length (in bytes) of the dataview. /// /// More information: /// - [ECMAScript reference][spec] @@ -225,7 +226,7 @@ impl DataView { ) -> JsResult { // 1. Let O be the this value. // 2. Perform ? RequireInternalSlot(O, [[DataView]]). - let dataview = this.as_object().map(|obj| obj.borrow()); + let dataview = this.as_object().map(JsObject::borrow); let dataview = dataview .as_ref() .and_then(|obj| obj.as_data_view()) @@ -248,7 +249,8 @@ impl DataView { /// `25.3.4.1 get DataView.prototype.byteOffset` /// - /// The byteOffset accessor property represents the offset (in bytes) of this view from the start of its ArrayBuffer or SharedArrayBuffer. + /// The `byteOffset` accessor property represents the offset (in bytes) of this view from the + /// start of its `ArrayBuffer` or `SharedArrayBuffer`. /// /// More information: /// - [ECMAScript reference][spec] @@ -263,7 +265,7 @@ impl DataView { ) -> JsResult { // 1. Let O be the this value. // 2. Perform ? RequireInternalSlot(O, [[DataView]]). - let dataview = this.as_object().map(|obj| obj.borrow()); + let dataview = this.as_object().map(JsObject::borrow); let dataview = dataview .as_ref() .and_then(|obj| obj.as_data_view()) @@ -286,8 +288,9 @@ impl DataView { /// `25.3.1.1 GetViewValue ( view, requestIndex, isLittleEndian, type )` /// - /// The abstract operation GetViewValue takes arguments view, requestIndex, isLittleEndian, and type. - /// It is used by functions on DataView instances to retrieve values from the view's buffer. + /// The abstract operation `GetViewValue` takes arguments view, requestIndex, `isLittleEndian`, + /// and type. It is used by functions on `DataView` instances to retrieve values from the + /// view's buffer. /// /// More information: /// - [ECMAScript reference][spec] @@ -302,7 +305,7 @@ impl DataView { ) -> JsResult { // 1. Perform ? RequireInternalSlot(view, [[DataView]]). // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot. - let view = view.as_object().map(|obj| obj.borrow()); + let view = view.as_object().map(JsObject::borrow); let view = view .as_ref() .and_then(|obj| obj.as_data_view()) @@ -353,7 +356,8 @@ impl DataView { /// `25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )` /// - /// The getBigInt64() method gets a signed 64-bit integer (long long) at the specified byte offset from the start of the DataView. + /// The `getBigInt64()` method gets a signed 64-bit integer (long long) at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -370,7 +374,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -381,7 +385,8 @@ impl DataView { /// `25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )` /// - /// The getBigUint64() method gets an unsigned 64-bit integer (unsigned long long) at the specified byte offset from the start of the DataView. + /// The `getBigUint64()` method gets an unsigned 64-bit integer (unsigned long long) at the + /// specified byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -398,7 +403,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -409,7 +414,8 @@ impl DataView { /// `25.3.4.7 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )` /// - /// The getFloat32() method gets a signed 32-bit float (float) at the specified byte offset from the start of the DataView. + /// The `getFloat32()` method gets a signed 32-bit float (float) at the specified byte offset + /// from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -426,7 +432,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -437,7 +443,8 @@ impl DataView { /// `25.3.4.8 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )` /// - /// The getFloat64() method gets a signed 64-bit float (double) at the specified byte offset from the start of the DataView. + /// The `getFloat64()` method gets a signed 64-bit float (double) at the specified byte offset + /// from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -454,7 +461,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -465,7 +472,8 @@ impl DataView { /// `25.3.4.9 DataView.prototype.getInt8 ( byteOffset [ , littleEndian ] )` /// - /// The getInt8() method gets a signed 8-bit integer (byte) at the specified byte offset from the start of the DataView. + /// The `getInt8()` method gets a signed 8-bit integer (byte) at the specified byte offset + /// from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -482,7 +490,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -493,7 +501,8 @@ impl DataView { /// `25.3.4.10 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )` /// - /// The getInt16() method gets a signed 16-bit integer (short) at the specified byte offset from the start of the DataView. + /// The `getInt16()` method gets a signed 16-bit integer (short) at the specified byte offset + /// from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -510,7 +519,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -521,7 +530,8 @@ impl DataView { /// `25.3.4.11 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )` /// - /// The getInt32() method gets a signed 32-bit integer (long) at the specified byte offset from the start of the DataView. + /// The `getInt32()` method gets a signed 32-bit integer (long) at the specified byte offset + /// from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -538,7 +548,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -549,7 +559,8 @@ impl DataView { /// `25.3.4.12 DataView.prototype.getUint8 ( byteOffset [ , littleEndian ] )` /// - /// The getUint8() method gets an unsigned 8-bit integer (unsigned byte) at the specified byte offset from the start of the DataView. + /// The `getUint8()` method gets an unsigned 8-bit integer (unsigned byte) at the specified + /// byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -566,7 +577,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -577,7 +588,8 @@ impl DataView { /// `25.3.4.13 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )` /// - /// The getUint16() method gets an unsigned 16-bit integer (unsigned short) at the specified byte offset from the start of the DataView. + /// The `getUint16()` method gets an unsigned 16-bit integer (unsigned short) at the specified + /// byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -594,7 +606,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -605,7 +617,8 @@ impl DataView { /// `25.3.4.14 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )` /// - /// The getUint32() method gets an unsigned 32-bit integer (unsigned long) at the specified byte offset from the start of the DataView. + /// The `getUint32()` method gets an unsigned 32-bit integer (unsigned long) at the specified + /// byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -622,7 +635,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(1); // 1. Let v be the this value. // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64). - DataView::get_view_value( + Self::get_view_value( this, byte_offset, is_little_endian, @@ -633,8 +646,9 @@ impl DataView { /// `25.3.1.1 SetViewValue ( view, requestIndex, isLittleEndian, type )` /// - /// The abstract operation SetViewValue takes arguments view, requestIndex, isLittleEndian, type, and value. - /// It is used by functions on DataView instances to store values into the view's buffer. + /// The abstract operation `SetViewValue` takes arguments view, requestIndex, `isLittleEndian`, + /// type, and value. It is used by functions on `DataView` instances to store values into the + /// view's buffer. /// /// More information: /// - [ECMAScript reference][spec] @@ -650,7 +664,7 @@ impl DataView { ) -> JsResult { // 1. Perform ? RequireInternalSlot(view, [[DataView]]). // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot. - let view = view.as_object().map(|obj| obj.borrow()); + let view = view.as_object().map(JsObject::borrow); let view = view .as_ref() .and_then(|obj| obj.as_data_view()) @@ -701,7 +715,7 @@ impl DataView { buffer.set_value_in_buffer( buffer_index, t, - number_value, + &number_value, SharedMemoryOrder::Unordered, Some(is_little_endian), context, @@ -710,7 +724,8 @@ impl DataView { /// `25.3.4.15 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )` /// - /// The setBigInt64() method stores a signed 64-bit integer (long long) value at the specified byte offset from the start of the DataView. + /// The `setBigInt64()` method stores a signed 64-bit integer (long long) value at the + /// specified byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -728,7 +743,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigUint64, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -740,7 +755,8 @@ impl DataView { /// `25.3.4.16 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )` /// - /// The setBigUint64() method stores an unsigned 64-bit integer (unsigned long long) value at the specified byte offset from the start of the DataView. + /// The `setBigUint64()` method stores an unsigned 64-bit integer (unsigned long long) value at + /// the specified byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -758,7 +774,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigUint64, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -770,7 +786,8 @@ impl DataView { /// `25.3.4.17 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )` /// - /// The setFloat32() method stores a signed 32-bit float (float) value at the specified byte offset from the start of the DataView. + /// The `setFloat32()` method stores a signed 32-bit float (float) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -788,7 +805,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Float32, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -800,7 +817,8 @@ impl DataView { /// `25.3.4.18 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )` /// - /// The setFloat64() method stores a signed 64-bit float (double) value at the specified byte offset from the start of the DataView. + /// The `setFloat64()` method stores a signed 64-bit float (double) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -818,7 +836,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Float64, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -830,7 +848,8 @@ impl DataView { /// `25.3.4.19 DataView.prototype.setInt8 ( byteOffset, value [ , littleEndian ] )` /// - /// The setInt8() method stores a signed 8-bit integer (byte) value at the specified byte offset from the start of the DataView. + /// The `setInt8()` method stores a signed 8-bit integer (byte) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -848,7 +867,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int8, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -860,7 +879,8 @@ impl DataView { /// `25.3.4.20 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )` /// - /// The setInt16() method stores a signed 16-bit integer (short) value at the specified byte offset from the start of the DataView. + /// The `setInt16()` method stores a signed 16-bit integer (short) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -878,7 +898,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int16, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -890,7 +910,8 @@ impl DataView { /// `25.3.4.21 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )` /// - /// The setInt32() method stores a signed 32-bit integer (long) value at the specified byte offset from the start of the DataView. + /// The `setInt32()` method stores a signed 32-bit integer (long) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -908,7 +929,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int32, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -920,7 +941,8 @@ impl DataView { /// `25.3.4.22 DataView.prototype.setUint8 ( byteOffset, value [ , littleEndian ] )` /// - /// The setUint8() method stores an unsigned 8-bit integer (byte) value at the specified byte offset from the start of the DataView. + /// The `setUint8()` method stores an unsigned 8-bit integer (byte) value at the specified byte + /// offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -938,7 +960,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint8, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -950,7 +972,8 @@ impl DataView { /// `25.3.4.23 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )` /// - /// The setUint16() method stores an unsigned 16-bit integer (unsigned short) value at the specified byte offset from the start of the DataView. + /// The `setUint16()` method stores an unsigned 16-bit integer (unsigned short) value at the + /// specified byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -968,7 +991,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint16, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, @@ -980,7 +1003,8 @@ impl DataView { /// `25.3.4.24 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )` /// - /// The setUint32() method stores an unsigned 32-bit integer (unsigned long) value at the specified byte offset from the start of the DataView. + /// The `setUint32()` method stores an unsigned 32-bit integer (unsigned long) value at the + /// specified byte offset from the start of the `DataView`. /// /// More information: /// - [ECMAScript reference][spec] @@ -998,7 +1022,7 @@ impl DataView { let is_little_endian = args.get_or_undefined(2); // 1. Let v be the this value. // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint32, value). - DataView::set_view_value( + Self::set_view_value( this, byte_offset, is_little_endian, diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index 1ca7bba1e8..674ccafdf9 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -29,9 +29,7 @@ const MILLIS_PER_SECOND: i64 = 1000; #[inline] fn is_zero_or_normal_opt(value: Option) -> bool { - value - .map(|value| value == 0f64 || value.is_normal()) - .unwrap_or(true) + value.map_or(true, |value| value == 0f64 || value.is_normal()) } macro_rules! check_normal_opt { @@ -43,8 +41,7 @@ macro_rules! check_normal_opt { #[inline] fn ignore_ambiguity(result: LocalResult) -> Option { match result { - LocalResult::Ambiguous(v, _) => Some(v), - LocalResult::Single(v) => Some(v), + LocalResult::Ambiguous(v, _) | LocalResult::Single(v) => Some(v), LocalResult::None => None, } } @@ -290,14 +287,14 @@ impl Date { }; self.0 = naive.and_then(|naive| { - let year = year.unwrap_or_else(|| naive.year() as f64) as i32; - let month = month.unwrap_or_else(|| naive.month0() as f64) as i32; - let day = (day.unwrap_or_else(|| naive.day() as f64) as i32).checked_sub(1)?; - let hour = hour.unwrap_or_else(|| naive.hour() as f64) as i64; - let minute = minute.unwrap_or_else(|| naive.minute() as f64) as i64; - let second = second.unwrap_or_else(|| naive.second() as f64) as i64; + let year = year.unwrap_or_else(|| f64::from(naive.year())) as i32; + let month = month.unwrap_or_else(|| f64::from(naive.month0())) as i32; + let day = (day.unwrap_or_else(|| f64::from(naive.day())) as i32).checked_sub(1)?; + let hour = hour.unwrap_or_else(|| f64::from(naive.hour())) as i64; + let minute = minute.unwrap_or_else(|| f64::from(naive.minute())) as i64; + let second = second.unwrap_or_else(|| f64::from(naive.second())) as i64; let millisecond = millisecond - .unwrap_or_else(|| naive.nanosecond() as f64 / NANOS_PER_MS as f64) + .unwrap_or_else(|| f64::from(naive.nanosecond()) / NANOS_PER_MS as f64) as i64; let (year, month, day) = fix_day(year, month, day)?; @@ -384,7 +381,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date pub(crate) fn make_date_now(prototype: JsObject) -> JsObject { - JsObject::from_proto_and_data(prototype, ObjectData::date(Date::default())) + JsObject::from_proto_and_data(prototype, ObjectData::date(Self::default())) } /// `Date(value)` @@ -416,8 +413,8 @@ impl Date { None } else { let secs = (tv / 1_000f64) as i64; - let nsecs = ((tv % 1_000f64) * 1_000_000f64) as u32; - NaiveDateTime::from_timestamp_opt(secs, nsecs) + let nano_secs = ((tv % 1_000f64) * 1_000_000f64) as u32; + NaiveDateTime::from_timestamp_opt(secs, nano_secs) } } }, @@ -426,7 +423,7 @@ impl Date { let tv = tv.filter(|time| Self::time_clip(time.timestamp_millis() as f64).is_some()); Ok(JsObject::from_proto_and_data( prototype, - ObjectData::date(Date(tv)), + ObjectData::date(Self(tv)), )) } @@ -467,12 +464,12 @@ impl Date { if !check_normal_opt!(year, month, day, hour, min, sec, milli) { return Ok(JsObject::from_proto_and_data( prototype, - ObjectData::date(Date(None)), + ObjectData::date(Self(None)), )); } if (0.0..=99.0).contains(&year) { - year += 1900.0 + year += 1900.0; } let mut date = Self( @@ -525,10 +522,10 @@ impl Date { let hint = args.get_or_undefined(0); - let try_first = match hint.as_string().map(|s| s.as_str()) { + let try_first = match hint.as_string().map(JsString::as_str) { // 3. If hint is "string" or "default", then // a. Let tryFirst be string. - Some("string") | Some("default") => PreferredType::String, + Some("string" | "default") => PreferredType::String, // 4. Else if hint is "number", then // a. Let tryFirst be number. Some("number") => PreferredType::Number, @@ -554,7 +551,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getdate /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate pub fn get_date(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.day() as f64) + self.to_local().map_or(f64::NAN, |dt| f64::from(dt.day())) } /// `Date.prototype.getDay()` @@ -572,7 +569,7 @@ impl Date { self.to_local().map_or(f64::NAN, |dt| { let weekday = dt.weekday() as u32; let weekday = (weekday + 1) % 7; // 0 represents Monday in Chrono - weekday as f64 + f64::from(weekday) }) } @@ -587,7 +584,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getfullyear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear pub fn get_full_year(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.year() as f64) + self.to_local().map_or(f64::NAN, |dt| f64::from(dt.year())) } /// `Date.prototype.getHours()` @@ -601,7 +598,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.gethours /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours pub fn get_hours(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.hour() as f64) + self.to_local().map_or(f64::NAN, |dt| f64::from(dt.hour())) } /// `Date.prototype.getMilliseconds()` @@ -615,8 +612,9 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getmilliseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds pub fn get_milliseconds(&self) -> f64 { - self.to_local() - .map_or(f64::NAN, |dt| dt.nanosecond() as f64 / NANOS_PER_MS as f64) + self.to_local().map_or(f64::NAN, |dt| { + f64::from(dt.nanosecond()) / NANOS_PER_MS as f64 + }) } /// `Date.prototype.getMinutes()` @@ -630,7 +628,8 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getminutes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMinutes pub fn get_minutes(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.minute() as f64) + self.to_local() + .map_or(f64::NAN, |dt| f64::from(dt.minute())) } /// `Date.prototype.getMonth()` @@ -645,7 +644,8 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getmonth /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth pub fn get_month(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.month0() as f64) + self.to_local() + .map_or(f64::NAN, |dt| f64::from(dt.month0())) } /// `Date.prototype.getSeconds()` @@ -659,13 +659,15 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getSeconds pub fn get_seconds(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| dt.second() as f64) + self.to_local() + .map_or(f64::NAN, |dt| f64::from(dt.second())) } /// `Date.prototype.getYear()` /// - /// The getYear() method returns the year in the specified date according to local time. Because getYear() does not - /// return full years ("year 2000 problem"), it is no longer used and has been replaced by the getFullYear() method. + /// The `getYear()` method returns the year in the specified date according to local time. + /// Because `getYear()` does not return full years ("year 2000 problem"), it is no longer used + /// and has been replaced by the `getFullYear()` method. /// /// More information: /// - [ECMAScript reference][spec] @@ -675,7 +677,7 @@ impl Date { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear pub fn get_year(&self) -> f64 { self.to_local() - .map_or(f64::NAN, |dt| dt.year() as f64 - 1900f64) + .map_or(f64::NAN, |dt| f64::from(dt.year()) - 1900f64) } /// `Date.prototype.getTime()` @@ -695,7 +697,7 @@ impl Date { /// `Date.prototype.getTimeZoneOffset()` /// - /// The getTimezoneOffset() method returns the time zone difference, in minutes, from current locale (host system + /// The `getTimezoneOffset()` method returns the time zone difference, in minutes, from current locale (host system /// settings) to UTC. /// /// More information: @@ -720,7 +722,7 @@ impl Date { // 3. Return (t - LocalTime(t)) / msPerMinute. Ok(JsValue::new( - -Local::now().offset().local_minus_utc() as f64 / 60f64, + f64::from(-Local::now().offset().local_minus_utc()) / 60f64, )) } @@ -735,7 +737,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcdate /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDate pub fn get_utc_date(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.day() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.day())) } /// `Date.prototype.getUTCDay()` @@ -753,7 +755,7 @@ impl Date { self.to_utc().map_or(f64::NAN, |dt| { let weekday = dt.weekday() as u32; let weekday = (weekday + 1) % 7; // 0 represents Monday in Chrono - weekday as f64 + f64::from(weekday) }) } @@ -768,7 +770,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcfullyear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear pub fn get_utc_full_year(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.year() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.year())) } /// `Date.prototype.getUTCHours()` @@ -782,7 +784,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutchours /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCHours pub fn get_utc_hours(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.hour() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.hour())) } /// `Date.prototype.getUTCMilliseconds()` @@ -796,8 +798,9 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcmilliseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds pub fn get_utc_milliseconds(&self) -> f64 { - self.to_utc() - .map_or(f64::NAN, |dt| dt.nanosecond() as f64 / NANOS_PER_MS as f64) + self.to_utc().map_or(f64::NAN, |dt| { + f64::from(dt.nanosecond()) / NANOS_PER_MS as f64 + }) } /// `Date.prototype.getUTCMinutes()` @@ -811,7 +814,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcminutes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes pub fn get_utc_minutes(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.minute() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.minute())) } /// `Date.prototype.getUTCMonth()` @@ -826,7 +829,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcmonth /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth pub fn get_utc_month(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.month0() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.month0())) } /// `Date.prototype.getUTCSeconds()` @@ -840,7 +843,7 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds pub fn get_utc_seconds(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| dt.second() as f64) + self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.second())) } /// `Date.prototype.setDate()` @@ -1204,7 +1207,7 @@ impl Date { // 4. If y is NaN, then if y.is_nan() { // a. Set the [[DateValue]] internal slot of this Date object to NaN. - this.set_data(ObjectData::date(Date(None))); + this.set_data(ObjectData::date(Self(None))); // b. Return NaN. return Ok(JsValue::nan()); @@ -1248,12 +1251,12 @@ impl Date { let t = t.to_number(context)?; let seconds = (t / 1_000f64) as i64; let nanoseconds = ((t % 1_000f64) * 1_000_000f64) as u32; - Date( + Self( ignore_ambiguity(Local.timestamp_opt(seconds, nanoseconds)) .map(|dt| dt.naive_utc()), ) } else { - Date(None) + Self(None) }; // 3. Let v be TimeClip(t). @@ -1793,9 +1796,10 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.toutcstring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString pub fn to_utc_string(self) -> String { - self.to_utc() - .map(|date_time| date_time.format("%a, %d %b %Y %H:%M:%S GMT").to_string()) - .unwrap_or_else(|| "Invalid Date".to_string()) + self.to_utc().map_or_else( + || "Invalid Date".to_string(), + |date_time| date_time.format("%a, %d %b %Y %H:%M:%S GMT").to_string(), + ) } /// `Date.prototype.valueOf()` @@ -1822,6 +1826,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.now /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now + #[allow(clippy::unnecessary_wraps)] pub(crate) fn now(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { Ok(JsValue::new(Utc::now().timestamp_millis() as f64)) } @@ -1829,7 +1834,7 @@ impl Date { /// `Date.parse()` /// /// The `Date.parse()` method parses a string representation of a date, and returns the number of milliseconds since - /// January 1, 1970, 00:00:00 UTC or NaN if the string is unrecognized or, in some cases, contains illegal date + /// January 1, 1970, 00:00:00 UTC or `NaN` if the string is unrecognized or, in some cases, contains illegal date /// values. /// /// More information: diff --git a/boa/src/builtins/date/tests.rs b/boa/src/builtins/date/tests.rs index b9cde13960..a31185a296 100644 --- a/boa/src/builtins/date/tests.rs +++ b/boa/src/builtins/date/tests.rs @@ -70,7 +70,7 @@ fn date_this_time_value() { } #[test] -fn date_call() -> Result<(), Box> { +fn date_call() { let mut context = Context::default(); let dt1 = forward(&mut context, "Date()"); @@ -80,11 +80,10 @@ fn date_call() -> Result<(), Box> { let dt2 = forward(&mut context, "Date()"); assert_ne!(dt1, dt2); - Ok(()) } #[test] -fn date_ctor_call() -> Result<(), Box> { +fn date_ctor_call() { let mut context = Context::default(); let dt1 = forward_dt_local(&mut context, "new Date()"); @@ -94,11 +93,10 @@ fn date_ctor_call() -> Result<(), Box> { let dt2 = forward_dt_local(&mut context, "new Date()"); assert_ne!(dt1, dt2); - Ok(()) } #[test] -fn date_ctor_call_string() -> Result<(), Box> { +fn date_ctor_call_string() { let mut context = Context::default(); let date_time = forward_dt_utc(&mut context, "new Date('2020-06-08T09:16:15.779-06:30')"); @@ -108,20 +106,18 @@ fn date_ctor_call_string() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 06, 08).and_hms_milli(15, 46, 15, 779)), date_time ); - Ok(()) } #[test] -fn date_ctor_call_string_invalid() -> Result<(), Box> { +fn date_ctor_call_string_invalid() { let mut context = Context::default(); let date_time = forward_dt_local(&mut context, "new Date('nope')"); assert_eq!(None, date_time); - Ok(()) } #[test] -fn date_ctor_call_number() -> Result<(), Box> { +fn date_ctor_call_number() { let mut context = Context::default(); let date_time = forward_dt_utc(&mut context, "new Date(1594199775779)"); @@ -129,11 +125,10 @@ fn date_ctor_call_number() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), date_time ); - Ok(()) } #[test] -fn date_ctor_call_date() -> Result<(), Box> { +fn date_ctor_call_date() { let mut context = Context::default(); let date_time = forward_dt_utc(&mut context, "new Date(new Date(1594199775779))"); @@ -142,11 +137,10 @@ fn date_ctor_call_date() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), date_time ); - Ok(()) } #[test] -fn date_ctor_call_multiple() -> Result<(), Box> { +fn date_ctor_call_multiple() { let mut context = Context::default(); let date_time = forward_dt_local(&mut context, "new Date(2020, 06, 08, 09, 16, 15, 779)"); @@ -155,11 +149,10 @@ fn date_ctor_call_multiple() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), date_time ); - Ok(()) } #[test] -fn date_ctor_call_multiple_90s() -> Result<(), Box> { +fn date_ctor_call_multiple_90s() { let mut context = Context::default(); let date_time = forward_dt_local(&mut context, "new Date(99, 06, 08, 09, 16, 15, 779)"); @@ -168,11 +161,10 @@ fn date_ctor_call_multiple_90s() -> Result<(), Box> { Some(NaiveDate::from_ymd(1999, 07, 08).and_hms_milli(09, 16, 15, 779)), date_time ); - Ok(()) } #[test] -fn date_ctor_call_multiple_nan() -> Result<(), Box> { +fn date_ctor_call_multiple_nan() { fn check(src: &str) { let mut context = Context::default(); let date_time = forward_dt_local(&mut context, src); @@ -186,48 +178,43 @@ fn date_ctor_call_multiple_nan() -> Result<(), Box> { check("new Date(2020, 06, 08, 09, 1/0, 15, 779)"); check("new Date(2020, 06, 08, 09, 16, 1/0, 779)"); check("new Date(2020, 06, 08, 09, 16, 15, 1/0)"); - - Ok(()) } #[test] -fn date_ctor_now_call() -> Result<(), Box> { +fn date_ctor_now_call() { let mut context = Context::default(); let date_time = forward(&mut context, "Date.now()"); - let dt1 = date_time.parse::()?; + let dt1 = date_time.parse::().unwrap(); std::thread::sleep(std::time::Duration::from_millis(1)); let date_time = forward(&mut context, "Date.now()"); - let dt2 = date_time.parse::()?; + let dt2 = date_time.parse::().unwrap(); assert_ne!(dt1, dt2); - Ok(()) } #[test] -fn date_ctor_parse_call() -> Result<(), Box> { +fn date_ctor_parse_call() { let mut context = Context::default(); let date_time = forward_val(&mut context, "Date.parse('2020-06-08T09:16:15.779-07:30')"); assert_eq!(Ok(JsValue::new(1591634775779f64)), date_time); - Ok(()) } #[test] -fn date_ctor_utc_call() -> Result<(), Box> { +fn date_ctor_utc_call() { let mut context = Context::default(); let date_time = forward_val(&mut context, "Date.UTC(2020, 06, 08, 09, 16, 15, 779)"); assert_eq!(Ok(JsValue::new(1594199775779f64)), date_time); - Ok(()) } #[test] -fn date_ctor_utc_call_nan() -> Result<(), Box> { +fn date_ctor_utc_call_nan() { fn check(src: &str) { let mut context = Context::default(); let date_time = forward_val(&mut context, src).expect("Expected Success"); @@ -241,12 +228,10 @@ fn date_ctor_utc_call_nan() -> Result<(), Box> { check("Date.UTC(2020, 06, 08, 09, 1/0, 15, 779)"); check("Date.UTC(2020, 06, 08, 09, 16, 1/0, 779)"); check("Date.UTC(2020, 06, 08, 09, 16, 15, 1/0)"); - - Ok(()) } #[test] -fn date_proto_get_date_call() -> Result<(), Box> { +fn date_proto_get_date_call() { let mut context = Context::default(); let actual = forward_val( @@ -257,12 +242,10 @@ fn date_proto_get_date_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getDate()"); assert_eq!(Ok(JsValue::nan()), actual); - - Ok(()) } #[test] -fn date_proto_get_day_call() -> Result<(), Box> { +fn date_proto_get_day_call() { let mut context = Context::default(); let actual = forward_val( @@ -273,11 +256,10 @@ fn date_proto_get_day_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getDay()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_full_year_call() -> Result<(), Box> { +fn date_proto_get_full_year_call() { let mut context = Context::default(); let actual = forward_val( @@ -288,11 +270,10 @@ fn date_proto_get_full_year_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getFullYear()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_hours_call() -> Result<(), Box> { +fn date_proto_get_hours_call() { let mut context = Context::default(); let actual = forward_val( @@ -303,11 +284,10 @@ fn date_proto_get_hours_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getHours()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_milliseconds_call() -> Result<(), Box> { +fn date_proto_get_milliseconds_call() { let mut context = Context::default(); let actual = forward_val( @@ -318,11 +298,10 @@ fn date_proto_get_milliseconds_call() -> Result<(), Box> let actual = forward_val(&mut context, "new Date(1/0).getMilliseconds()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_minutes_call() -> Result<(), Box> { +fn date_proto_get_minutes_call() { let mut context = Context::default(); let actual = forward_val( @@ -333,11 +312,10 @@ fn date_proto_get_minutes_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getMinutes()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_month() -> Result<(), Box> { +fn date_proto_get_month() { let mut context = Context::default(); let actual = forward_val( @@ -348,12 +326,10 @@ fn date_proto_get_month() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getMonth()"); assert_eq!(Ok(JsValue::nan()), actual); - - Ok(()) } #[test] -fn date_proto_get_seconds() -> Result<(), Box> { +fn date_proto_get_seconds() { let mut context = Context::default(); let actual = forward_val( @@ -364,11 +340,10 @@ fn date_proto_get_seconds() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getSeconds()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_time() -> Result<(), Box> { +fn date_proto_get_time() { let mut context = Context::default(); let actual = forward_val( @@ -384,11 +359,10 @@ fn date_proto_get_time() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getTime()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_year() -> Result<(), Box> { +fn date_proto_get_year() { let mut context = Context::default(); let actual = forward_val( @@ -399,11 +373,10 @@ fn date_proto_get_year() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getYear()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_timezone_offset() -> Result<(), Box> { +fn date_proto_get_timezone_offset() { let mut context = Context::default(); let actual = forward_val( @@ -420,7 +393,7 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { ); // The value of now().offset() depends on the host machine, so we have to replicate the method code here. - let offset_seconds = chrono::Local::now().offset().local_minus_utc() as f64; + let offset_seconds = f64::from(chrono::Local::now().offset().local_minus_utc()); let offset_minutes = -offset_seconds / 60f64; assert_eq!(Ok(JsValue::new(offset_minutes)), actual); @@ -429,11 +402,10 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { "new Date('1975-08-19T23:15:30+07:00').getTimezoneOffset()", ); assert_eq!(Ok(JsValue::new(offset_minutes)), actual); - Ok(()) } #[test] -fn date_proto_get_utc_date_call() -> Result<(), Box> { +fn date_proto_get_utc_date_call() { let mut context = Context::default(); let actual = forward_val( @@ -444,12 +416,10 @@ fn date_proto_get_utc_date_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCDate()"); assert_eq!(Ok(JsValue::nan()), actual); - - Ok(()) } #[test] -fn date_proto_get_utc_day_call() -> Result<(), Box> { +fn date_proto_get_utc_day_call() { let mut context = Context::default(); let actual = forward_val( @@ -460,11 +430,10 @@ fn date_proto_get_utc_day_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCDay()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_utc_full_year_call() -> Result<(), Box> { +fn date_proto_get_utc_full_year_call() { let mut context = Context::default(); let actual = forward_val( @@ -475,11 +444,10 @@ fn date_proto_get_utc_full_year_call() -> Result<(), Box> let actual = forward_val(&mut context, "new Date(1/0).getUTCFullYear()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_utc_hours_call() -> Result<(), Box> { +fn date_proto_get_utc_hours_call() { let mut context = Context::default(); let actual = forward_val( @@ -490,11 +458,10 @@ fn date_proto_get_utc_hours_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCHours()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_utc_milliseconds_call() -> Result<(), Box> { +fn date_proto_get_utc_milliseconds_call() { let mut context = Context::default(); let actual = forward_val( @@ -505,11 +472,10 @@ fn date_proto_get_utc_milliseconds_call() -> Result<(), Box Result<(), Box> { +fn date_proto_get_utc_minutes_call() { let mut context = Context::default(); let actual = forward_val( @@ -520,11 +486,10 @@ fn date_proto_get_utc_minutes_call() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCMinutes()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_get_utc_month() -> Result<(), Box> { +fn date_proto_get_utc_month() { let mut context = Context::default(); let actual = forward_val( @@ -535,12 +500,10 @@ fn date_proto_get_utc_month() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCMonth()"); assert_eq!(Ok(JsValue::nan()), actual); - - Ok(()) } #[test] -fn date_proto_get_utc_seconds() -> Result<(), Box> { +fn date_proto_get_utc_seconds() { let mut context = Context::default(); let actual = forward_val( @@ -551,11 +514,10 @@ fn date_proto_get_utc_seconds() -> Result<(), Box> { let actual = forward_val(&mut context, "new Date(1/0).getUTCSeconds()"); assert_eq!(Ok(JsValue::nan()), actual); - Ok(()) } #[test] -fn date_proto_set_date() -> Result<(), Box> { +fn date_proto_set_date() { let mut context = Context::default(); let actual = forward_dt_local( @@ -582,12 +544,10 @@ fn date_proto_set_date() -> Result<(), Box> { "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setDate(1/0); dt", ); assert_eq!(None, actual); - - Ok(()) } #[test] -fn date_proto_set_full_year() -> Result<(), Box> { +fn date_proto_set_full_year() { let mut context = Context::default(); let actual = forward_dt_local( @@ -654,12 +614,10 @@ fn date_proto_set_full_year() -> Result<(), Box> { Some(NaiveDate::from_ymd(2010, 02, 23).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_hours() -> Result<(), Box> { +fn date_proto_set_hours() { let mut context = Context::default(); let actual = forward_dt_local( @@ -708,12 +666,10 @@ fn date_proto_set_hours() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 09, 11).and_hms_milli(21, 40, 40, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_milliseconds() -> Result<(), Box> { +fn date_proto_set_milliseconds() { let mut context = Context::default(); let actual = forward_dt_local( @@ -736,12 +692,10 @@ fn date_proto_set_milliseconds() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 55, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_minutes() -> Result<(), Box> { +fn date_proto_set_minutes() { let mut context = Context::default(); let actual = forward_dt_local( @@ -782,12 +736,10 @@ fn date_proto_set_minutes() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 08, 29).and_hms_milli(09, 20, 40, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_month() -> Result<(), Box> { +fn date_proto_set_month() { let mut context = Context::default(); let actual = forward_dt_local( @@ -819,12 +771,10 @@ fn date_proto_set_month() -> Result<(), Box> { Some(NaiveDate::from_ymd(2023, 07, 22).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_seconds() -> Result<(), Box> { +fn date_proto_set_seconds() { let mut context = Context::default(); let actual = forward_dt_local( @@ -856,12 +806,10 @@ fn date_proto_set_seconds() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 11, 14).and_hms_milli(08, 23, 20, 123)), actual ); - - Ok(()) } #[test] -fn set_year() -> Result<(), Box> { +fn set_year() { let mut context = Context::default(); let actual = forward_dt_local( @@ -881,12 +829,10 @@ fn set_year() -> Result<(), Box> { Some(NaiveDate::from_ymd(2001, 07, 08).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_time() -> Result<(), Box> { +fn date_proto_set_time() { let mut context = Context::default(); let actual = forward_dt_local( @@ -897,12 +843,10 @@ fn date_proto_set_time() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_date() -> Result<(), Box> { +fn date_proto_set_utc_date() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -929,12 +873,10 @@ fn date_proto_set_utc_date() -> Result<(), Box> { "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCDate(1/0); dt", ); assert_eq!(None, actual); - - Ok(()) } #[test] -fn date_proto_set_utc_full_year() -> Result<(), Box> { +fn date_proto_set_utc_full_year() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1001,12 +943,10 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { Some(NaiveDate::from_ymd(2010, 02, 23).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_hours() -> Result<(), Box> { +fn date_proto_set_utc_hours() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1055,12 +995,10 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 09, 11).and_hms_milli(21, 40, 40, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_milliseconds() -> Result<(), Box> { +fn date_proto_set_utc_milliseconds() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1083,12 +1021,10 @@ fn date_proto_set_utc_milliseconds() -> Result<(), Box> { Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 55, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_minutes() -> Result<(), Box> { +fn date_proto_set_utc_minutes() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1129,12 +1065,10 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 08, 29).and_hms_milli(09, 20, 40, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_month() -> Result<(), Box> { +fn date_proto_set_utc_month() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1166,12 +1100,10 @@ fn date_proto_set_utc_month() -> Result<(), Box> { Some(NaiveDate::from_ymd(2023, 07, 22).and_hms_milli(09, 16, 15, 779)), actual ); - - Ok(()) } #[test] -fn date_proto_set_utc_seconds() -> Result<(), Box> { +fn date_proto_set_utc_seconds() { let mut context = Context::default(); let actual = forward_dt_utc( @@ -1203,12 +1135,10 @@ fn date_proto_set_utc_seconds() -> Result<(), Box> { Some(NaiveDate::from_ymd(2021, 11, 14).and_hms_milli(08, 23, 20, 123)), actual ); - - Ok(()) } #[test] -fn date_proto_to_date_string() -> Result<(), Box> { +fn date_proto_to_date_string() { let mut context = Context::default(); let actual = forward_val( @@ -1217,12 +1147,10 @@ fn date_proto_to_date_string() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new("Wed Jul 08 2020"), actual); - - Ok(()) } #[test] -fn date_proto_to_gmt_string() -> Result<(), Box> { +fn date_proto_to_gmt_string() { let mut context = Context::default(); let actual = forward_val( @@ -1231,12 +1159,10 @@ fn date_proto_to_gmt_string() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new("Wed, 08 Jul 2020 09:16:15 GMT"), actual); - - Ok(()) } #[test] -fn date_proto_to_iso_string() -> Result<(), Box> { +fn date_proto_to_iso_string() { let mut context = Context::default(); let actual = forward_val( @@ -1245,12 +1171,10 @@ fn date_proto_to_iso_string() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new("2020-07-08T09:16:15.779Z"), actual); - - Ok(()) } #[test] -fn date_proto_to_json() -> Result<(), Box> { +fn date_proto_to_json() { let mut context = Context::default(); let actual = forward_val( @@ -1259,12 +1183,10 @@ fn date_proto_to_json() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new("2020-07-08T09:16:15.779Z"), actual); - - Ok(()) } #[test] -fn date_proto_to_string() -> Result<(), Box> { +fn date_proto_to_string() { let mut context = Context::default(); let actual = forward_val( @@ -1287,12 +1209,10 @@ fn date_proto_to_string() -> Result<(), Box> { )), actual ); - - Ok(()) } #[test] -fn date_proto_to_time_string() -> Result<(), Box> { +fn date_proto_to_time_string() { let mut context = Context::default(); let actual = forward_val( @@ -1315,12 +1235,10 @@ fn date_proto_to_time_string() -> Result<(), Box> { )), actual ); - - Ok(()) } #[test] -fn date_proto_to_utc_string() -> Result<(), Box> { +fn date_proto_to_utc_string() { let mut context = Context::default(); let actual = forward_val( @@ -1329,12 +1247,10 @@ fn date_proto_to_utc_string() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new("Wed, 08 Jul 2020 09:16:15 GMT"), actual); - - Ok(()) } #[test] -fn date_proto_value_of() -> Result<(), Box> { +fn date_proto_value_of() { let mut context = Context::default(); let actual = forward_val( @@ -1343,12 +1259,10 @@ fn date_proto_value_of() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new(1594199775779f64), actual); - - Ok(()) } #[test] -fn date_neg() -> Result<(), Box> { +fn date_neg() { let mut context = Context::default(); let actual = forward_val( @@ -1357,12 +1271,10 @@ fn date_neg() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!(JsValue::new(-1594199775779f64), actual); - - Ok(()) } #[test] -fn date_json() -> Result<(), Box> { +fn date_json() { let mut context = Context::default(); let actual = forward_val( @@ -1374,6 +1286,4 @@ fn date_json() -> Result<(), Box> { JsValue::new(r#"{"date":"2020-07-08T09:16:15.779Z"}"#), actual ); - - Ok(()) } diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index a5e18262e6..850cad5869 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -1,6 +1,6 @@ //! This module implements the global `SyntaxError` object. //! -//! The SyntaxError object represents an error when trying to interpret syntactically invalid code. +//! The `SyntaxError` object represents an error when trying to interpret syntactically invalid code. //! It is thrown when the JavaScript context encounters tokens or token order that does not conform //! to the syntax of the language when parsing code. //! diff --git a/boa/src/builtins/function/arguments.rs b/boa/src/builtins/function/arguments.rs index c74b63303a..050ace2ee4 100644 --- a/boa/src/builtins/function/arguments.rs +++ b/boa/src/builtins/function/arguments.rs @@ -44,7 +44,7 @@ impl Arguments { // 3. Set obj.[[ParameterMap]] to undefined. // skipped because the `Arguments` enum ensures ordinary argument objects don't have a `[[ParameterMap]]` - obj.borrow_mut().data = ObjectData::arguments(Arguments::Unmapped); + obj.borrow_mut().data = ObjectData::arguments(Self::Unmapped); // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }). @@ -133,7 +133,7 @@ impl Arguments { // 11. Set obj.[[ParameterMap]] to map. let obj = JsObject::from_proto_and_data( context.standard_objects().object_object().prototype(), - ObjectData::arguments(Arguments::Mapped(MappedArguments(map.clone()))), + ObjectData::arguments(Self::Mapped(MappedArguments(map.clone()))), ); // 14. Let index be 0. @@ -169,7 +169,9 @@ impl Arguments { // 19. Repeat, while index ≥ 0, // a. Let name be parameterNames[index]. - for (index, parameter_name_vec) in formals.iter().map(|fp| fp.names()).enumerate().rev() { + for (index, parameter_name_vec) in + formals.iter().map(FormalParameter::names).enumerate().rev() + { for parameter_name in parameter_name_vec.iter().copied() { // b. If name is not an element of mappedNames, then if !mapped_names.contains(¶meter_name) { @@ -190,7 +192,7 @@ impl Arguments { |_, _, captures, context| { captures.0.get_binding_value(captures.1, false, context) }, - (env.clone(), parameter_name.to_owned()), + (env.clone(), parameter_name), ) .length(0) .name("") @@ -215,7 +217,7 @@ impl Arguments { .map(|_| JsValue::Undefined) // Ok(JsValue::Undefined) }, - (env.clone(), parameter_name.to_owned()), + (env.clone(), parameter_name), ) .length(1) .name("") diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 255dbf14ff..5e50a68d48 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -2,7 +2,7 @@ //! //! Objects wrap `Function`s and expose them via call/construct slots. //! -//! `The `Function` object is used for matching text with a pattern. +//! The `Function` object is used for matching text with a pattern. //! //! More information: //! - [ECMAScript reference][spec] @@ -158,7 +158,8 @@ impl Captures { /// Boa representation of a Function Object. /// -/// FunctionBody is specific to this interpreter, it will either be Rust code or JavaScript code (AST Node) +/// `FunctionBody` is specific to this interpreter, it will either be Rust code or JavaScript code +/// (AST Node). /// /// #[derive(Trace, Finalize)] @@ -190,8 +191,7 @@ impl Function { /// Returns true if the function object is a constructor. pub fn is_constructor(&self) -> bool { match self { - Self::Native { constructor, .. } => *constructor, - Self::Closure { constructor, .. } => *constructor, + Self::Native { constructor, .. } | Self::Closure { constructor, .. } => *constructor, Self::VmOrdinary { code, .. } => code.constructor, } } @@ -477,6 +477,7 @@ impl BuiltInFunctionObject { Ok(JsValue::ordinary_has_instance(this, args.get_or_undefined(0), context)?.into()) } + #[allow(clippy::unnecessary_wraps)] fn prototype(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { Ok(JsValue::undefined()) } @@ -623,7 +624,7 @@ impl BoundFunction { Ok(JsObject::from_proto_and_data( proto, ObjectData::bound_function( - BoundFunction { + Self { target_function, this, args, diff --git a/boa/src/builtins/function/tests.rs b/boa/src/builtins/function/tests.rs index 505d6bb278..f183343973 100644 --- a/boa/src/builtins/function/tests.rs +++ b/boa/src/builtins/function/tests.rs @@ -142,7 +142,7 @@ fn function_prototype_call_throw() { let value = forward_val(&mut context, throw).unwrap_err(); assert!(value.is_object()); let string = value.to_string(&mut context).unwrap(); - assert!(string.starts_with("TypeError")) + assert!(string.starts_with("TypeError")); } #[test] diff --git a/boa/src/builtins/intl/mod.rs b/boa/src/builtins/intl/mod.rs index 158bdd38fe..e4f3e0362d 100644 --- a/boa/src/builtins/intl/mod.rs +++ b/boa/src/builtins/intl/mod.rs @@ -132,7 +132,7 @@ impl Intl { let ll = Self::canonicalize_locale_list(args, context)?; // 2. Return CreateArrayFromList(ll). Ok(JsValue::Object(Array::create_array_from_list( - ll.into_iter().map(|x| x.into()), + ll.into_iter().map(Into::into), context, ))) } diff --git a/boa/src/builtins/intrinsics.rs b/boa/src/builtins/intrinsics.rs index d940b5f2ff..5823f59e8a 100644 --- a/boa/src/builtins/intrinsics.rs +++ b/boa/src/builtins/intrinsics.rs @@ -11,7 +11,7 @@ pub struct IntrinsicObjects { } impl IntrinsicObjects { - pub fn init(context: &mut Context) -> IntrinsicObjects { + pub fn init(context: &mut Context) -> Self { Self { throw_type_error: create_throw_type_error(context), } diff --git a/boa/src/builtins/iterable/mod.rs b/boa/src/builtins/iterable/mod.rs index 47b534f90b..9add566c6a 100644 --- a/boa/src/builtins/iterable/mod.rs +++ b/boa/src/builtins/iterable/mod.rs @@ -75,7 +75,7 @@ impl IteratorPrototypes { /// `CreateIterResultObject( value, done )` /// -/// Generates an object supporting the IteratorResult interface. +/// Generates an object supporting the `IteratorResult` interface. pub fn create_iter_result_object(value: JsValue, done: bool, context: &mut Context) -> JsValue { // 1. Assert: Type(done) is Boolean. // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%). @@ -109,7 +109,7 @@ impl JsValue { &self, context: &mut Context, hint: Option, - method: Option, + method: Option, ) -> JsResult { // 1. If hint is not present, set hint to sync. let hint = hint.unwrap_or(IteratorHint::Sync); @@ -130,7 +130,7 @@ impl JsValue { // 1. Let syncMethod be ? GetMethod(obj, @@iterator). let sync_method = self .get_method(WellKnownSymbols::iterator(), context)? - .map_or(JsValue::Undefined, JsValue::from); + .map_or(Self::Undefined, Self::from); // 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod). let _sync_iterator_record = self.get_iterator(context, Some(IteratorHint::Sync), Some(sync_method)); @@ -140,7 +140,7 @@ impl JsValue { } else { // b. Otherwise, set method to ? GetMethod(obj, @@iterator). self.get_method(WellKnownSymbols::iterator(), context)? - .map_or(JsValue::Undefined, JsValue::from) + .map_or(Self::Undefined, Self::from) } }; @@ -161,7 +161,7 @@ impl JsValue { } } -/// Create the %IteratorPrototype% object +/// Create the `%IteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] @@ -277,7 +277,7 @@ impl IteratorRecord { /// [spec]: https://tc39.es/ecma262/#sec-iterabletolist pub(crate) fn iterable_to_list( context: &mut Context, - items: JsValue, + items: &JsValue, method: Option, ) -> JsResult> { // 1. If method is present, then @@ -305,7 +305,7 @@ pub(crate) fn iterable_to_list( break; } - values.push(next.value) + values.push(next.value); } // 6. Return values. diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index 60778c7cf0..a4b30b66d1 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -232,7 +232,7 @@ impl Json { // a. If IsCallable(replacer) is true, then if replacer_obj.is_callable() { // i. Set ReplacerFunction to replacer. - replacer_function = Some(replacer_obj.clone()) + replacer_function = Some(replacer_obj.clone()); // b. Else, } else { // i. Let isArray be ? IsArray(replacer). @@ -260,7 +260,7 @@ impl Json { // g. If item is not undefined and item is not currently an element of PropertyList, then // i. Append item to the end of PropertyList. if let Some(s) = v.as_string() { - property_set.insert(s.to_owned()); + property_set.insert(s.clone()); } else if v.is_number() { property_set.insert( v.to_string(context) @@ -348,7 +348,7 @@ impl Json { // 12. Return ? SerializeJSONProperty(state, the empty String, wrapper). Ok( Self::serialize_json_property(&mut state, JsString::new(""), &wrapper, context)? - .map(|s| s.into()) + .map(Into::into) .unwrap_or_default(), ) } @@ -385,7 +385,7 @@ impl Json { // 3. If state.[[ReplacerFunction]] is not undefined, then if let Some(obj) = &state.replacer_function { // a. Set value to ? Call(state.[[ReplacerFunction]], holder, « key, value »). - value = obj.call(&holder.clone().into(), &[key.into(), value], context)? + value = obj.call(&holder.clone().into(), &[key.into(), value], context)?; } // 4. If Type(value) is Object, then @@ -403,12 +403,12 @@ impl Json { // c. Else if value has a [[BooleanData]] internal slot, then else if let Some(boolean) = obj.borrow().as_boolean() { // i. Set value to value.[[BooleanData]]. - value = boolean.into() + value = boolean.into(); } // d. Else if value has a [[BigIntData]] internal slot, then else if let Some(bigint) = obj.borrow().as_bigint() { // i. Set value to value.[[BigIntData]]. - value = bigint.clone().into() + value = bigint.clone().into(); } } @@ -420,10 +420,11 @@ impl Json { // 6. If value is true, return "true". // 7. If value is false, return "false". if value.is_boolean() { - return match value.to_boolean() { - true => Ok(Some(JsString::new("true"))), - false => Ok(Some(JsString::new("false"))), - }; + return Ok(Some(JsString::new(if value.to_boolean() { + "true" + } else { + "false" + }))); } // 8. If Type(value) is String, return QuoteJSONString(value). @@ -503,7 +504,7 @@ impl Json { code_point => { // i. Set product to the string-concatenation of product and ! UTF16EncodeCodePoint(C). product.push( - char::from_u32(code_point as u32) + char::from_u32(u32::from(code_point)) .expect("char from code point cannot fail here"), ); } @@ -674,11 +675,11 @@ impl Json { // b. If strP is undefined, then if let Some(str_p) = str_p { // i. Append strP to partial. - partial.push(str_p) + partial.push(str_p); // c. Else, } else { // i. Append "null" to partial. - partial.push("null".into()) + partial.push("null".into()); } // d. Set index to index + 1. diff --git a/boa/src/builtins/map/map_iterator.rs b/boa/src/builtins/map/map_iterator.rs index b7cbb1ab63..92a2e75631 100644 --- a/boa/src/builtins/map/map_iterator.rs +++ b/boa/src/builtins/map/map_iterator.rs @@ -25,7 +25,7 @@ pub struct MapIterator { impl MapIterator { pub(crate) const NAME: &'static str = "MapIterator"; - /// Abstract operation CreateMapIterator( map, kind ) + /// Abstract operation `CreateMapIterator( map, kind )` /// /// Creates a new iterator over the given map. /// @@ -41,7 +41,7 @@ impl MapIterator { if let Some(map_obj) = map.as_object() { if let Some(map) = map_obj.borrow_mut().as_map_mut() { let lock = map.lock(map_obj.clone()); - let iter = MapIterator { + let iter = Self { iterated_map: Some(map_obj.clone()), map_next_index: 0, map_iteration_kind: kind, @@ -66,7 +66,7 @@ impl MapIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-%mapiteratorprototype%.next pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut map_iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut map_iterator = this.as_object().map(JsObject::borrow_mut); let map_iterator = map_iterator .as_mut() .and_then(|obj| obj.as_map_iterator_mut()) @@ -110,7 +110,7 @@ impl MapIterator { )) } - /// Create the %MapIteratorPrototype% object + /// Create the `%MapIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 4ae94eb8a1..73be927231 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -161,6 +161,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-get-map-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) @@ -330,10 +331,9 @@ impl Map { args: &[JsValue], context: &mut Context, ) -> JsResult { - let key = args.get_or_undefined(0); - const JS_ZERO: &JsValue = &JsValue::Rational(0f64); + let key = args.get_or_undefined(0); let key = match key { JsValue::Rational(r) => { if r.is_zero() { @@ -403,10 +403,9 @@ impl Map { args: &[JsValue], context: &mut Context, ) -> JsResult { - let key = args.get_or_undefined(0); - const JS_ZERO: &JsValue = &JsValue::Rational(0f64); + let key = args.get_or_undefined(0); let key = match key { JsValue::Rational(r) => { if r.is_zero() { diff --git a/boa/src/builtins/map/ordered_map.rs b/boa/src/builtins/map/ordered_map.rs index 5cd186954b..4ea5cd426a 100644 --- a/boa/src/builtins/map/ordered_map.rs +++ b/boa/src/builtins/map/ordered_map.rs @@ -31,12 +31,12 @@ impl Equivalent for JsValue { fn equivalent(&self, key: &MapKey) -> bool { match key { MapKey::Key(v) => v == self, - _ => false, + MapKey::Empty(_) => false, } } } -/// A newtype wrapping indexmap::IndexMap +/// A structure wrapping `indexmap::IndexMap`. #[derive(Clone)] pub struct OrderedMap { map: IndexMap, S>, @@ -70,7 +70,7 @@ impl Default for OrderedMap { impl OrderedMap { pub fn new() -> Self { - OrderedMap { + Self { map: IndexMap::new(), lock: 0, empty_count: 0, @@ -78,7 +78,7 @@ impl OrderedMap { } pub fn with_capacity(capacity: usize) -> Self { - OrderedMap { + Self { map: IndexMap::with_capacity(capacity), lock: 0, empty_count: 0, @@ -147,7 +147,7 @@ impl OrderedMap { pub fn clear(&mut self) { self.map.clear(); self.map.shrink_to_fit(); - self.empty_count = 0 + self.empty_count = 0; } /// Return a reference to the value stored for `key`, if it is present, @@ -160,7 +160,7 @@ impl OrderedMap { /// Get a key-value pair by index. /// - /// Valid indices are 0 <= index < self.full_len(). + /// Valid indices are `0 <= index < self.full_len()`. /// /// Computes in O(1) time. pub fn get_index(&self, index: usize) -> Option<(&JsValue, &V)> { diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 955ef6388c..c46ac3f7da 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -83,7 +83,7 @@ impl BuiltIn for Math { .function(Self::trunc, "trunc", 1) .property( string_tag, - Math::NAME, + Self::NAME, Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, ) .build(); @@ -466,7 +466,7 @@ impl Math { // 4. Let n32 be the result of converting n to a value in IEEE 754-2019 binary32 format using roundTiesToEven mode. // 5. Let n64 be the result of converting n32 to a value in IEEE 754-2019 binary64 format. // 6. Return the ECMAScript Number value corresponding to n64. - Ok((x as f32 as f64).into()) + Ok(f64::from(x as f32).into()) } /// Get an approximation of the square root of the sum of squares of all arguments. @@ -715,6 +715,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.random /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random + #[allow(clippy::unnecessary_wraps)] pub(crate) fn random(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // NOTE: Each Math.random function created for distinct realms must produce a distinct sequence of values from successive calls. Ok(rand::random::().into()) diff --git a/boa/src/builtins/number/conversions.rs b/boa/src/builtins/number/conversions.rs index e35837e1e1..e9960cbb95 100644 --- a/boa/src/builtins/number/conversions.rs +++ b/boa/src/builtins/number/conversions.rs @@ -36,10 +36,10 @@ pub(crate) fn f64_to_int32(number: f64) -> i32 { let d64 = number.to_bits(); let significand = d64 & SIGNIFICAND_MASK; - if !is_denormal(number) { - significand + HIDDEN_BIT - } else { + if is_denormal(number) { significand + } else { + significand + HIDDEN_BIT } } diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 97b9c94bcd..a6b104aa64 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -4,7 +4,7 @@ //! A `Number` object is created using the `Number()` constructor. A primitive type object number is created using the `Number()` **function**. //! //! The JavaScript `Number` type is double-precision 64-bit binary format IEEE 754 value. In more recent implementations, -//! JavaScript also supports integers with arbitrary precision using the BigInt type. +//! JavaScript also supports integers with arbitrary precision using the `BigInt` type. //! //! More information: //! - [ECMAScript reference][spec] @@ -301,7 +301,7 @@ impl Number { Ok(JsValue::new(this_str_num)) } - /// flt_str_to_exp - used in to_precision + /// `flt_str_to_exp` - used in `to_precision` /// /// This function traverses a string representing a number, /// returning the floored log10 of this number. @@ -325,7 +325,7 @@ impl Number { (flt.len() as i32) - 1 } - /// round_to_precision - used in to_precision + /// `round_to_precision` - used in `to_precision` /// /// This procedure has two roles: /// - If there are enough or more than enough digits in the @@ -367,14 +367,14 @@ impl Number { } } digits.clear(); - let replacement = if !propagated { + let replacement = if propagated { + replacement.as_str() + } else { digits.push('1'); &replacement.as_str()[1..] - } else { - replacement.as_str() }; for c in replacement.chars().rev() { - digits.push(c) + digits.push(c); } !propagated } else { @@ -541,7 +541,7 @@ impl Number { let mut fraction_cursor = 0; let negative = value.is_sign_negative(); if negative { - value = -value + value = -value; } // Split the value into an integer part and a fractional part. // let mut integer = value.trunc(); @@ -559,15 +559,15 @@ impl Number { fraction_cursor += 1; loop { // Shift up by one digit. - fraction *= radix as f64; - delta *= radix as f64; + fraction *= f64::from(radix); + delta *= f64::from(radix); // Write digit. let digit = fraction as u32; frac_buf[fraction_cursor] = - std::char::from_digit(digit, radix as u32).unwrap() as u8; + std::char::from_digit(digit, u32::from(radix)).unwrap() as u8; fraction_cursor += 1; // Calculate remainder. - fraction -= digit as f64; + fraction -= f64::from(digit); // Round to even. if fraction + delta > 1.0 && (fraction > 0.5 || (fraction - 0.5).abs() < f64::EPSILON && digit & 1 != 0) @@ -583,11 +583,11 @@ impl Number { let c: u8 = frac_buf[fraction_cursor]; // Reconstruct digit. let digit_0 = (c as char).to_digit(10).unwrap(); - if digit_0 + 1 >= radix as u32 { + if digit_0 + 1 >= u32::from(radix) { continue; } frac_buf[fraction_cursor] = - std::char::from_digit(digit_0 + 1, radix as u32).unwrap() as u8; + std::char::from_digit(digit_0 + 1, u32::from(radix)).unwrap() as u8; fraction_cursor += 1; } break; @@ -603,15 +603,15 @@ impl Number { // Compute integer digits. Fill unrepresented digits with zero. let mut int_iter = int_buf.iter_mut().enumerate().rev(); //.rev(); while FloatCore::integer_decode(integer / f64::from(radix)).1 > 0 { - integer /= radix as f64; + integer /= f64::from(radix); *int_iter.next().unwrap().1 = b'0'; } loop { - let remainder = integer % (radix as f64); + let remainder = integer % f64::from(radix); *int_iter.next().unwrap().1 = - std::char::from_digit(remainder as u32, radix as u32).unwrap() as u8; - integer = (integer - remainder) / radix as f64; + std::char::from_digit(remainder as u32, u32::from(radix)).unwrap() as u8; + integer = (integer - remainder) / f64::from(radix); if integer <= 0f64 { break; } @@ -761,6 +761,7 @@ impl Number { let mut strip_prefix = true; // 8. If R ≠ 0, then + #[allow(clippy::if_not_else)] if var_r != 0 { // a. If R < 2 or R > 36, return NaN. if !(2..=36).contains(&var_r) { @@ -769,7 +770,7 @@ impl Number { // b. If R ≠ 16, set stripPrefix to false. if var_r != 16 { - strip_prefix = false + strip_prefix = false; } } else { // 9. Else, @@ -823,9 +824,9 @@ impl Number { if math_int == 0_f64 { if sign == -1 { return Ok(JsValue::new(-0_f64)); - } else { - return Ok(JsValue::new(0_f64)); } + + return Ok(JsValue::new(0_f64)); } // 16. Return 𝔽(sign × mathInt). @@ -873,15 +874,16 @@ impl Number { // Prevent fast_float from parsing "inf", "+inf" as Infinity and "-inf" as -Infinity Ok(JsValue::nan()) } else { - Ok(fast_float::parse_partial::(s) - .map(|(f, len)| { + Ok(fast_float::parse_partial::(s).map_or_else( + |_| JsValue::nan(), + |(f, len)| { if len > 0 { JsValue::new(f) } else { JsValue::nan() } - }) - .unwrap_or_else(|_| JsValue::nan())) + }, + )) } } else { // Not enough arguments to parseFloat. @@ -893,7 +895,7 @@ impl Number { /// /// Converts the argument to a number, throwing a type error if the conversion is invalid. /// - /// If the number is NaN, +∞, or -∞ false is returned. + /// If the number is `NaN`, `+∞`, or `-∞`, `false` is returned. /// /// Otherwise true is returned. /// @@ -920,7 +922,7 @@ impl Number { /// /// Converts the argument to a number, throwing a type error if the conversion is invalid. /// - /// If the number is NaN true is returned. + /// If the number is `NaN`, `true` is returned. /// /// Otherwise false is returned. /// @@ -947,7 +949,7 @@ impl Number { /// /// Checks if the argument is a number, returning false if it isn't. /// - /// If the number is NaN, +∞, or -∞ false is returned. + /// If the number is `NaN`, `+∞`, or `-∞`, `false` is returned. /// /// Otherwise true is returned. /// @@ -957,6 +959,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-number.isfinite /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite + #[allow(clippy::unnecessary_wraps)] pub(crate) fn number_is_finite( _: &JsValue, args: &[JsValue], @@ -983,6 +986,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-number.isinteger /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger + #[allow(clippy::unnecessary_wraps)] pub(crate) fn number_is_integer( _: &JsValue, args: &[JsValue], @@ -995,7 +999,7 @@ impl Number { /// /// Checks if the argument is a number, returning false if it isn't. /// - /// If the number is NaN true is returned. + /// If the number is `NaN`, `true` is returned. /// /// Otherwise false is returned. /// @@ -1005,27 +1009,26 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isnan-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN + #[allow(clippy::unnecessary_wraps)] pub(crate) fn number_is_nan( _: &JsValue, args: &[JsValue], _ctx: &mut Context, ) -> JsResult { - Ok(JsValue::new(if let Some(val) = args.get(0) { - match val { - JsValue::Integer(_) => false, - JsValue::Rational(number) => number.is_nan(), - _ => false, - } - } else { - false - })) + Ok(JsValue::new( + if let Some(&JsValue::Rational(number)) = args.get(0) { + number.is_nan() + } else { + false + }, + )) } /// `Number.isSafeInteger( number )` /// /// Checks if the argument is an integer, returning false if it isn't. /// - /// If abs(number) ≤ MAX_SAFE_INTEGER true is returned. + /// If `abs(number) ≤ MAX_SAFE_INTEGER`, `true` is returned. /// /// Otherwise false is returned. /// @@ -1035,6 +1038,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isnan-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN + #[allow(clippy::unnecessary_wraps)] pub(crate) fn is_safe_integer( _: &JsValue, args: &[JsValue], @@ -1043,13 +1047,13 @@ impl Number { Ok(JsValue::new(match args.get(0) { Some(JsValue::Integer(_)) => true, Some(JsValue::Rational(number)) if Self::is_float_integer(*number) => { - number.abs() <= Number::MAX_SAFE_INTEGER + number.abs() <= Self::MAX_SAFE_INTEGER } _ => false, })) } - /// Checks if the argument is a finite integer Number value. + /// Checks if the argument is a finite integer number value. /// /// More information: /// - [ECMAScript reference][spec] @@ -1059,7 +1063,7 @@ impl Number { pub(crate) fn is_integer(val: &JsValue) -> bool { match val { JsValue::Integer(_) => true, - JsValue::Rational(number) => Number::is_float_integer(*number), + JsValue::Rational(number) => Self::is_float_integer(*number), _ => false, } } @@ -1071,7 +1075,7 @@ impl Number { number.is_finite() && number.abs().floor() == number.abs() } - /// The abstract operation Number::equal takes arguments + /// The abstract operation `Number::equal` takes arguments /// x (a Number) and y (a Number). It performs the following steps when called: /// /// @@ -1081,7 +1085,7 @@ impl Number { x == y } - /// The abstract operation Number::sameValue takes arguments + /// The abstract operation `Number::sameValue` takes arguments /// x (a Number) and y (a Number). It performs the following steps when called: /// /// @@ -1093,7 +1097,7 @@ impl Number { a == b && a.signum() == b.signum() } - /// The abstract operation Number::sameValueZero takes arguments + /// The abstract operation `Number::sameValueZero` takes arguments /// x (a Number) and y (a Number). It performs the following steps when called: /// /// diff --git a/boa/src/builtins/object/for_in_iterator.rs b/boa/src/builtins/object/for_in_iterator.rs index ab1bebf5ce..ea5082e804 100644 --- a/boa/src/builtins/object/for_in_iterator.rs +++ b/boa/src/builtins/object/for_in_iterator.rs @@ -10,7 +10,7 @@ use crate::{ use rustc_hash::FxHashSet; use std::collections::VecDeque; -/// The ForInIterator object represents an iteration over some specific object. +/// The `ForInIterator` object represents an iteration over some specific object. /// It implements the iterator protocol. /// /// More information: @@ -29,7 +29,7 @@ impl ForInIterator { pub(crate) const NAME: &'static str = "ForInIterator"; fn new(object: JsValue) -> Self { - ForInIterator { + Self { object, visited_keys: FxHashSet::default(), remaining_keys: VecDeque::default(), @@ -37,7 +37,7 @@ impl ForInIterator { } } - /// CreateForInIterator( object ) + /// `CreateForInIterator( object )` /// /// Creates a new iterator over the given object. /// @@ -62,7 +62,7 @@ impl ForInIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-%foriniteratorprototype%.next pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut iterator = this.as_object().map(JsObject::borrow_mut); let iterator = iterator .as_mut() .and_then(|obj| obj.as_for_in_iterator_mut()) @@ -79,7 +79,7 @@ impl ForInIterator { PropertyKey::Index(i) => { iterator.remaining_keys.push_back(i.to_string().into()); } - _ => {} + PropertyKey::Symbol(_) => {} } } iterator.object_was_visited = true; @@ -118,7 +118,7 @@ impl ForInIterator { } } - /// Create the %ArrayIteratorPrototype% object + /// Create the `%ArrayIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index ae007eea7b..bd70638139 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -23,7 +23,7 @@ use crate::{ property::{Attribute, PropertyDescriptor, PropertyKey, PropertyNameKind}, symbol::WellKnownSymbols, value::JsValue, - BoaProfiler, Context, JsResult, + BoaProfiler, Context, JsResult, JsString, }; use super::Array; @@ -148,7 +148,7 @@ impl Object { }; if !properties.is_undefined() { - object_define_properties(&obj, properties.clone(), context)?; + object_define_properties(&obj, properties, context)?; return Ok(obj.into()); } @@ -287,7 +287,7 @@ impl Object { } } - /// Uses the SameValue algorithm to check equality of objects + /// Uses the `SameValue` algorithm to check equality of objects pub fn is(_: &JsValue, args: &[JsValue], _: &mut Context) -> JsResult { let x = args.get_or_undefined(0); let y = args.get_or_undefined(1); @@ -441,7 +441,7 @@ impl Object { let arg = args.get_or_undefined(0); if let JsValue::Object(obj) = arg { let props = args.get_or_undefined(1); - object_define_properties(obj, props.clone(), context)?; + object_define_properties(obj, props, context)?; Ok(arg.clone()) } else { context.throw_type_error("Expected an object") @@ -517,7 +517,7 @@ impl Object { let tag = o.get(WellKnownSymbols::to_string_tag(), context)?; // 16. If Type(tag) is not String, set tag to builtinTag. - let tag_str = tag.as_string().map(|s| s.as_str()).unwrap_or(builtin_tag); + let tag_str = tag.as_string().map_or(builtin_tag, JsString::as_str); // 17. Return the string-concatenation of "[object ", tag, and "]". Ok(format!("[object {}]", tag_str).into()) @@ -951,7 +951,7 @@ impl Object { } } -/// The abstract operation ObjectDefineProperties +/// The abstract operation `ObjectDefineProperties` /// /// More information: /// - [ECMAScript reference][spec] @@ -960,7 +960,7 @@ impl Object { #[inline] fn object_define_properties( object: &JsObject, - props: JsValue, + props: &JsValue, context: &mut Context, ) -> JsResult<()> { // 1. Assert: Type(O) is Object. @@ -1003,14 +1003,14 @@ fn object_define_properties( Ok(()) } -/// Type enum used in the abstract operation GetOwnPropertyKeys +/// Type enum used in the abstract operation `GetOwnPropertyKeys`. #[derive(Debug, Copy, Clone)] enum PropertyKeyType { String, Symbol, } -/// The abstract operation GetOwnPropertyKeys +/// The abstract operation `GetOwnPropertyKeys`. /// /// More information: /// - [ECMAScript reference][spec] @@ -1033,9 +1033,9 @@ fn get_own_property_keys( // a. If Type(nextKey) is Symbol and type is symbol or Type(nextKey) is String and type is string, then // i. Append nextKey as the last element of nameList. match (r#type, &next_key) { - (PropertyKeyType::String, PropertyKey::String(_)) => Some(next_key.into()), + (PropertyKeyType::String, PropertyKey::String(_)) + | (PropertyKeyType::Symbol, PropertyKey::Symbol(_)) => Some(next_key.into()), (PropertyKeyType::String, PropertyKey::Index(index)) => Some(index.to_string().into()), - (PropertyKeyType::Symbol, PropertyKey::Symbol(_)) => Some(next_key.into()), _ => None, } }); diff --git a/boa/src/builtins/object/tests.rs b/boa/src/builtins/object/tests.rs index 7b818930d0..8c41b30701 100644 --- a/boa/src/builtins/object/tests.rs +++ b/boa/src/builtins/object/tests.rs @@ -172,7 +172,7 @@ fn object_property_is_enumerable() { assert_eq!( forward(&mut context, r#"x.propertyIsEnumerable()"#), "false", - ) + ); } #[test] diff --git a/boa/src/builtins/reflect/mod.rs b/boa/src/builtins/reflect/mod.rs index f8c789e17a..d2640506fa 100644 --- a/boa/src/builtins/reflect/mod.rs +++ b/boa/src/builtins/reflect/mod.rs @@ -12,7 +12,7 @@ use crate::{ builtins::{self, BuiltIn}, - object::ObjectInitializer, + object::{JsObject, ObjectInitializer}, property::Attribute, symbol::WellKnownSymbols, BoaProfiler, Context, JsResult, JsValue, @@ -79,7 +79,7 @@ impl Reflect { pub(crate) fn apply(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be a function"))?; let this_arg = args.get_or_undefined(1); let args_list = args.get_or_undefined(2); @@ -106,7 +106,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be a function"))?; let args_list = args.get_or_undefined(1); @@ -115,7 +115,7 @@ impl Reflect { } let new_target = if let Some(new_target) = args.get(2) { - if new_target.as_object().map(|o| o.is_constructor()) != Some(true) { + if new_target.as_object().map(JsObject::is_constructor) != Some(true) { return context.throw_type_error("newTarget must be constructor"); } new_target.clone() @@ -142,7 +142,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args.get_or_undefined(1).to_property_key(context)?; let prop_desc: JsValue = args @@ -153,7 +153,7 @@ impl Reflect { target .__define_own_property__(key, prop_desc.to_property_descriptor(context)?, context) - .map(|b| b.into()) + .map(Into::into) } /// Defines a property on an object. @@ -171,7 +171,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args.get_or_undefined(1).to_property_key(context)?; @@ -190,7 +190,7 @@ impl Reflect { // 1. If Type(target) is not Object, throw a TypeError exception. let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; // 2. Let key be ? ToPropertyKey(propertyKey). let key = args.get_or_undefined(1).to_property_key(context)?; @@ -246,7 +246,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; Ok(target .__get_prototype_of__(context)? @@ -264,7 +264,7 @@ impl Reflect { pub(crate) fn has(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args .get(1) @@ -288,7 +288,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; Ok(target.__is_extensible__(context)?.into()) } @@ -308,13 +308,13 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let keys: Vec = target .__own_property_keys__(context)? .into_iter() - .map(|key| key.into()) + .map(Into::into) .collect(); Ok(Array::create_array_from_list(keys, context).into()) @@ -335,7 +335,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; Ok(target.__prevent_extensions__(context)?.into()) @@ -352,7 +352,7 @@ impl Reflect { pub(crate) fn set(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args.get_or_undefined(1).to_property_key(context)?; let value = args.get_or_undefined(2); @@ -381,7 +381,7 @@ impl Reflect { ) -> JsResult { let target = args .get(0) - .and_then(|v| v.as_object()) + .and_then(JsValue::as_object) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let proto = match args.get_or_undefined(1) { JsValue::Object(obj) => Some(obj.clone()), diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 0b9c6043f4..6de8d38b3e 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -1,6 +1,6 @@ //! This module implements the global `RegExp` object. //! -//! `The `RegExp` object is used for matching text with a pattern. +//! The `RegExp` object is used for matching text with a pattern. //! //! More information: //! - [ECMAScript reference][spec] @@ -237,10 +237,10 @@ impl RegExp { }; // 7. Let O be ? RegExpAlloc(newTarget). - let o = RegExp::alloc(new_target, &[], context)?; + let o = Self::alloc(new_target, &[], context)?; // 8.Return ? RegExpInitialize(O, P, F). - RegExp::initialize(&o, &[p, f], context) + Self::initialize(&o, &[p, f], context) } /// `22.2.3.2.1 RegExpAlloc ( newTarget )` @@ -335,7 +335,7 @@ impl RegExp { Ok(val) => val, }; - let regexp = RegExp { + let regexp = Self { matcher, dot_all, global, @@ -361,19 +361,19 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-regexpcreate pub(crate) fn create(p: JsValue, f: JsValue, context: &mut Context) -> JsResult { // 1. Let obj be ? RegExpAlloc(%RegExp%). - let obj = RegExp::alloc( - &context.global_object().get(RegExp::NAME, context)?, + let obj = Self::alloc( + &context.global_object().get(Self::NAME, context)?, &[], context, )?; // 2. Return ? RegExpInitialize(obj, P, F). - RegExp::initialize(&obj, &[p, f], context) + Self::initialize(&obj, &[p, f], context) } /// `get RegExp [ @@species ]` /// - /// The `RegExp [ @@species ]` accessor property returns the RegExp constructor. + /// The `RegExp [ @@species ]` accessor property returns the `RegExp` constructor. /// /// More information: /// - [ECMAScript reference][spec] @@ -381,6 +381,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) @@ -639,7 +640,10 @@ impl RegExp { // 5. Let src be R.[[OriginalSource]]. // 6. Let flags be R.[[OriginalFlags]]. // 7. Return EscapeRegExpPattern(src, flags). - RegExp::escape_pattern(&re.original_source, &re.original_flags) + Ok(Self::escape_pattern( + &re.original_source, + &re.original_flags, + )) } } } else { @@ -653,9 +657,9 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-escaperegexppattern - fn escape_pattern(src: &str, _flags: &str) -> JsResult { + fn escape_pattern(src: &str, _flags: &str) -> JsValue { if src.is_empty() { - Ok(JsValue::new("(?:)")) + JsValue::new("(?:)") } else { let mut s = String::from(""); @@ -668,7 +672,7 @@ impl RegExp { } } - Ok(JsValue::new(s)) + JsValue::new(s) } } @@ -744,7 +748,7 @@ impl RegExp { let arg_str = args.get_or_undefined(0).to_string(context)?; // 4. Return ? RegExpBuiltinExec(R, S). - if let Some(v) = Self::abstract_builtin_exec(obj, arg_str, context)? { + if let Some(v) = Self::abstract_builtin_exec(obj, &arg_str, context)? { Ok(v.into()) } else { Ok(JsValue::null()) @@ -788,7 +792,7 @@ impl RegExp { } // 6. Return ? RegExpBuiltinExec(R, S). - Self::abstract_builtin_exec(this, input, context) + Self::abstract_builtin_exec(this, &input, context) } /// `22.2.5.2.2 RegExpBuiltinExec ( R, S )` @@ -799,7 +803,7 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-regexpbuiltinexec pub(crate) fn abstract_builtin_exec( this: &JsObject, - input: JsString, + input: &JsString, context: &mut Context, ) -> JsResult> { // 1. Assert: R is an initialized RegExp instance. @@ -866,7 +870,7 @@ impl RegExp { .throw_type_error("Failed to get byte index from utf16 encoded string") } }; - let r = matcher.find_from(&input, last_byte_index).next(); + let r = matcher.find_from(input, last_byte_index).next(); match r { // c. If r is failure, then @@ -881,12 +885,12 @@ impl RegExp { } // ii. Set lastIndex to AdvanceStringIndex(S, lastIndex, fullUnicode). - last_index = advance_string_index(input.clone(), last_index, unicode); + last_index = advance_string_index(input, last_index, unicode); } Some(m) => { // c. If r is failure, then - // d. Else, + #[allow(clippy::if_not_else)] if m.start() != last_index { // i. If sticky is true, then if sticky { @@ -898,7 +902,8 @@ impl RegExp { } // ii. Set lastIndex to AdvanceStringIndex(S, lastIndex, fullUnicode). - last_index = advance_string_index(input.clone(), last_index, unicode); + last_index = advance_string_index(input, last_index, unicode); + // d. Else, } else { //i. Assert: r is a State. //ii. Set matchSucceeded to true. @@ -1052,7 +1057,7 @@ impl RegExp { let global = rx.get("global", context)?.to_boolean(); // 5. If global is false, then - // 6. Else, + #[allow(clippy::if_not_else)] if !global { // a. Return ? RegExpExec(rx, S). if let Some(v) = Self::abstract_exec(rx, arg_str, context)? { @@ -1060,6 +1065,7 @@ impl RegExp { } else { Ok(JsValue::null()) } + // 6. Else, } else { // a. Assert: global is true. @@ -1096,7 +1102,7 @@ impl RegExp { let this_index = rx.get("lastIndex", context)?.to_length(context)?; // b. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode). - let next_index = advance_string_index(arg_str.clone(), this_index, unicode); + let next_index = advance_string_index(&arg_str, this_index, unicode); // c. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true). rx.set("lastIndex", JsValue::new(next_index), true, context)?; @@ -1106,12 +1112,11 @@ impl RegExp { n += 1; } else { // 1. If n = 0, return null. - // 2. Return A. if n == 0 { return Ok(JsValue::null()); - } else { - return Ok(a.into()); } + // 2. Return A. + return Ok(a.into()); } } } @@ -1208,13 +1213,13 @@ impl RegExp { let unicode = flags.contains('u'); // 13. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode). - RegExpStringIterator::create_regexp_string_iterator( + Ok(RegExpStringIterator::create_regexp_string_iterator( matcher.clone(), arg_str, global, unicode, context, - ) + )) } /// `RegExp.prototype [ @@replace ] ( string, replaceValue )` @@ -1258,7 +1263,7 @@ impl RegExp { let mut replace_value = args.get_or_undefined(1).clone(); let functional_replace = replace_value .as_object() - .map(|obj| obj.is_callable()) + .map(JsObject::is_callable) .unwrap_or_default(); // 6. If functionalReplace is false, then @@ -1296,24 +1301,24 @@ impl RegExp { results.push(result.clone()); // ii. If global is false, set done to true. - // iii. Else, + if !global { break; - } else { - // 1. Let matchStr be ? ToString(? Get(result, "0")). - let match_str = result.get("0", context)?.to_string(context)?; + } + // iii. Else, + // 1. Let matchStr be ? ToString(? Get(result, "0")). + let match_str = result.get("0", context)?.to_string(context)?; - // 2. If matchStr is the empty String, then - if match_str.is_empty() { - // a. Let thisIndex be ℝ(? ToLength(? Get(rx, "lastIndex"))). - let this_index = rx.get("lastIndex", context)?.to_length(context)?; + // 2. If matchStr is the empty String, then + if match_str.is_empty() { + // a. Let thisIndex be ℝ(? ToLength(? Get(rx, "lastIndex"))). + let this_index = rx.get("lastIndex", context)?.to_length(context)?; - // b. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode). - let next_index = advance_string_index(arg_str.clone(), this_index, unicode); + // b. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode). + let next_index = advance_string_index(&arg_str, this_index, unicode); - // c. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true). - rx.set("lastIndex", JsValue::new(next_index), true, context)?; - } + // c. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true). + rx.set("lastIndex", JsValue::new(next_index), true, context)?; } } else { break; @@ -1420,12 +1425,12 @@ impl RegExp { // ii. Let replacement be ? GetSubstitution(matched, S, position, captures, namedCaptures, replaceValue). replacement = string::get_substitution( - matched.to_string(), - arg_str.to_string(), + matched.as_str(), + arg_str.as_str(), position, - captures, - named_captures, - replace_value.to_string(context)?, + &captures, + &named_captures, + &replace_value.to_string(context)?, context, )?; } @@ -1652,7 +1657,7 @@ impl RegExp { // iii. If e = p, set q to AdvanceStringIndex(S, q, unicodeMatching). // iv. Else, if e == p { - q = advance_string_index(arg_str.clone(), q, unicode); + q = advance_string_index(&arg_str, q, unicode); } else { // 1. Let T be the substring of S from p to q. let arg_str_substring = String::from_utf16_lossy( @@ -1711,7 +1716,7 @@ impl RegExp { q = p; } } else { - q = advance_string_index(arg_str.clone(), q, unicode); + q = advance_string_index(&arg_str, q, unicode); } } @@ -1739,7 +1744,7 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-advancestringindex -fn advance_string_index(s: JsString, index: usize, unicode: bool) -> usize { +fn advance_string_index(s: &JsString, index: usize, unicode: bool) -> usize { // Regress only works with utf8, so this function differs from the spec. // 1. Assert: index ≤ 2^53 - 1. diff --git a/boa/src/builtins/regexp/regexp_string_iterator.rs b/boa/src/builtins/regexp/regexp_string_iterator.rs index fd8092234f..ee8a372e39 100644 --- a/boa/src/builtins/regexp/regexp_string_iterator.rs +++ b/boa/src/builtins/regexp/regexp_string_iterator.rs @@ -1,8 +1,9 @@ //! This module implements the global `RegExp String Iterator` object. //! -//! A RegExp String Iterator is an object, that represents a specific iteration over some specific String instance object, matching against some specific RegExp instance object. -//! There is not a named constructor for RegExp String Iterator objects. -//! Instead, RegExp String Iterator objects are created by calling certain methods of RegExp instance objects. +//! A `RegExp` String Iterator is an object, that represents a specific iteration over some +//! specific String instance object, matching against some specific `RegExp` instance object. +//! There is not a named constructor for `RegExp` String Iterator objects. Instead, `RegExp` +//! String Iterator objects are created by calling certain methods of `RegExp` instance objects. //! //! More information: //! - [ECMAScript reference][spec] @@ -54,7 +55,7 @@ impl RegExpStringIterator { global: bool, unicode: bool, context: &mut Context, - ) -> JsResult { + ) -> JsValue { // TODO: Implement this with closures and generators. // For now all values of the closure are stored in RegExpStringIterator and the actual closure execution is in `.next()`. @@ -72,11 +73,11 @@ impl RegExpStringIterator { ObjectData::reg_exp_string_iterator(Self::new(matcher, string, global, unicode)), ); - Ok(regexp_string_iterator.into()) + regexp_string_iterator.into() } pub fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut iterator = this.as_object().map(JsObject::borrow_mut); let iterator = iterator .as_mut() .and_then(|obj| obj.as_regexp_string_iterator_mut()) @@ -116,7 +117,7 @@ impl RegExpStringIterator { // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). let next_index = - advance_string_index(iterator.string.clone(), this_index, iterator.unicode); + advance_string_index(&iterator.string, this_index, iterator.unicode); // 3. Perform ? Set(R, "lastIndex", 𝔽(nextIndex), true). iterator @@ -137,7 +138,7 @@ impl RegExpStringIterator { } } - /// Create the %ArrayIteratorPrototype% object + /// Create the `%ArrayIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/set/mod.rs b/boa/src/builtins/set/mod.rs index c0882d773e..35c2da665f 100644 --- a/boa/src/builtins/set/mod.rs +++ b/boa/src/builtins/set/mod.rs @@ -162,7 +162,7 @@ impl Set { return iterator_record.close(Err(status), context); } - next = iterator_record.next(context)? + next = iterator_record.next(context)?; } // 8.b @@ -179,6 +179,7 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-get-set-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) @@ -203,7 +204,7 @@ impl Set { if let Some(object) = this.as_object() { if let Some(set) = object.borrow_mut().as_set_mut() { - set.add(if value.as_number().map(|n| n == -0f64).unwrap_or(false) { + set.add(if value.as_number().map_or(false, |n| n == -0f64) { JsValue::Integer(0) } else { value.clone() @@ -336,7 +337,7 @@ impl Set { let mut index = 0; - while index < Set::get_size(this, context)? { + while index < Self::get_size(this, context)? { let arguments = this .as_object() .and_then(|obj| { @@ -418,13 +419,13 @@ impl Set { } fn size_getter(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - Set::get_size(this, context).map(JsValue::from) + Self::get_size(this, context).map(JsValue::from) } /// Helper function to get the size of the set. fn get_size(set: &JsValue, context: &mut Context) -> JsResult { set.as_object() - .and_then(|obj| obj.borrow().as_set_ref().map(|set| set.size())) + .and_then(|obj| obj.borrow().as_set_ref().map(OrderedSet::size)) .ok_or_else(|| context.construct_type_error("'this' is not a Set")) } } diff --git a/boa/src/builtins/set/ordered_set.rs b/boa/src/builtins/set/ordered_set.rs index c83c57d465..f084b69eaa 100644 --- a/boa/src/builtins/set/ordered_set.rs +++ b/boa/src/builtins/set/ordered_set.rs @@ -9,16 +9,19 @@ use std::{ hash::{BuildHasher, Hash}, }; -/// A newtype wrapping indexmap::IndexSet +/// A type wrapping `indexmap::IndexSet` #[derive(Clone)] -pub struct OrderedSet(IndexSet) +pub struct OrderedSet where - V: Hash + Eq; + V: Hash + Eq, +{ + inner: IndexSet, +} impl Finalize for OrderedSet {} unsafe impl Trace for OrderedSet { custom_trace!(this, { - for v in this.0.iter() { + for v in this.inner.iter() { mark(v); } }); @@ -26,7 +29,7 @@ unsafe impl Trace for OrderedSet { impl Debug for OrderedSet { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - self.0.fmt(formatter) + self.inner.fmt(formatter) } } @@ -41,25 +44,29 @@ where V: Hash + Eq, { pub fn new() -> Self { - OrderedSet(IndexSet::new()) + Self { + inner: IndexSet::new(), + } } pub fn with_capacity(capacity: usize) -> Self { - OrderedSet(IndexSet::with_capacity(capacity)) + Self { + inner: IndexSet::with_capacity(capacity), + } } /// Return the number of key-value pairs in the map. /// /// Computes in **O(1)** time. pub fn size(&self) -> usize { - self.0.len() + self.inner.len() } /// Returns true if the map contains no elements. /// /// Computes in **O(1)** time. pub fn is_empty(&self) -> bool { - self.0.len() == 0 + self.inner.len() == 0 } /// Insert a value pair in the set. @@ -71,7 +78,7 @@ where /// /// Computes in **O(1)** time (amortized average). pub fn add(&mut self, value: V) -> bool { - self.0.insert(value) + self.inner.insert(value) } /// Delete the `value` from the set and return true if successful @@ -80,7 +87,7 @@ where /// /// Computes in **O(n)** time (average). pub fn delete(&mut self, value: &V) -> bool { - self.0.shift_remove(value) + self.inner.shift_remove(value) } /// Checks if a given value is present in the set @@ -89,19 +96,19 @@ where /// /// Computes in **O(n)** time (average). pub fn contains(&self, value: &V) -> bool { - self.0.contains(value) + self.inner.contains(value) } /// Get a key-value pair by index /// Valid indices are 0 <= index < self.len() /// Computes in O(1) time. pub fn get_index(&self, index: usize) -> Option<&V> { - self.0.get_index(index) + self.inner.get_index(index) } /// Return an iterator over the values of the set, in their order pub fn iter(&self) -> Iter<'_, V> { - self.0.iter() + self.inner.iter() } } @@ -113,7 +120,7 @@ where type Item = &'a V; type IntoIter = Iter<'a, V>; fn into_iter(self) -> Self::IntoIter { - self.0.iter() + self.inner.iter() } } @@ -125,6 +132,6 @@ where type Item = V; type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { - self.0.into_iter() + self.inner.into_iter() } } diff --git a/boa/src/builtins/set/set_iterator.rs b/boa/src/builtins/set/set_iterator.rs index c82ac608ca..f6c84c0dbf 100644 --- a/boa/src/builtins/set/set_iterator.rs +++ b/boa/src/builtins/set/set_iterator.rs @@ -25,14 +25,14 @@ impl SetIterator { /// Constructs a new `SetIterator`, that will iterate over `set`, starting at index 0 fn new(set: JsValue, kind: PropertyNameKind) -> Self { - SetIterator { + Self { iterated_set: set, next_index: 0, iteration_kind: kind, } } - /// Abstract operation CreateSetIterator( set, kind ) + /// Abstract operation `CreateSetIterator( set, kind )` /// /// Creates a new iterator over the given set. /// @@ -61,7 +61,7 @@ impl SetIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-%setiteratorprototype%.next pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut set_iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut set_iterator = this.as_object().map(JsObject::borrow_mut); let set_iterator = set_iterator .as_mut() @@ -80,7 +80,7 @@ impl SetIterator { )); } - let entries = m.as_object().map(|obj| obj.borrow()); + let entries = m.as_object().map(JsObject::borrow); let entries = entries .as_ref() .and_then(|obj| obj.as_set_ref()) @@ -119,7 +119,7 @@ impl SetIterator { )) } - /// Create the %SetIteratorPrototype% object + /// Create the `%SetIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 063b285e27..3a49154f2d 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -13,13 +13,13 @@ pub mod string_iterator; #[cfg(test)] mod tests; -use crate::builtins::Symbol; -use crate::context::StandardObjects; -use crate::object::internal_methods::get_prototype_from_constructor; -use crate::object::JsObject; +use super::JsArgs; use crate::{ - builtins::{string::string_iterator::StringIterator, Array, BuiltIn, RegExp}, - object::{ConstructorBuilder, ObjectData}, + builtins::{string::string_iterator::StringIterator, Array, BuiltIn, RegExp, Symbol}, + context::StandardObjects, + object::{ + internal_methods::get_prototype_from_constructor, ConstructorBuilder, JsObject, ObjectData, + }, property::{Attribute, PropertyDescriptor}, symbol::WellKnownSymbols, BoaProfiler, Context, JsResult, JsString, JsValue, @@ -31,9 +31,7 @@ use std::{ }; use unicode_normalization::UnicodeNormalization; -use super::JsArgs; - -pub(crate) fn code_point_at(string: JsString, position: i32) -> Option<(u32, u8, bool)> { +pub(crate) fn code_point_at(string: &JsString, position: i32) -> Option<(u32, u8, bool)> { let size = string.encode_utf16().count() as i32; if position < 0 || position >= size { return None; @@ -41,16 +39,16 @@ pub(crate) fn code_point_at(string: JsString, position: i32) -> Option<(u32, u8, let mut encoded = string.encode_utf16(); let first = encoded.nth(position as usize)?; if !is_leading_surrogate(first) && !is_trailing_surrogate(first) { - return Some((first as u32, 1, false)); + return Some((u32::from(first), 1, false)); } if is_trailing_surrogate(first) || position + 1 == size { - return Some((first as u32, 1, true)); + return Some((u32::from(first), 1, true)); } let second = encoded.next()?; if !is_trailing_surrogate(second) { - return Some((first as u32, 1, true)); + return Some((u32::from(first), 1, true)); } - let cp = (first as u32 - 0xD800) * 0x400 + (second as u32 - 0xDC00) + 0x10000; + let cp = (u32::from(first) - 0xD800) * 0x400 + (u32::from(second) - 0xDC00) + 0x10000; Some((cp, 2, false)) } @@ -385,7 +383,7 @@ impl String { // Note that this is an O(N) operation (because UTF-8 is complex) while getting the number of // bytes is an O(1) operation. if let Some(utf16_val) = primitive_val.encode_utf16().nth(pos as usize) { - Ok(JsValue::new(from_u32(utf16_val as u32).unwrap())) + Ok(JsValue::new(from_u32(u32::from(utf16_val)).unwrap())) } else { Ok("".into()) } @@ -411,7 +409,7 @@ impl String { .cloned() .unwrap_or_default() .to_integer(context)?; - let k = if relative_index < 0 as f64 { + let k = if relative_index < 0_f64 { len - (-relative_index as usize) } else { relative_index as usize @@ -459,7 +457,7 @@ impl String { return Ok(JsValue::undefined()); } - if let Some((code_point, _, _)) = code_point_at(primitive_val, pos) { + if let Some((code_point, _, _)) = code_point_at(&primitive_val, pos) { Ok(JsValue::new(code_point)) } else { Ok(JsValue::undefined()) @@ -843,7 +841,7 @@ impl String { // 5. Let functionalReplace be IsCallable(replaceValue). let functional_replace = replace_value .as_object() - .map(|obj| obj.is_callable()) + .map(JsObject::is_callable) .unwrap_or_default(); // 6. If functionalReplace is false, then @@ -883,12 +881,12 @@ impl String { // c. Let replacement be ! GetSubstitution(searchString, string, position, captures, undefined, replaceValue). get_substitution( - search_str.to_string(), - this_str.to_string(), + search_str.as_str(), + this_str.as_str(), position, - captures, - JsValue::undefined(), - replace_value.to_string(context)?, + &captures, + &JsValue::undefined(), + &replace_value.to_string(context)?, context, )? }; @@ -910,9 +908,11 @@ impl String { /// `22.1.3.18 String.prototype.replaceAll ( searchValue, replaceValue )` /// - /// The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement. + /// The replaceAll() method returns a new string with 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. + /// 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. /// /// The original string is left unchanged. /// @@ -973,15 +973,16 @@ impl String { // 5. Let functionalReplace be IsCallable(replaceValue). let functional_replace = replace_value .as_object() - .map(|obj| obj.is_callable()) + .map(JsObject::is_callable) .unwrap_or_default(); // 6. If functionalReplace is false, then + #[allow(clippy::if_not_else)] let replace_value_string = if !functional_replace { // a. Set replaceValue to ? ToString(replaceValue). replace_value.to_string(context)? } else { - JsString::new("") + JsString::empty() }; // 7. Let searchLength be the length of searchString. @@ -1043,12 +1044,12 @@ impl String { // ii. Let captures be a new empty List. // iii. Let replacement be ! GetSubstitution(searchString, string, p, captures, undefined, replaceValue). get_substitution( - search_string.to_string(), - string.to_string(), + search_string.as_str(), + string.as_str(), p, - Vec::new(), - JsValue::undefined(), - replace_value_string.clone(), + &[], + &JsValue::undefined(), + &replace_value_string, context, ) .expect("GetSubstitution should never fail here.") @@ -1221,7 +1222,7 @@ impl String { fn string_pad( primitive: JsString, max_length: i32, - fill_string: Option, + fill_string: Option<&JsString>, at_start: bool, ) -> JsValue { let primitive_length = primitive.len() as i32; @@ -1230,7 +1231,7 @@ impl String { return JsValue::new(primitive); } - let filler = fill_string.as_deref().unwrap_or(" "); + let filler = fill_string.map_or(" ", JsString::as_str); if filler.is_empty() { return JsValue::new(primitive); @@ -1280,7 +1281,12 @@ impl String { let fill_string = args.get(1).map(|arg| arg.to_string(context)).transpose()?; - Ok(Self::string_pad(primitive, max_length, fill_string, false)) + Ok(Self::string_pad( + primitive, + max_length, + fill_string.as_ref(), + false, + )) } /// `String.prototype.padStart( targetLength [, padString] )` @@ -1311,7 +1317,12 @@ impl String { let fill_string = args.get(1).map(|arg| arg.to_string(context)).transpose()?; - Ok(Self::string_pad(primitive, max_length, fill_string, true)) + Ok(Self::string_pad( + primitive, + max_length, + fill_string.as_ref(), + true, + )) } /// String.prototype.trim() @@ -1858,12 +1869,12 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-getsubstitution pub(crate) fn get_substitution( - matched: StdString, - str: StdString, + matched: &str, + str: &str, position: usize, - captures: Vec, - named_captures: JsValue, - replacement: JsString, + captures: &[JsValue], + named_captures: &JsValue, + replacement: &JsString, context: &mut Context, ) -> JsResult { // 1. Assert: Type(matched) is String. @@ -1910,7 +1921,7 @@ pub(crate) fn get_substitution( // $& (Some('&'), _) => { // matched - result.push_str(&matched); + result.push_str(matched); } // $` (Some('`'), _) => { @@ -1971,7 +1982,7 @@ pub(crate) fn get_substitution( // 1. If namedCaptures is undefined, the replacement text is the String "$<". // 2. Else, if named_captures.is_undefined() { - result.push_str("$<") + result.push_str("$<"); } else { // a. Assert: Type(namedCaptures) is Object. @@ -1990,10 +2001,11 @@ pub(crate) fn get_substitution( } // c. If none is found, the replacement text is the String "$<". - // d. Else, + #[allow(clippy::if_not_else)] if !found { result.push_str("$<"); result.push_str(&group_name); + // d. Else, } else { // i. Let groupName be the enclosed substring. // ii. Let capture be ? Get(namedCaptures, groupName). diff --git a/boa/src/builtins/string/string_iterator.rs b/boa/src/builtins/string/string_iterator.rs index f6147bf11d..18c218118a 100644 --- a/boa/src/builtins/string/string_iterator.rs +++ b/boa/src/builtins/string/string_iterator.rs @@ -32,7 +32,7 @@ impl StringIterator { } pub fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - let mut string_iterator = this.as_object().map(|obj| obj.borrow_mut()); + let mut string_iterator = this.as_object().map(JsObject::borrow_mut); let string_iterator = string_iterator .as_mut() .and_then(|obj| obj.as_string_iterator_mut()) @@ -57,8 +57,8 @@ impl StringIterator { )); } let (_, code_unit_count, _) = - code_point_at(native_string, position).expect("Invalid code point position"); - string_iterator.next_index += code_unit_count as i32; + code_point_at(&native_string, position).expect("Invalid code point position"); + string_iterator.next_index += i32::from(code_unit_count); let result_string = crate::builtins::string::String::substring( &string_iterator.string, &[position.into(), string_iterator.next_index.into()], @@ -67,7 +67,7 @@ impl StringIterator { Ok(create_iter_result_object(result_string, false, context)) } - /// Create the %ArrayIteratorPrototype% object + /// Create the `%ArrayIteratorPrototype%` object /// /// More information: /// - [ECMA reference][spec] diff --git a/boa/src/builtins/string/tests.rs b/boa/src/builtins/string/tests.rs index 0806aa342f..7d6c78b69e 100644 --- a/boa/src/builtins/string/tests.rs +++ b/boa/src/builtins/string/tests.rs @@ -350,7 +350,7 @@ fn starts_with_with_regex_arg() { &mut context, scenario ), "\"TypeError: First argument to String.prototype.startsWith must not be a regular expression\"" - ) + ); } #[test] @@ -394,7 +394,7 @@ fn ends_with_with_regex_arg() { &mut context, scenario ), "\"TypeError: First argument to String.prototype.endsWith must not be a regular expression\"" - ) + ); } #[test] @@ -438,7 +438,7 @@ fn includes_with_regex_arg() { &mut context, scenario ), "\"TypeError: First argument to String.prototype.includes must not be a regular expression\"" - ) + ); } #[test] @@ -680,7 +680,10 @@ fn split() { // TODO: Support keeping invalid code point in string assert_eq!( - forward(&mut context, "'𝟘𝟙𝟚𝟛'.split('')"), + forward( + &mut context, + "\'\u{1d7d8}\u{1d7d9}\u{1d7da}\u{1d7db}\'.split(\'\')" + ), forward(&mut context, "['�','�','�','�','�','�','�','�']") ); } diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index cc45939811..89f94f02bc 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -61,8 +61,8 @@ impl GlobalSymbolRegistry { symbol } - fn get_symbol(&self, sym: JsSymbol) -> Option { - if let Some(key) = self.symbols.get(&sym) { + fn get_symbol(&self, sym: &JsSymbol) -> Option { + if let Some(key) = self.symbols.get(sym) { return Some(key.clone()); } @@ -311,7 +311,7 @@ impl Symbol { // 4. Return undefined. let symbol = GLOBAL_SYMBOL_REGISTRY.with(move |registry| { let registry = registry.borrow(); - registry.get_symbol(sym) + registry.get_symbol(&sym) }); Ok(symbol.map(JsValue::from).unwrap_or_default()) diff --git a/boa/src/builtins/typed_array/integer_indexed_object.rs b/boa/src/builtins/typed_array/integer_indexed_object.rs index cf29aacad5..e9eb71ff0e 100644 --- a/boa/src/builtins/typed_array/integer_indexed_object.rs +++ b/boa/src/builtins/typed_array/integer_indexed_object.rs @@ -56,14 +56,16 @@ impl IntegerIndexed { /// `IntegerIndexedObjectCreate ( prototype )` /// - /// Create a new `JsObject from a prototype and a `IntergetIndexedObject` + /// Create a new `JsObject` from a prototype and a `IntergetIndexedObject` /// /// More information: /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-integerindexedobjectcreate pub(super) fn create(prototype: JsObject, data: Self, context: &Context) -> JsObject { - // 1. Let internalSlotsList be « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] ». + // 1. Let internalSlotsList be « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], + // [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], + // [[ArrayLength]] ». // 2. Let A be ! MakeBasicObject(internalSlotsList). let a = context.construct_object(); diff --git a/boa/src/builtins/typed_array/mod.rs b/boa/src/builtins/typed_array/mod.rs index 1013464b7c..42063d7b53 100644 --- a/boa/src/builtins/typed_array/mod.rs +++ b/boa/src/builtins/typed_array/mod.rs @@ -146,11 +146,7 @@ macro_rules! typed_array { // ii. If firstArgument has a [[TypedArrayName]] internal slot, then if first_argument.is_typed_array() { // 1. Perform ? InitializeTypedArrayFromTypedArray(O, firstArgument). - TypedArray::initialize_from_typed_array( - &o, - first_argument.clone(), - context, - )?; + TypedArray::initialize_from_typed_array(&o, first_argument, context)?; } else if first_argument.is_array_buffer() { // iii. Else if firstArgument has an [[ArrayBufferData]] internal slot, then @@ -185,7 +181,7 @@ macro_rules! typed_array { // a. Let values be ? IterableToList(firstArgument, usingIterator). let values = iterable_to_list( context, - first_argument_v, + &first_argument_v, Some(using_iterator.into()), )?; @@ -418,7 +414,7 @@ impl TypedArray { // 6. If usingIterator is not undefined, then if let Some(using_iterator) = using_iterator { // a. Let values be ? IterableToList(source, usingIterator). - let values = iterable_to_list(context, source.clone(), Some(using_iterator.into()))?; + let values = iterable_to_list(context, source, Some(using_iterator.into()))?; // b. Let len be the number of elements in values. // c. Let targetObj be ? TypedArrayCreate(C, « 𝔽(len) »). @@ -525,6 +521,7 @@ impl TypedArray { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-get-%typedarray%-@@species + #[allow(clippy::unnecessary_wraps)] fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Return the this value. Ok(this.clone()) @@ -600,8 +597,7 @@ impl TypedArray { // 5. Return buffer. Ok(typed_array .viewed_array_buffer() - .map(|buffer| buffer.clone().into()) - .unwrap_or_else(JsValue::undefined)) + .map_or_else(JsValue::undefined, |buffer| buffer.clone().into())) } /// `23.2.3.3 get %TypedArray%.prototype.byteLength` @@ -810,7 +806,7 @@ impl TypedArray { buffer.set_value_in_buffer( to_byte_index as usize, TypedArrayName::Uint8Array, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -2071,7 +2067,7 @@ impl TypedArray { .set_value_in_buffer( target_byte_index, TypedArrayName::Uint8Array, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -2105,7 +2101,7 @@ impl TypedArray { .set_value_in_buffer( target_byte_index, target_name, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -2220,7 +2216,7 @@ impl TypedArray { target_buffer.set_value_in_buffer( target_byte_index, target_name, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -2310,6 +2306,7 @@ impl TypedArray { // d. Let targetName be the String value of A.[[TypedArrayName]]. // e. Let targetType be the Element Type value in Table 73 for targetName. // f. If srcType is different from targetType, then + #[allow(clippy::if_not_else)] if o.typed_array_name() != a_array.typed_array_name() { // i. Let n be 0. let mut n = 0; @@ -2379,7 +2376,7 @@ impl TypedArray { target_buffer.set_value_in_buffer( target_byte_index, TypedArrayName::Uint8Array, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -2785,6 +2782,7 @@ impl TypedArray { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag + #[allow(clippy::unnecessary_wraps)] fn to_string_tag(this: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { // 1. Let O be the this value. // 2. If Type(O) is not Object, return undefined. @@ -2947,7 +2945,7 @@ impl TypedArray { let o_inner = o.as_typed_array_mut().expect("expected a TypedArray"); // 2. Perform ? AllocateTypedArrayBuffer(O, len). - TypedArray::allocate_buffer(o_inner, len, context)?; + Self::allocate_buffer(o_inner, len, context)?; } // 3. Let k be 0. @@ -3001,7 +2999,7 @@ impl TypedArray { // 8. Else, if let Some(length) = length { // a. Perform ? AllocateTypedArrayBuffer(obj, length). - TypedArray::allocate_buffer(&mut indexed, length, context)?; + Self::allocate_buffer(&mut indexed, length, context)?; } // 2. Let obj be ! IntegerIndexedObjectCreate(proto). @@ -3019,7 +3017,7 @@ impl TypedArray { /// [spec]: https://tc39.es/ecma262/#sec-initializetypedarrayfromtypedarray fn initialize_from_typed_array( o: &JsObject, - src_array: JsObject, + src_array: &JsObject, context: &mut Context, ) -> JsResult<()> { let o_obj = o.borrow(); @@ -3121,7 +3119,7 @@ impl TypedArray { data.set_value_in_buffer( target_byte_index, constructor_name, - value, + &value, SharedMemoryOrder::Unordered, None, context, @@ -3268,7 +3266,7 @@ impl TypedArray { { let mut o_borrow = o.borrow_mut(); let o = o_borrow.as_typed_array_mut().expect("Must be typed array"); - TypedArray::allocate_buffer(o, len, context)?; + Self::allocate_buffer(o, len, context)?; } // 3. Let k be 0. @@ -3348,7 +3346,7 @@ impl TypedArrayName { } } - pub(crate) fn is_big_int_element_type(&self) -> bool { + pub(crate) fn is_big_int_element_type(self) -> bool { matches!( self, TypedArrayName::BigUint64Array | TypedArrayName::BigInt64Array diff --git a/boa/src/bytecompiler.rs b/boa/src/bytecompiler.rs index 533db5a845..f875edd22b 100644 --- a/boa/src/bytecompiler.rs +++ b/boa/src/bytecompiler.rs @@ -140,7 +140,7 @@ impl<'b> ByteCompiler<'b> { #[inline] fn emit_opcode(&mut self, opcode: Opcode) { - self.emit_u8(opcode as u8) + self.emit_u8(opcode as u8); } #[inline] @@ -153,11 +153,11 @@ impl<'b> ByteCompiler<'b> { match value { 0 => self.emit_opcode(Opcode::PushZero), 1 => self.emit_opcode(Opcode::PushOne), - x if x as i8 as i32 == x => { + x if i32::from(x as i8) == x => { self.emit_opcode(Opcode::PushInt8); self.emit_u8(x as i8 as u8); } - x if x as i16 as i32 == x => { + x if i32::from(x as i16) == x => { self.emit_opcode(Opcode::PushInt16); self.emit_u16(x as i16 as u16); } @@ -180,14 +180,13 @@ impl<'b> ByteCompiler<'b> { if value.is_infinite() { if value.is_sign_positive() { return self.emit_opcode(Opcode::PushPositiveInfinity); - } else { - return self.emit_opcode(Opcode::PushNegativeInfinity); } + return self.emit_opcode(Opcode::PushNegativeInfinity); } // Check if the f64 value can fit in an i32. #[allow(clippy::float_cmp)] - if value as i32 as f64 == value { + if f64::from(value as i32) == value { self.emit_push_integer(value as i32); } else { self.emit_opcode(Opcode::PushRational); @@ -245,7 +244,7 @@ impl<'b> ByteCompiler<'b> { breaks: Vec::new(), try_continues: Vec::new(), for_of_in_loop: false, - }) + }); } #[inline] @@ -257,7 +256,7 @@ impl<'b> ByteCompiler<'b> { breaks: Vec::new(), try_continues: Vec::new(), for_of_in_loop: true, - }) + }); } #[inline] @@ -280,7 +279,7 @@ impl<'b> ByteCompiler<'b> { breaks: Vec::new(), try_continues: Vec::new(), for_of_in_loop: false, - }) + }); } #[inline] @@ -306,7 +305,7 @@ impl<'b> ByteCompiler<'b> { breaks: Vec::new(), try_continues: Vec::new(), for_of_in_loop: false, - }) + }); } } @@ -324,7 +323,7 @@ impl<'b> ByteCompiler<'b> { if label.index < finally_start_address { self.patch_jump_with_target(label, finally_start_address); } else { - self.patch_jump_with_target(label, info.start_address) + self.patch_jump_with_target(label, info.start_address); } } @@ -730,46 +729,18 @@ impl<'b> ByteCompiler<'b> { self.emit_opcode(Opcode::DefineOwnPropertyByValue); } }, - MethodDefinitionKind::Generator => { + MethodDefinitionKind::Generator + | MethodDefinitionKind::Async + | MethodDefinitionKind::AsyncGenerator => { // TODO: Implement generators - match name { - PropertyName::Literal(name) => { - self.emit_opcode(Opcode::PushUndefined); - self.emit_opcode(Opcode::Swap); - let index = self.get_or_insert_name(*name); - self.emit(Opcode::DefineOwnPropertyByName, &[index]); - } - PropertyName::Computed(name_node) => { - self.compile_stmt(name_node, true); - self.emit_opcode(Opcode::PushUndefined); - self.emit_opcode(Opcode::DefineOwnPropertyByValue); - } - } - } - MethodDefinitionKind::Async => { // TODO: Implement async - match name { - PropertyName::Literal(name) => { - self.emit_opcode(Opcode::PushUndefined); - self.emit_opcode(Opcode::Swap); - let index = self.get_or_insert_name(*name); - self.emit(Opcode::DefineOwnPropertyByName, &[index]) - } - PropertyName::Computed(name_node) => { - self.compile_stmt(name_node, true); - self.emit_opcode(Opcode::PushUndefined); - self.emit_opcode(Opcode::DefineOwnPropertyByValue); - } - } - } - MethodDefinitionKind::AsyncGenerator => { // TODO: Implement async generators match name { PropertyName::Literal(name) => { self.emit_opcode(Opcode::PushUndefined); self.emit_opcode(Opcode::Swap); let index = self.get_or_insert_name(*name); - self.emit(Opcode::DefineOwnPropertyByName, &[index]) + self.emit(Opcode::DefineOwnPropertyByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_stmt(name_node, true); @@ -853,8 +824,7 @@ impl<'b> ByteCompiler<'b> { Node::Spread(spread) => self.compile_expr(spread.val(), true), Node::FunctionExpr(_function) => self.function(expr, use_expr), Node::ArrowFunctionDecl(_function) => self.function(expr, use_expr), - Node::Call(_) => self.call(expr, use_expr), - Node::New(_) => self.call(expr, use_expr), + Node::Call(_) | Node::New(_) => self.call(expr, use_expr), Node::TemplateLit(template_literal) => { for element in template_literal.elements() { match element { @@ -877,23 +847,15 @@ impl<'b> ByteCompiler<'b> { } } // TODO: implement AsyncFunctionExpr - Node::AsyncFunctionExpr(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement AwaitExpr - Node::AwaitExpr(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement GeneratorExpr - Node::GeneratorExpr(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement AsyncGeneratorExpr - Node::AsyncGeneratorExpr(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement Yield - Node::Yield(_) => { + Node::AsyncFunctionExpr(_) + | Node::AwaitExpr(_) + | Node::GeneratorExpr(_) + | Node::AsyncGeneratorExpr(_) + | Node::Yield(_) => { self.emit_opcode(Opcode::PushUndefined); } Node::TaggedTemplate(template) => { @@ -1428,15 +1390,9 @@ impl<'b> ByteCompiler<'b> { } } // TODO: implement AsyncFunctionDecl - Node::AsyncFunctionDecl(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement GeneratorDecl - Node::GeneratorDecl(_) => { - self.emit_opcode(Opcode::PushUndefined); - } // TODO: implement AsyncGeneratorDecl - Node::AsyncGeneratorDecl(_) => { + Node::AsyncFunctionDecl(_) | Node::GeneratorDecl(_) | Node::AsyncGeneratorDecl(_) => { self.emit_opcode(Opcode::PushUndefined); } Node::Empty => {} @@ -1522,7 +1478,7 @@ impl<'b> ByteCompiler<'b> { } if has_parameter_expressions { - compiler.emit_opcode(Opcode::PushFunctionEnvironment) + compiler.emit_opcode(Opcode::PushFunctionEnvironment); } for node in body.items() { @@ -1600,11 +1556,11 @@ impl<'b> ByteCompiler<'b> { match kind { CallKind::Call if last_is_rest_parameter => { - self.emit(Opcode::CallWithRest, &[call.args().len() as u32]) + self.emit(Opcode::CallWithRest, &[call.args().len() as u32]); } CallKind::Call => self.emit(Opcode::Call, &[call.args().len() as u32]), CallKind::New if last_is_rest_parameter => { - self.emit(Opcode::NewWithRest, &[call.args().len() as u32]) + self.emit(Opcode::NewWithRest, &[call.args().len() as u32]); } CallKind::New => self.emit(Opcode::New, &[call.args().len() as u32]), } @@ -1635,7 +1591,9 @@ impl<'b> ByteCompiler<'b> { self.emit_opcode(Opcode::RequireObjectCoercible); for binding in pattern.bindings() { - use BindingPatternTypeObject::*; + use BindingPatternTypeObject::{ + BindingPattern, Empty, RestProperty, SingleName, + }; match binding { // ObjectBindingPattern : { } @@ -1710,7 +1668,10 @@ impl<'b> ByteCompiler<'b> { self.emit_opcode(Opcode::InitIterator); for (i, binding) in pattern.bindings().iter().enumerate() { - use BindingPatternTypeArray::*; + use BindingPatternTypeArray::{ + BindingPattern, BindingPatternRest, Elision, Empty, SingleName, + SingleNameRest, + }; let next = if i == pattern.bindings().len() - 1 { Opcode::IteratorNextFull @@ -1745,7 +1706,7 @@ impl<'b> ByteCompiler<'b> { // BindingElement : BindingPattern Initializer[opt] BindingPattern { pattern } => { self.emit_opcode(next); - self.compile_declaration_pattern(pattern, def) + self.compile_declaration_pattern(pattern, def); } // BindingRestElement : ... BindingIdentifier SingleNameRest { ident } => { diff --git a/boa/src/context.rs b/boa/src/context.rs index 61ddcf4efd..0f080b114e 100644 --- a/boa/src/context.rs +++ b/boa/src/context.rs @@ -397,7 +397,7 @@ impl Default for Context { console: Console::default(), iterator_prototypes: IteratorPrototypes::default(), typed_array_constructor: StandardConstructor::default(), - standard_objects: Default::default(), + standard_objects: StandardObjects::default(), intrinsic_objects: IntrinsicObjects::default(), strict: false, vm: Vm { @@ -761,7 +761,7 @@ impl Context { #[inline] pub fn register_global_closure(&mut self, name: &str, length: usize, body: F) -> JsResult<()> where - F: Fn(&JsValue, &[JsValue], &mut Context) -> JsResult + Copy + 'static, + F: Fn(&JsValue, &[JsValue], &mut Self) -> JsResult + Copy + 'static, { let function = FunctionBuilder::closure(self, body) .name(name) @@ -886,7 +886,7 @@ impl Context { where S: AsRef<[u8]>, { - let main_timer = BoaProfiler::global().start_event("Main", "Main"); + let main_timer = BoaProfiler::global().start_event("Evaluation", "Main"); let parsing_result = Parser::new(src.as_ref(), false) .parse_all(&mut self.interner) @@ -924,7 +924,7 @@ impl Context { /// `Gc` returned by the [`Self::compile()`] function. #[inline] pub fn execute(&mut self, code_block: Gc) -> JsResult { - let _ = BoaProfiler::global().start_event("Execute", "Main"); + let _ = BoaProfiler::global().start_event("Execution", "Main"); let global_object = self.global_object().into(); self.vm.push_frame(CallFrame { @@ -950,7 +950,7 @@ impl Context { &self.iterator_prototypes } - /// Return the cached TypedArray constructor. + /// Return the cached `TypedArray` constructor. #[inline] pub(crate) fn typed_array_constructor(&self) -> &StandardConstructor { &self.typed_array_constructor diff --git a/boa/src/environment/declarative_environment_record.rs b/boa/src/environment/declarative_environment_record.rs index 7b7589a79c..c8d1ffc77a 100644 --- a/boa/src/environment/declarative_environment_record.rs +++ b/boa/src/environment/declarative_environment_record.rs @@ -39,9 +39,9 @@ pub struct DeclarativeEnvironmentRecord { } impl DeclarativeEnvironmentRecord { - pub fn new(env: Option) -> DeclarativeEnvironmentRecord { + pub fn new(env: Option) -> Self { let _timer = BoaProfiler::global().start_event("new_declarative_environment", "env"); - DeclarativeEnvironmentRecord { + Self { env_rec: gc::Cell::new(FxHashMap::default()), outer_env: env, } @@ -337,7 +337,7 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { } impl From for Environment { - fn from(env: DeclarativeEnvironmentRecord) -> Environment { + fn from(env: DeclarativeEnvironmentRecord) -> Self { Gc::new(Box::new(env)) } } diff --git a/boa/src/environment/environment_record_trait.rs b/boa/src/environment/environment_record_trait.rs index 24de3fe82c..4270a23624 100644 --- a/boa/src/environment/environment_record_trait.rs +++ b/boa/src/environment/environment_record_trait.rs @@ -60,9 +60,11 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn initialize_binding(&self, name: Sym, value: JsValue, context: &mut Context) -> JsResult<()>; /// Set the value of an already existing mutable binding in an Environment Record. + /// /// The String value `name` is the text of the bound name. - /// value is the `value` for the binding and may be a value of any ECMAScript language type. S is a Boolean flag. - /// If `strict` is true and the binding cannot be set throw a TypeError exception. + /// value is the `value` for the binding and may be a value of any ECMAScript language type. + /// `S` is a `Boolean` flag. If `strict` is true and the binding cannot be set throw a + /// `TypeError` exception. fn set_mutable_binding( &self, name: Sym, diff --git a/boa/src/environment/function_environment_record.rs b/boa/src/environment/function_environment_record.rs index c7a2c2ed99..2da7869836 100644 --- a/boa/src/environment/function_environment_record.rs +++ b/boa/src/environment/function_environment_record.rs @@ -64,8 +64,8 @@ impl FunctionEnvironmentRecord { binding_status: BindingStatus, new_target: JsValue, context: &mut Context, - ) -> JsResult { - let mut func_env = FunctionEnvironmentRecord { + ) -> JsResult { + let mut func_env = Self { declarative_record: DeclarativeEnvironmentRecord::new(outer), // the outer environment will come from Environment set as a private property of F - https://tc39.es/ecma262/#sec-ecmascript-function-objects function: f, this_binding_status: binding_status, @@ -247,7 +247,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { } fn set_outer_environment(&mut self, env: Environment) { - self.declarative_record.set_outer_environment(env) + self.declarative_record.set_outer_environment(env); } fn get_environment_type(&self) -> EnvironmentType { @@ -276,7 +276,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { } impl From for Environment { - fn from(env: FunctionEnvironmentRecord) -> Environment { + fn from(env: FunctionEnvironmentRecord) -> Self { Gc::new(Box::new(env)) } } diff --git a/boa/src/environment/global_environment_record.rs b/boa/src/environment/global_environment_record.rs index 41fa693d0c..3bdd958ba7 100644 --- a/boa/src/environment/global_environment_record.rs +++ b/boa/src/environment/global_environment_record.rs @@ -31,7 +31,7 @@ pub struct GlobalEnvironmentRecord { } impl GlobalEnvironmentRecord { - pub fn new(global: JsObject, this_value: JsObject) -> GlobalEnvironmentRecord { + pub fn new(global: JsObject, this_value: JsObject) -> Self { let obj_rec = ObjectEnvironmentRecord { bindings: global, outer_env: None, @@ -45,7 +45,7 @@ impl GlobalEnvironmentRecord { let dcl_rec = DeclarativeEnvironmentRecord::new(None); - GlobalEnvironmentRecord { + Self { object_record: obj_rec, global_this_binding: this_value, declarative_record: dcl_rec, @@ -236,10 +236,7 @@ impl GlobalEnvironmentRecord { .__get_own_property__(&context.interner().resolve_expect(name).into(), context)?; // 4. If existingProp is undefined or existingProp.[[Configurable]] is true, then - let desc = if existing_prop - .map(|f| f.expect_configurable()) - .unwrap_or(true) - { + let desc = if existing_prop.map_or(true, |f| f.expect_configurable()) { // a. Let desc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }. PropertyDescriptor::builder() .value(value.clone()) @@ -568,7 +565,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { } impl From for Environment { - fn from(env: GlobalEnvironmentRecord) -> Environment { + fn from(env: GlobalEnvironmentRecord) -> Self { Gc::new(Box::new(env)) } } diff --git a/boa/src/environment/object_environment_record.rs b/boa/src/environment/object_environment_record.rs index 55a85251bd..6aa276ed8e 100644 --- a/boa/src/environment/object_environment_record.rs +++ b/boa/src/environment/object_environment_record.rs @@ -27,8 +27,8 @@ pub struct ObjectEnvironmentRecord { } impl ObjectEnvironmentRecord { - pub fn new(object: JsObject, environment: Option) -> ObjectEnvironmentRecord { - ObjectEnvironmentRecord { + pub fn new(object: JsObject, environment: Option) -> Self { + Self { bindings: object, outer_env: environment, /// Object Environment Records created for with statements (13.11) @@ -194,12 +194,11 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { // a. If S is false, return the value undefined; otherwise throw a ReferenceError exception. if !strict { return Ok(JsValue::undefined()); - } else { - return context.throw_reference_error(format!( - "{} has no binding", - context.interner().resolve_expect(name) - )); } + return context.throw_reference_error(format!( + "{} has no binding", + context.interner().resolve_expect(name) + )); } // 4. Return ? Get(bindingObject, N). @@ -276,7 +275,7 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { } impl From for Environment { - fn from(env: ObjectEnvironmentRecord) -> Environment { + fn from(env: ObjectEnvironmentRecord) -> Self { Gc::new(Box::new(env)) } } diff --git a/boa/src/lib.rs b/boa/src/lib.rs index 7113c8673e..b0612d2695 100644 --- a/boa/src/lib.rs +++ b/boa/src/lib.rs @@ -10,8 +10,27 @@ html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" )] +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic +)] #![deny( clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -28,8 +47,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, diff --git a/boa/src/object/internal_methods/arguments.rs b/boa/src/object/internal_methods/arguments.rs index 994fb8a72f..46fac77f4e 100644 --- a/boa/src/object/internal_methods/arguments.rs +++ b/boa/src/object/internal_methods/arguments.rs @@ -70,6 +70,7 @@ pub(crate) fn arguments_exotic_get_own_property( /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc +#[allow(clippy::needless_pass_by_value)] pub(crate) fn arguments_exotic_define_own_property( obj: &JsObject, key: PropertyKey, @@ -130,7 +131,7 @@ pub(crate) fn arguments_exotic_define_own_property( let set_status = map.set(key.clone(), value, false, context); // 2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable. - assert_eq!(set_status, Ok(true)) + assert_eq!(set_status, Ok(true)); } // ii. If Desc.[[Writable]] is present and its value is false, then diff --git a/boa/src/object/internal_methods/array.rs b/boa/src/object/internal_methods/array.rs index 0002949ab4..bc87c6e013 100644 --- a/boa/src/object/internal_methods/array.rs +++ b/boa/src/object/internal_methods/array.rs @@ -61,7 +61,7 @@ pub(crate) fn array_exotic_define_own_property( // 5. If SameValueZero(newLen, numberLen) is false, throw a RangeError exception. #[allow(clippy::float_cmp)] - if new_len as f64 != number_len { + if f64::from(new_len) != number_len { return context.throw_range_error("bad length for array"); } diff --git a/boa/src/object/internal_methods/integer_indexed.rs b/boa/src/object/internal_methods/integer_indexed.rs index a86f86da02..d1ef9913aa 100644 --- a/boa/src/object/internal_methods/integer_indexed.rs +++ b/boa/src/object/internal_methods/integer_indexed.rs @@ -25,7 +25,7 @@ pub(crate) static INTEGER_INDEXED_EXOTIC_INTERNAL_METHODS: InternalObjectMethods ..ORDINARY_INTERNAL_METHODS }; -/// InternalMethod `[[GetOwnProperty]]` for Integer-Indexed exotic objects. +/// `[[GetOwnProperty]]` internal method for Integer-Indexed exotic objects. /// /// More information: /// - [ECMAScript reference][spec] @@ -58,7 +58,7 @@ pub(crate) fn integer_indexed_exotic_get_own_property( } } -/// InternalMethod `[[HasProperty]]` for Integer-Indexed exotic objects. +/// `[[HasProperty]]` internal method for Integer-Indexed exotic objects. /// /// More information: /// - [ECMAScript reference][spec] @@ -81,7 +81,7 @@ pub(crate) fn integer_indexed_exotic_has_property( } } -/// InternalMethod `[[DefineOwnProperty]]` for Integer-Indexed exotic objects. +/// `[[DefineOwnProperty]]` internal method for Integer-Indexed exotic objects. /// /// More information: /// - [ECMAScript reference][spec] @@ -116,7 +116,7 @@ pub(crate) fn integer_indexed_exotic_define_own_property( // vi. If Desc has a [[Value]] field, perform ? IntegerIndexedElementSet(O, numericIndex, Desc.[[Value]]). if let Some(value) = desc.value() { - integer_indexed_element_set(obj, index as usize, value, context)? + integer_indexed_element_set(obj, index as usize, value, context)?; } // vii. Return true. @@ -212,6 +212,7 @@ pub(crate) fn integer_indexed_exotic_delete( /// /// [spec]: https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-ownpropertykeys #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn integer_indexed_exotic_own_property_keys( obj: &JsObject, _context: &mut Context, @@ -240,7 +241,7 @@ pub(crate) fn integer_indexed_exotic_own_property_keys( obj.properties .string_property_keys() .cloned() - .map(|s| s.into()), + .map(Into::into), ); // 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do @@ -249,7 +250,7 @@ pub(crate) fn integer_indexed_exotic_own_property_keys( obj.properties .symbol_property_keys() .cloned() - .map(|sym| sym.into()), + .map(Into::into), ); // 5. Return keys. @@ -375,7 +376,7 @@ fn integer_indexed_element_set( .set_value_in_buffer( indexed_position, elem_type, - num_value, + &num_value, SharedMemoryOrder::Unordered, None, context, diff --git a/boa/src/object/internal_methods/mod.rs b/boa/src/object/internal_methods/mod.rs index 0704ebd832..003b65c348 100644 --- a/boa/src/object/internal_methods/mod.rs +++ b/boa/src/object/internal_methods/mod.rs @@ -333,6 +333,7 @@ pub(crate) struct InternalObjectMethods { /// /// [spec]: https://tc39.es/ecma262/#sec-ordinarygetprototypeof #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_get_prototype_of( obj: &JsObject, _context: &mut Context, @@ -350,6 +351,7 @@ pub(crate) fn ordinary_get_prototype_of( /// /// [spec]: https://tc39.es/ecma262/#sec-ordinarysetprototypeof #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_set_prototype_of( obj: &JsObject, val: JsPrototype, @@ -392,9 +394,7 @@ pub(crate) fn ordinary_set_prototype_of( break; } // ii. Else, set p to p.[[Prototype]]. - else { - p = proto.prototype().clone(); - } + p = proto.prototype().clone(); } // 9. Set O.[[Prototype]] to V. @@ -411,18 +411,20 @@ pub(crate) fn ordinary_set_prototype_of( /// /// [spec]: https://tc39.es/ecma262/#sec-ordinaryisextensible #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_is_extensible(obj: &JsObject, _context: &mut Context) -> JsResult { // 1. Return O.[[Extensible]]. Ok(obj.borrow().extensible) } -/// Abstract operation `OrdinaryPreventExtensions. +/// Abstract operation `OrdinaryPreventExtensions`. /// /// More information: /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-ordinarypreventextensions #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_prevent_extensions( obj: &JsObject, _context: &mut Context, @@ -441,6 +443,7 @@ pub(crate) fn ordinary_prevent_extensions( /// /// [spec]: https://tc39.es/ecma262/#sec-ordinarygetownproperty #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_get_own_property( obj: &JsObject, key: &PropertyKey, @@ -519,9 +522,8 @@ pub(crate) fn ordinary_has_property( parent // 5. If parent is not null, then // a. Return ? parent.[[HasProperty]](P). - .map(|obj| obj.__has_property__(key, context)) // 6. Return false. - .unwrap_or(Ok(false)) + .map_or(Ok(false), |obj| obj.__has_property__(key, context)) } } @@ -652,11 +654,9 @@ pub(crate) fn ordinary_set( ); } // e. Else - else { - // i. Assert: Receiver does not currently have a property P. - // ii. Return ? CreateDataProperty(Receiver, P, V). - return receiver.create_data_property(key, value, context); - } + // i. Assert: Receiver does not currently have a property P. + // ii. Return ? CreateDataProperty(Receiver, P, V). + return receiver.create_data_property(key, value, context); } // 4. Assert: IsAccessorDescriptor(ownDesc) is true. @@ -715,6 +715,7 @@ pub(crate) fn ordinary_delete( /// /// [spec]: https://tc39.es/ecma262/#sec-ordinaryownpropertykeys #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn ordinary_own_property_keys( obj: &JsObject, _context: &mut Context, @@ -736,7 +737,7 @@ pub(crate) fn ordinary_own_property_keys( // 2. For each own property key P of O such that P is an array index, in ascending numeric index order, do // a. Add P as the last element of keys. - keys.extend(ordered_indexes.into_iter().map(|idx| idx.into())); + keys.extend(ordered_indexes.into_iter().map(Into::into)); // 3. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do // a. Add P as the last element of keys. @@ -745,7 +746,7 @@ pub(crate) fn ordinary_own_property_keys( .properties .string_property_keys() .cloned() - .map(|s| s.into()), + .map(Into::into), ); // 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do @@ -755,7 +756,7 @@ pub(crate) fn ordinary_own_property_keys( .properties .symbol_property_keys() .cloned() - .map(|sym| sym.into()), + .map(Into::into), ); // 5. Return keys. @@ -812,7 +813,7 @@ pub(crate) fn validate_and_apply_property_descriptor( if let Some((obj, key)) = obj_and_key { obj.borrow_mut().properties.insert( - key, + &key, // c. If IsGenericDescriptor(Desc) is true or IsDataDescriptor(Desc) is true, then if desc.is_generic_descriptor() || desc.is_data_descriptor() { // i. If O is not undefined, create an own data property named P of @@ -928,8 +929,8 @@ pub(crate) fn validate_and_apply_property_descriptor( if let Some((obj, key)) = obj_and_key { // a. For each field of Desc that is present, set the corresponding attribute of the // property named P of object O to the value of the field. - current.fill_with(desc); - obj.borrow_mut().properties.insert(key, current); + current.fill_with(&desc); + obj.borrow_mut().properties.insert(&key, current); } // 10. Return true. diff --git a/boa/src/object/internal_methods/proxy.rs b/boa/src/object/internal_methods/proxy.rs index 633c41f53a..5b5be57dbf 100644 --- a/boa/src/object/internal_methods/proxy.rs +++ b/boa/src/object/internal_methods/proxy.rs @@ -159,7 +159,7 @@ pub(crate) fn proxy_exotic_set_prototype_of( &handler.into(), &[ target.clone().into(), - val.clone().map_or(JsValue::Null, |obj| obj.into()), + val.clone().map_or(JsValue::Null, Into::into), ], context, )? @@ -338,14 +338,13 @@ pub(crate) fn proxy_exotic_get_own_property( return context.throw_type_error( "Proxy trap result is undefined and target is not extensible", ); - // e. Return undefined. - } else { - return Ok(None); } - } else { - // a. If targetDesc is undefined, return undefined. + // e. Return undefined. return Ok(None); } + + // a. If targetDesc is undefined, return undefined. + return Ok(None); } // 11. Let extensibleTarget be ? IsExtensible(target). @@ -829,7 +828,7 @@ pub(crate) fn proxy_exotic_own_property_keys( "Proxy trap result contains duplicate string property keys", ); } - trap_result.push(s.clone().into()) + trap_result.push(s.clone().into()); } JsValue::Symbol(s) => { if !unchecked_result_keys.insert(s.clone().into()) { @@ -837,7 +836,7 @@ pub(crate) fn proxy_exotic_own_property_keys( "Proxy trap result contains duplicate symbol property keys", ); } - trap_result.push(s.clone().into()) + trap_result.push(s.clone().into()); } _ => {} } diff --git a/boa/src/object/internal_methods/string.rs b/boa/src/object/internal_methods/string.rs index ed65f14964..453b90d586 100644 --- a/boa/src/object/internal_methods/string.rs +++ b/boa/src/object/internal_methods/string.rs @@ -84,6 +84,7 @@ pub(crate) fn string_exotic_define_own_property( /// /// [spec]: https://tc39.es/ecma262/#sec-string-exotic-objects-ownpropertykeys #[inline] +#[allow(clippy::unnecessary_wraps)] pub(crate) fn string_exotic_own_property_keys( obj: &JsObject, _context: &mut Context, @@ -103,7 +104,7 @@ pub(crate) fn string_exotic_own_property_keys( // 5. For each integer i starting with 0 such that i < len, in ascending order, do // a. Add ! ToString(𝔽(i)) as the last element of keys. - keys.extend((0..len).into_iter().map(|idx| idx.into())); + keys.extend((0..len).into_iter().map(Into::into)); // 6. For each own property key P of O such that P is an array index // and ! ToIntegerOrInfinity(P) ≥ len, in ascending numeric index order, do @@ -111,11 +112,11 @@ pub(crate) fn string_exotic_own_property_keys( let mut remaining_indices: Vec<_> = obj .properties .index_property_keys() - .cloned() + .copied() .filter(|idx| (*idx as usize) >= len) .collect(); remaining_indices.sort_unstable(); - keys.extend(remaining_indices.into_iter().map(|idx| idx.into())); + keys.extend(remaining_indices.into_iter().map(Into::into)); // 7. For each own property key P of O such that Type(P) is String and P is not // an array index, in ascending chronological order of property creation, do @@ -124,7 +125,7 @@ pub(crate) fn string_exotic_own_property_keys( obj.properties .string_property_keys() .cloned() - .map(|s| s.into()), + .map(Into::into), ); // 8. For each own property key P of O such that Type(P) is Symbol, in ascending @@ -134,14 +135,14 @@ pub(crate) fn string_exotic_own_property_keys( obj.properties .symbol_property_keys() .cloned() - .map(|sym| sym.into()), + .map(Into::into), ); // 9. Return keys. Ok(keys) } -/// StringGetOwnProperty abstract operation +/// `StringGetOwnProperty` abstract operation /// /// More information: /// - [ECMAScript reference][spec] diff --git a/boa/src/object/jsobject.rs b/boa/src/object/jsobject.rs index 31d5e860e7..e88c2d9744 100644 --- a/boa/src/object/jsobject.rs +++ b/boa/src/object/jsobject.rs @@ -2,7 +2,7 @@ //! //! The `JsObject` is a garbage collected Object. -use super::{JsPrototype, NativeObject, Object}; +use super::{JsPrototype, NativeObject, Object, PropertyMap}; use crate::{ gc::{self, Finalize, Gc, Trace}, object::{ObjectData, ObjectKind}, @@ -46,12 +46,12 @@ impl JsObject { /// Create a `JsObject` and automatically set its internal methods and /// internal slots from the `data` provided. #[inline] - pub fn from_proto_and_data>>(prototype: O, data: ObjectData) -> Self { + pub fn from_proto_and_data>>(prototype: O, data: ObjectData) -> Self { Self::from_object(Object { data, prototype: prototype.into(), extensible: true, - properties: Default::default(), + properties: PropertyMap::default(), }) } @@ -245,7 +245,7 @@ impl JsObject { #[inline] #[track_caller] pub fn prototype(&self) -> Ref<'_, JsPrototype> { - Ref::map(self.borrow(), |obj| obj.prototype()) + Ref::map(self.borrow(), Object::prototype) } /// Get the extensibility of the object. @@ -549,7 +549,7 @@ Cannot both specify accessors and a value or writable attribute", // 5. Let keys be ? from.[[OwnPropertyKeys]](). // 6. For each element nextKey of keys, do - let excluded_keys: Vec = excluded_keys.into_iter().map(|e| e.into()).collect(); + let excluded_keys: Vec = excluded_keys.into_iter().map(Into::into).collect(); for key in from.__own_property_keys__(context)? { // a. Let excluded be false. let mut excluded = false; @@ -617,7 +617,7 @@ Cannot both specify accessors and a value or writable attribute", /// It determines if Object is a callable function with a `[[Call]]` internal method. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-iscallable #[inline] @@ -629,7 +629,7 @@ Cannot both specify accessors and a value or writable attribute", /// It determines if Object is a function object with a `[[Construct]]` internal method. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-isconstructor #[inline] @@ -638,7 +638,7 @@ Cannot both specify accessors and a value or writable attribute", self.borrow().data.internal_methods.__construct__.is_some() } - /// Returns true if the JsObject is the global for a Realm + /// Returns true if the `JsObject` is the global for a Realm pub fn is_global(&self) -> bool { matches!( self.borrow().data, @@ -659,7 +659,7 @@ impl AsRef> for JsObject { impl PartialEq for JsObject { fn eq(&self, other: &Self) -> bool { - JsObject::equals(self, other) + Self::equals(self, other) } } diff --git a/boa/src/object/mod.rs b/boa/src/object/mod.rs index a0281b7c0c..0d9dcb9f33 100644 --- a/boa/src/object/mod.rs +++ b/boa/src/object/mod.rs @@ -416,7 +416,7 @@ impl Debug for ObjectData { } impl Default for Object { - /// Return a new ObjectData struct, with `kind` set to Ordinary + /// Return a new `ObjectData` struct, with `kind` set to Ordinary #[inline] fn default() -> Self { Self { @@ -1144,7 +1144,7 @@ impl Object { K: Into, P: Into, { - self.properties.insert(key.into(), property.into()) + self.properties.insert(&key.into(), property.into()) } /// Helper function for property removal. @@ -1339,8 +1339,9 @@ impl<'context> FunctionBuilder<'context> { #[inline] pub fn constructor(&mut self, yes: bool) -> &mut Self { match self.function.as_mut() { - Some(Function::Native { constructor, .. }) => *constructor = yes, - Some(Function::Closure { constructor, .. }) => *constructor = yes, + Some(Function::Native { constructor, .. } | Function::Closure { constructor, .. }) => { + *constructor = yes; + } _ => unreachable!(), } self diff --git a/boa/src/object/operations.rs b/boa/src/object/operations.rs index 2a2b2c0a99..e0bbb72245 100644 --- a/boa/src/object/operations.rs +++ b/boa/src/object/operations.rs @@ -189,7 +189,7 @@ impl JsObject { /// Defines the property or throws a `TypeError` if the operation fails. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-definepropertyorthrow #[inline] @@ -421,9 +421,10 @@ impl JsObject { /// `7.3.22 SpeciesConstructor ( O, defaultConstructor )` /// - /// The abstract operation SpeciesConstructor takes arguments O (an Object) and defaultConstructor (a constructor). - /// It is used to retrieve the constructor that should be used to create new objects that are derived from O. - /// defaultConstructor is the constructor to use if a constructor @@species property cannot be found starting from O. + /// The abstract operation `SpeciesConstructor` takes arguments `O` (an Object) and + /// `defaultConstructor` (a constructor). It is used to retrieve the constructor that should be + /// used to create new objects that are derived from `O`. `defaultConstructor` is the + /// constructor to use if a constructor `@@species` property cannot be found starting from `O`. /// /// More information: /// - [ECMAScript reference][spec] @@ -433,7 +434,7 @@ impl JsObject { &self, default_constructor: F, context: &mut Context, - ) -> JsResult + ) -> JsResult where F: FnOnce(&StandardObjects) -> &StandardConstructor, { @@ -471,7 +472,7 @@ impl JsObject { /// It is used to iterate over names of object's keys. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-enumerableownpropertynames pub(crate) fn enumerable_own_property_names( @@ -491,7 +492,7 @@ impl JsObject { let key_str = match &key { PropertyKey::String(s) => Some(s.clone()), PropertyKey::Index(i) => Some(i.to_string().into()), - _ => None, + PropertyKey::Symbol(_) => None, }; if let Some(key_str) = key_str { @@ -507,7 +508,7 @@ impl JsObject { // a. Let value be ? Get(O, key). // b. If kind is value, append value to properties. PropertyNameKind::Value => { - properties.push(self.get(key.clone(), context)?) + properties.push(self.get(key.clone(), context)?); } // c. Else, // i. Assert: kind is key+value. @@ -535,10 +536,10 @@ impl JsObject { /// Retrieves the value of a specific property, when the value of the property is expected to be a function. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-getmethod - pub(crate) fn get_method(&self, key: K, context: &mut Context) -> JsResult> + pub(crate) fn get_method(&self, key: K, context: &mut Context) -> JsResult> where K: Into, { @@ -618,11 +619,11 @@ impl JsValue { /// type of the value. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-getmethod #[inline] - pub(crate) fn get_v(&self, key: K, context: &mut Context) -> JsResult + pub(crate) fn get_v(&self, key: K, context: &mut Context) -> JsResult where K: Into, { @@ -638,7 +639,7 @@ impl JsValue { /// Retrieves the value of a specific property, when the value of the property is expected to be a function. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-getmethod #[inline] @@ -655,14 +656,14 @@ impl JsValue { /// self. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-createlistfromarraylike pub(crate) fn create_list_from_array_like( &self, element_types: &[Type], context: &mut Context, - ) -> JsResult> { + ) -> JsResult> { // 1. If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ». let types = if element_types.is_empty() { &[ @@ -709,20 +710,15 @@ impl JsValue { Ok(list) } - /// Abstract operation `( V, P [ , argumentsList ] ) + /// Abstract operation `( V, P [ , argumentsList ] )` /// /// Calls a method property of an ECMAScript language value. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-invoke - pub(crate) fn invoke( - &self, - key: K, - args: &[JsValue], - context: &mut Context, - ) -> JsResult + pub(crate) fn invoke(&self, key: K, args: &[Self], context: &mut Context) -> JsResult where K: Into, { @@ -737,12 +733,12 @@ impl JsValue { /// Abstract operation `OrdinaryHasInstance ( C, O )` /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-ordinaryhasinstance pub fn ordinary_has_instance( - function: &JsValue, - object: &JsValue, + function: &Self, + object: &Self, context: &mut Context, ) -> JsResult { // 1. If IsCallable(C) is false, return false. @@ -756,7 +752,7 @@ impl JsValue { if let Some(bound_function) = function.borrow().as_bound_function() { // a. Let BC be C.[[BoundTargetFunction]]. // b. Return ? InstanceofOperator(O, BC). - return JsValue::instance_of( + return Self::instance_of( object, &bound_function.target_function().clone().into(), context, diff --git a/boa/src/object/property_map.rs b/boa/src/object/property_map.rs index 4f5c98686d..d3d5257dc7 100644 --- a/boa/src/object/property_map.rs +++ b/boa/src/object/property_map.rs @@ -7,7 +7,7 @@ use indexmap::IndexMap; use rustc_hash::{FxHashMap, FxHasher}; use std::{collections::hash_map, hash::BuildHasherDefault, iter::FusedIterator}; -/// Wrapper around indexmap::IndexMap for usage in PropertyMap +/// Wrapper around `indexmap::IndexMap` for usage in `PropertyMap`. #[derive(Debug, Finalize)] struct OrderedHashMap(IndexMap>); @@ -49,7 +49,7 @@ impl PropertyMap { pub fn insert( &mut self, - key: PropertyKey, + key: &PropertyKey, property: PropertyDescriptor, ) -> Option { match &key { diff --git a/boa/src/profiler.rs b/boa/src/profiler.rs index 8458c70e52..a58dc0b69f 100644 --- a/boa/src/profiler.rs +++ b/boa/src/profiler.rs @@ -70,18 +70,14 @@ impl Debug for BoaProfiler { #[cfg(not(feature = "profiler"))] pub struct BoaProfiler; -#[allow(clippy::unused_unit)] +#[allow(clippy::unused_unit, clippy::unused_self)] #[cfg(not(feature = "profiler"))] impl BoaProfiler { - pub fn start_event(&self, _label: &str, _category: &str) -> () { - () - } + pub fn start_event(&self, _label: &str, _category: &str) -> () {} - pub fn drop(&self) { - () - } + pub fn drop(&self) {} - pub fn global() -> BoaProfiler { - BoaProfiler + pub fn global() -> Self { + Self } } diff --git a/boa/src/property/mod.rs b/boa/src/property/mod.rs index c591ac0177..1333d9e24d 100644 --- a/boa/src/property/mod.rs +++ b/boa/src/property/mod.rs @@ -1,10 +1,11 @@ //! This module implements the Property Descriptor. //! -//! The Property Descriptor type is used to explain the manipulation and reification of Object property attributes. -//! Values of the Property Descriptor type are Records. Each field's name is an attribute name -//! and its value is a corresponding attribute value as specified in [6.1.7.1][section]. -//! In addition, any field may be present or absent. -//! The schema name used within this specification to tag literal descriptions of Property Descriptor records is “PropertyDescriptor”. +//! The Property Descriptor type is used to explain the manipulation and reification of `Object` +//! property attributes. Values of the Property Descriptor type are Records. Each field's name is +//! an attribute name and its value is a corresponding attribute value as specified in +//! [6.1.7.1][section]. In addition, any field may be present or absent. The schema name used +//! within this specification to tag literal descriptions of Property Descriptor records is +//! `PropertyDescriptor`. //! //! More information: //! - [MDN documentation][mdn] @@ -245,7 +246,7 @@ impl PropertyDescriptor { } #[inline] - pub fn fill_with(&mut self, desc: Self) { + pub fn fill_with(&mut self, desc: &Self) { match (&mut self.kind, &desc.kind) { ( DescriptorKind::Data { value, writable }, @@ -255,10 +256,10 @@ impl PropertyDescriptor { }, ) => { if let Some(desc_value) = desc_value { - *value = Some(desc_value.clone()) + *value = Some(desc_value.clone()); } if let Some(desc_writable) = desc_writable { - *writable = Some(*desc_writable) + *writable = Some(*desc_writable); } } ( @@ -269,10 +270,10 @@ impl PropertyDescriptor { }, ) => { if let Some(desc_get) = desc_get { - *get = Some(desc_get.clone()) + *get = Some(desc_get.clone()); } if let Some(desc_set) = desc_set { - *set = Some(desc_set.clone()) + *set = Some(desc_set.clone()); } } (_, DescriptorKind::Generic) => {} @@ -280,10 +281,10 @@ impl PropertyDescriptor { } if let Some(enumerable) = desc.enumerable { - self.enumerable = Some(enumerable) + self.enumerable = Some(enumerable); } if let Some(configurable) = desc.configurable { - self.configurable = Some(configurable) + self.configurable = Some(configurable); } } } @@ -423,10 +424,10 @@ impl PropertyDescriptorBuilder { ref mut writable, } => { if value.is_none() { - *value = Some(JsValue::undefined()) + *value = Some(JsValue::undefined()); } if writable.is_none() { - *writable = Some(false) + *writable = Some(false); } } DescriptorKind::Accessor { @@ -434,10 +435,10 @@ impl PropertyDescriptorBuilder { ref mut get, } => { if set.is_none() { - *set = Some(JsValue::undefined()) + *set = Some(JsValue::undefined()); } if get.is_none() { - *get = Some(JsValue::undefined()) + *get = Some(JsValue::undefined()); } } } @@ -465,7 +466,7 @@ impl From for PropertyDescriptor { } } -/// This abstracts away the need for IsPropertyKey by transforming the PropertyKey +/// This abstracts away the need for `IsPropertyKey` by transforming the `PropertyKey` /// values into an enum with both valid types: String and Symbol /// /// More information: @@ -481,52 +482,52 @@ pub enum PropertyKey { impl From for PropertyKey { #[inline] - fn from(string: JsString) -> PropertyKey { + fn from(string: JsString) -> Self { if let Ok(index) = string.parse() { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(string) + Self::String(string) } } } impl From<&str> for PropertyKey { #[inline] - fn from(string: &str) -> PropertyKey { + fn from(string: &str) -> Self { if let Ok(index) = string.parse() { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(string.into()) + Self::String(string.into()) } } } impl From for PropertyKey { #[inline] - fn from(string: String) -> PropertyKey { + fn from(string: String) -> Self { if let Ok(index) = string.parse() { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(string.into()) + Self::String(string.into()) } } } impl From> for PropertyKey { #[inline] - fn from(string: Box) -> PropertyKey { + fn from(string: Box) -> Self { if let Ok(index) = string.parse() { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(string.into()) + Self::String(string.into()) } } } impl From for PropertyKey { #[inline] - fn from(symbol: JsSymbol) -> PropertyKey { - PropertyKey::Symbol(symbol) + fn from(symbol: JsSymbol) -> Self { + Self::Symbol(symbol) } } @@ -534,24 +535,24 @@ impl fmt::Display for PropertyKey { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - PropertyKey::String(ref string) => string.fmt(f), - PropertyKey::Symbol(ref symbol) => symbol.fmt(f), - PropertyKey::Index(index) => index.fmt(f), + Self::String(ref string) => string.fmt(f), + Self::Symbol(ref symbol) => symbol.fmt(f), + Self::Index(index) => index.fmt(f), } } } impl From<&PropertyKey> for JsValue { #[inline] - fn from(property_key: &PropertyKey) -> JsValue { + fn from(property_key: &PropertyKey) -> Self { match property_key { PropertyKey::String(ref string) => string.clone().into(), PropertyKey::Symbol(ref symbol) => symbol.clone().into(), PropertyKey::Index(index) => { if let Ok(integer) = i32::try_from(*index) { - JsValue::new(integer) + Self::new(integer) } else { - JsValue::new(*index) + Self::new(*index) } } } @@ -560,15 +561,15 @@ impl From<&PropertyKey> for JsValue { impl From for JsValue { #[inline] - fn from(property_key: PropertyKey) -> JsValue { + fn from(property_key: PropertyKey) -> Self { match property_key { PropertyKey::String(ref string) => string.clone().into(), PropertyKey::Symbol(ref symbol) => symbol.clone().into(), PropertyKey::Index(index) => { if let Ok(integer) = i32::try_from(index) { - JsValue::new(integer) + Self::new(integer) } else { - JsValue::new(index) + Self::new(index) } } } @@ -577,28 +578,28 @@ impl From for JsValue { impl From for PropertyKey { fn from(value: u8) -> Self { - PropertyKey::Index(value.into()) + Self::Index(value.into()) } } impl From for PropertyKey { fn from(value: u16) -> Self { - PropertyKey::Index(value.into()) + Self::Index(value.into()) } } impl From for PropertyKey { fn from(value: u32) -> Self { - PropertyKey::Index(value) + Self::Index(value) } } impl From for PropertyKey { fn from(value: usize) -> Self { if let Ok(index) = u32::try_from(value) { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(JsString::from(value.to_string())) + Self::String(JsString::from(value.to_string())) } } } @@ -606,9 +607,9 @@ impl From for PropertyKey { impl From for PropertyKey { fn from(value: i64) -> Self { if let Ok(index) = u32::try_from(value) { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(JsString::from(value.to_string())) + Self::String(JsString::from(value.to_string())) } } } @@ -616,9 +617,9 @@ impl From for PropertyKey { impl From for PropertyKey { fn from(value: u64) -> Self { if let Ok(index) = u32::try_from(value) { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(JsString::from(value.to_string())) + Self::String(JsString::from(value.to_string())) } } } @@ -626,9 +627,9 @@ impl From for PropertyKey { impl From for PropertyKey { fn from(value: isize) -> Self { if let Ok(index) = u32::try_from(value) { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(JsString::from(value.to_string())) + Self::String(JsString::from(value.to_string())) } } } @@ -636,9 +637,9 @@ impl From for PropertyKey { impl From for PropertyKey { fn from(value: i32) -> Self { if let Ok(index) = u32::try_from(value) { - PropertyKey::Index(index) + Self::Index(index) } else { - PropertyKey::String(JsString::from(value.to_string())) + Self::String(JsString::from(value.to_string())) } } } @@ -647,17 +648,17 @@ impl From for PropertyKey { fn from(value: f64) -> Self { use num_traits::cast::FromPrimitive; if let Some(index) = u32::from_f64(value) { - return PropertyKey::Index(index); + return Self::Index(index); } - PropertyKey::String(ryu_js::Buffer::new().format(value).into()) + Self::String(ryu_js::Buffer::new().format(value).into()) } } impl PartialEq<&str> for PropertyKey { fn eq(&self, other: &&str) -> bool { match self { - PropertyKey::String(ref string) => string == other, + Self::String(ref string) => string == other, _ => false, } } diff --git a/boa/src/string.rs b/boa/src/string.rs index 2eaf9be8c5..7ba12bffb5 100644 --- a/boa/src/string.rs +++ b/boa/src/string.rs @@ -211,16 +211,16 @@ impl Inner { fn new(s: &str) -> NonNull { // We get the layout of the `Inner` type and we extend by the size // of the string array. - let inner_layout = Layout::new::(); + let inner_layout = Layout::new::(); let (layout, offset) = inner_layout .extend(Layout::array::(s.len()).unwrap()) .unwrap(); let inner = unsafe { - let inner = alloc(layout) as *mut Inner; + let inner = alloc(layout).cast::(); // Write the first part, the Inner. - inner.write(Inner { + inner.write(Self { len: s.len(), refcount: Cell::new(1), data: [0; 0], @@ -243,7 +243,7 @@ impl Inner { /// Concatenate array of strings. #[inline] - fn concat_array(strings: &[&str]) -> NonNull { + fn concat_array(strings: &[&str]) -> NonNull { let mut total_string_size = 0; for string in strings { total_string_size += string.len(); @@ -251,16 +251,16 @@ impl Inner { // We get the layout of the `Inner` type and we extend by the size // of the string array. - let inner_layout = Layout::new::(); + let inner_layout = Layout::new::(); let (layout, offset) = inner_layout .extend(Layout::array::(total_string_size).unwrap()) .unwrap(); let inner = unsafe { - let inner = alloc(layout) as *mut Inner; + let inner = alloc(layout).cast::(); // Write the first part, the Inner. - inner.write(Inner { + inner.write(Self { len: total_string_size, refcount: Cell::new(1), data: [0; 0], @@ -287,15 +287,15 @@ impl Inner { /// Deallocate inner type with string data. #[inline] - unsafe fn dealloc(x: NonNull) { + unsafe fn dealloc(x: NonNull) { let len = (*x.as_ptr()).len; - let inner_layout = Layout::new::(); + let inner_layout = Layout::new::(); let (layout, _offset) = inner_layout .extend(Layout::array::(len).unwrap()) .unwrap(); - dealloc(x.as_ptr() as _, layout); + dealloc(x.as_ptr().cast::<_>(), layout); } } @@ -322,7 +322,7 @@ impl JsString { /// Create an empty string, same as calling default. #[inline] pub fn empty() -> Self { - JsString::default() + Self::default() } /// Create a new JavaScript string. @@ -343,7 +343,7 @@ impl JsString { } /// Concatenate two string. - pub fn concat(x: T, y: U) -> JsString + pub fn concat(x: T, y: U) -> Self where T: AsRef, U: AsRef, @@ -366,7 +366,7 @@ impl JsString { } /// Concatenate array of string. - pub fn concat_array(strings: &[&str]) -> JsString { + pub fn concat_array(strings: &[&str]) -> Self { let this = Self { inner: Inner::concat_array(strings), _marker: PhantomData, @@ -500,7 +500,7 @@ impl Clone for JsString { let inner = self.inner(); inner.refcount.set(inner.refcount.get() + 1); - JsString { + Self { inner: self.inner, _marker: PhantomData, } @@ -581,7 +581,7 @@ impl Deref for JsString { } } -impl PartialEq for JsString { +impl PartialEq for JsString { #[inline] fn eq(&self, other: &Self) -> bool { // If they point at the same memory allocation, then they are equal. @@ -651,7 +651,7 @@ mod tests { #[test] fn empty() { - let _ = JsString::new(""); + let _empty = JsString::new(""); } #[test] diff --git a/boa/src/symbol.rs b/boa/src/symbol.rs index 37fbe9fda2..23266f8f1d 100644 --- a/boa/src/symbol.rs +++ b/boa/src/symbol.rs @@ -120,7 +120,7 @@ impl WellKnownSymbols { /// The `Symbol.asyncIterator` well known symbol. /// - /// A method that returns the default AsyncIterator for an object. + /// A method that returns the default `AsyncIterator` for an object. /// Called by the semantics of the `for-await-of` statement. #[inline] pub fn async_iterator() -> JsSymbol { diff --git a/boa/src/syntax/ast/keyword.rs b/boa/src/syntax/ast/keyword.rs index af7b6c086a..bc1363f386 100644 --- a/boa/src/syntax/ast/keyword.rs +++ b/boa/src/syntax/ast/keyword.rs @@ -386,8 +386,8 @@ pub enum Keyword { /// - [MDN documentation][mdn] /// /// [node]: ../node/enum.Node.html#variant.Throw - /// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction - /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions + /// [spec]: https://tc39.es/ecma262/#sec-throw-statement + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw Throw, /// The `true` keyword diff --git a/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs b/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs index 3670fc80e4..a9bc9b24dc 100644 --- a/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs +++ b/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs @@ -69,7 +69,7 @@ impl ToInternedString for ConditionalOp { } impl From for Node { - fn from(cond_op: ConditionalOp) -> Node { + fn from(cond_op: ConditionalOp) -> Self { Self::ConditionalOp(cond_op) } } diff --git a/boa/src/syntax/ast/node/conditional/if_node/mod.rs b/boa/src/syntax/ast/node/conditional/if_node/mod.rs index cab16100d2..0981f037f6 100644 --- a/boa/src/syntax/ast/node/conditional/if_node/mod.rs +++ b/boa/src/syntax/ast/node/conditional/if_node/mod.rs @@ -88,7 +88,7 @@ impl ToInternedString for If { } impl From for Node { - fn from(if_stm: If) -> Node { + fn from(if_stm: If) -> Self { Self::If(if_stm) } } diff --git a/boa/src/syntax/ast/node/declaration/mod.rs b/boa/src/syntax/ast/node/declaration/mod.rs index 2d4aca44c2..dfb21a8579 100644 --- a/boa/src/syntax/ast/node/declaration/mod.rs +++ b/boa/src/syntax/ast/node/declaration/mod.rs @@ -95,7 +95,7 @@ pub enum DeclarationList { impl AsRef<[Declaration]> for DeclarationList { fn as_ref(&self) -> &[Declaration] { - use DeclarationList::*; + use DeclarationList::{Const, Let, Var}; match self { Var(list) | Const(list) | Let(list) => list, } @@ -104,8 +104,10 @@ impl AsRef<[Declaration]> for DeclarationList { impl ToInternedString for DeclarationList { fn to_interned_string(&self, interner: &Interner) -> String { - if !self.as_ref().is_empty() { - use DeclarationList::*; + if self.as_ref().is_empty() { + String::new() + } else { + use DeclarationList::{Const, Let, Var}; format!( "{} {}", match &self { @@ -115,19 +117,17 @@ impl ToInternedString for DeclarationList { }, join_nodes(interner, self.as_ref()) ) - } else { - String::new() } } } impl From for Node { fn from(list: DeclarationList) -> Self { - use DeclarationList::*; + use DeclarationList::{Const, Let, Var}; match &list { - Let(_) => Node::LetDeclList(list), - Const(_) => Node::ConstDeclList(list), - Var(_) => Node::VarDeclList(list), + Let(_) => Self::LetDeclList(list), + Const(_) => Self::ConstDeclList(list), + Var(_) => Self::VarDeclList(list), } } } @@ -140,9 +140,9 @@ impl From for Box<[Declaration]> { /// Declaration represents either an individual binding or a binding pattern. /// -/// For `let` and `const` declarations this type represents a [LexicalBinding][spec1] +/// For `let` and `const` declarations this type represents a [`LexicalBinding`][spec1] /// -/// For `var` declarations this type represents a [VariableDeclaration][spec2] +/// For `var` declarations this type represents a [`VariableDeclaration`][spec2] /// /// More information: /// - [ECMAScript reference: 14.3 Declarations and the Variable Statement][spec3] @@ -176,7 +176,7 @@ impl ToInternedString for Declaration { } impl Declaration { - /// Creates a new variable declaration with a BindingIdentifier. + /// Creates a new variable declaration with a `BindingIdentifier`. #[inline] pub(in crate::syntax) fn new_with_identifier(ident: N, init: I) -> Self where @@ -189,7 +189,7 @@ impl Declaration { } } - /// Creates a new variable declaration with an ObjectBindingPattern. + /// Creates a new variable declaration with an `ObjectBindingPattern`. #[inline] pub(in crate::syntax) fn new_with_object_pattern( bindings: Vec, @@ -204,7 +204,7 @@ impl Declaration { ))) } - /// Creates a new variable declaration with an ArrayBindingPattern. + /// Creates a new variable declaration with an `ArrayBindingPattern`. #[inline] pub(in crate::syntax) fn new_with_array_pattern( bindings: Vec, @@ -229,12 +229,12 @@ impl Declaration { } } -/// DeclarationPattern represents an object or array binding pattern. +/// `DeclarationPattern` represents an object or array binding pattern. /// /// This enum mostly wraps the functionality of the specific binding pattern types. /// /// More information: -/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - BindingPattern][spec1] +/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - `BindingPattern`][spec1] /// /// [spec1]: https://tc39.es/ecma262/#prod-BindingPattern #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] @@ -275,12 +275,12 @@ impl DeclarationPattern { } } -/// DeclarationPatternObject represents an object binding pattern. +/// `DeclarationPatternObject` represents an object binding pattern. /// /// This struct holds a list of bindings, and an optional initializer for the binding pattern. /// /// More information: -/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - ObjectBindingPattern][spec1] +/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - `ObjectBindingPattern`][spec1] /// /// [spec1]: https://tc39.es/ecma262/#prod-ObjectBindingPattern #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] @@ -339,7 +339,7 @@ impl DeclarationPatternObject { let mut idents = Vec::new(); for binding in &self.bindings { - use BindingPatternTypeObject::*; + use BindingPatternTypeObject::{BindingPattern, Empty, RestProperty, SingleName}; match binding { Empty => {} @@ -372,12 +372,12 @@ impl DeclarationPatternObject { } } -/// DeclarationPatternArray represents an array binding pattern. +/// `DeclarationPatternArray` represents an array binding pattern. /// /// This struct holds a list of bindings, and an optional initializer for the binding pattern. /// /// More information: -/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - ArrayBindingPattern][spec1] +/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - `ArrayBindingPattern`][spec1] /// /// [spec1]: https://tc39.es/ecma262/#prod-ArrayBindingPattern #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] @@ -394,7 +394,7 @@ impl ToInternedString for DeclarationPatternArray { if i == self.bindings.len() - 1 { match binding { BindingPatternTypeArray::Elision => { - buf.push_str(&format!("{}, ", binding.to_interned_string(interner))) + buf.push_str(&format!("{}, ", binding.to_interned_string(interner))); } _ => buf.push_str(&format!("{} ", binding.to_interned_string(interner))), } @@ -438,11 +438,12 @@ impl DeclarationPatternArray { let mut idents = Vec::new(); for binding in &self.bindings { - use BindingPatternTypeArray::*; + use BindingPatternTypeArray::{ + BindingPattern, BindingPatternRest, Elision, Empty, SingleName, SingleNameRest, + }; match binding { - Empty => {} - Elision => {} + Empty | Elision => {} SingleName { ident, default_init: _, @@ -451,7 +452,7 @@ impl DeclarationPatternArray { } BindingPattern { pattern } | BindingPatternRest { pattern } => { let mut i = pattern.idents(); - idents.append(&mut i) + idents.append(&mut i); } SingleNameRest { ident } => idents.push(*ident), } @@ -461,10 +462,10 @@ impl DeclarationPatternArray { } } -/// BindingPatternTypeObject represents the different types of bindings that an object binding pattern may contain. +/// `BindingPatternTypeObject` represents the different types of bindings that an object binding pattern may contain. /// /// More information: -/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - ObjectBindingPattern][spec1] +/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - `ObjectBindingPattern`][spec1] /// /// [spec1]: https://tc39.es/ecma262/#prod-ObjectBindingPattern #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] @@ -565,10 +566,10 @@ impl ToInternedString for BindingPatternTypeObject { } } -/// BindingPatternTypeArray represents the different types of bindings that an array binding pattern may contain. +/// `BindingPatternTypeArray` represents the different types of bindings that an array binding pattern may contain. /// /// More information: -/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - ArrayBindingPattern][spec1] +/// - [ECMAScript reference: 14.3.3 Destructuring Binding Patterns - `ArrayBindingPattern`][spec1] /// /// [spec1]: https://tc39.es/ecma262/#prod-ArrayBindingPattern #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] diff --git a/boa/src/syntax/ast/node/field/get_const_field/mod.rs b/boa/src/syntax/ast/node/field/get_const_field/mod.rs index d5b56e34b9..c33bc32665 100644 --- a/boa/src/syntax/ast/node/field/get_const_field/mod.rs +++ b/boa/src/syntax/ast/node/field/get_const_field/mod.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; /// [dot notation][mdn]. /// /// In the object.property syntax, the property must be a valid JavaScript identifier. -/// (In the ECMAScript standard, the names of properties are technically "IdentifierNames", not +/// (In the ECMAScript standard, the names of properties are technically `IdentifierNames`, not /// "Identifiers", so reserved words can be used but are not recommended). /// /// One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup diff --git a/boa/src/syntax/ast/node/field/get_field/mod.rs b/boa/src/syntax/ast/node/field/get_field/mod.rs index 7534ebb490..79207490fe 100644 --- a/boa/src/syntax/ast/node/field/get_field/mod.rs +++ b/boa/src/syntax/ast/node/field/get_field/mod.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; /// This property accessor provides access to an object's properties by using the /// [bracket notation][mdn]. /// -/// In the object\[property_name\] syntax, the property_name is just a string or +/// In the `object[property_name]` syntax, the `property_name` is just a string or /// [Symbol][symbol]. So, it can be any string, including '1foo', '!bar!', or even ' ' (a /// space). /// diff --git a/boa/src/syntax/ast/node/iteration/break_node/mod.rs b/boa/src/syntax/ast/node/iteration/break_node/mod.rs index 2789649899..076549a3f9 100644 --- a/boa/src/syntax/ast/node/iteration/break_node/mod.rs +++ b/boa/src/syntax/ast/node/iteration/break_node/mod.rs @@ -65,7 +65,7 @@ impl ToInternedString for Break { } impl From for Node { - fn from(break_smt: Break) -> Node { + fn from(break_smt: Break) -> Self { Self::Break(break_smt) } } diff --git a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs index ff33ad2dcd..bdc54fb4b9 100644 --- a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs +++ b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs @@ -53,7 +53,7 @@ impl ToInternedString for Continue { } impl From for Node { - fn from(cont: Continue) -> Node { + fn from(cont: Continue) -> Self { Self::Continue(cont) } } diff --git a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs index a3f7b71464..d5eec396c2 100644 --- a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs @@ -79,7 +79,7 @@ impl ToInternedString for ForInLoop { } impl From for Node { - fn from(for_in: ForInLoop) -> Node { + fn from(for_in: ForInLoop) -> Self { Self::ForInLoop(for_in) } } diff --git a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs index 63970eecbd..29626d7dd5 100644 --- a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs @@ -80,7 +80,7 @@ impl ToInternedString for ForOfLoop { } impl From for Node { - fn from(for_of: ForOfLoop) -> Node { + fn from(for_of: ForOfLoop) -> Self { Self::ForOfLoop(for_of) } } diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index a6b4c8c2f7..b0e308b5eb 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -336,7 +336,7 @@ fn for_loop_break_label() { } str "#; - assert_eq!(&exec(scenario), "\"01\"") + assert_eq!(&exec(scenario), "\"01\""); } #[test] @@ -462,7 +462,7 @@ fn for_in_break_label() { } str "#; - assert_eq!(&exec(scenario), "\"0\"") + assert_eq!(&exec(scenario), "\"0\""); } #[test] @@ -481,7 +481,7 @@ fn for_in_continue_label() { } str "#; - assert_eq!(&exec(scenario), "\"00\"") + assert_eq!(&exec(scenario), "\"00\""); } #[test] diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 82c95db0a3..0429964e39 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -230,7 +230,8 @@ impl From for Node { impl Node { /// Returns a node ordering based on the hoistability of each node. - pub(crate) fn hoistable_order(a: &Node, b: &Node) -> Ordering { + #[allow(clippy::match_same_arms)] + pub(crate) fn hoistable_order(a: &Self, b: &Self) -> Ordering { match (a, b) { (Node::FunctionDecl(_), Node::FunctionDecl(_)) => Ordering::Equal, (_, Node::FunctionDecl(_)) => Ordering::Greater, @@ -307,8 +308,9 @@ impl Node { Self::TemplateLit(ref template) => template.to_interned_string(interner), Self::Throw(ref throw) => throw.to_interned_string(interner), Self::Assign(ref op) => op.to_interned_string(interner), - Self::LetDeclList(ref decl) => decl.to_interned_string(interner), - Self::ConstDeclList(ref decl) => decl.to_interned_string(interner), + Self::LetDeclList(ref decl) | Self::ConstDeclList(ref decl) => { + decl.to_interned_string(interner) + } Self::AsyncFunctionDecl(ref decl) => decl.to_indented_string(interner, indentation), Self::AsyncFunctionExpr(ref expr) => expr.to_indented_string(interner, indentation), Self::AwaitExpr(ref expr) => expr.to_interned_string(interner), @@ -341,7 +343,7 @@ where } else { buf.push_str(", "); } - buf.push_str(&e.to_interned_string(interner)) + buf.push_str(&e.to_interned_string(interner)); } buf } @@ -606,7 +608,7 @@ unsafe impl Trace for MethodDefinitionKind { empty_trace!(); } -/// PropertyName can be either a literal or computed. +/// `PropertyName` can be either a literal or computed. /// /// More information: /// - [ECMAScript reference][spec] @@ -657,7 +659,7 @@ unsafe impl Trace for PropertyName { } /// This parses the given source code, and then makes sure that -/// the resulting StatementList is formatted in the same manner +/// the resulting `StatementList` is formatted in the same manner /// as the source code. This is expected to have a preceding /// newline. /// diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index 3df6cc4b00..3895902323 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -49,10 +49,10 @@ impl Object { pub(in crate::syntax::ast::node) fn to_indented_string( &self, interner: &Interner, - indent: usize, + indent_n: usize, ) -> String { let mut buf = "{\n".to_owned(); - let indentation = " ".repeat(indent + 1); + let indentation = " ".repeat(indent_n + 1); for property in self.properties().iter() { buf.push_str(&match property { PropertyDefinition::IdentifierReference(ident) => { @@ -63,7 +63,7 @@ impl Object { "{}{}: {},\n", indentation, key.to_interned_string(interner), - value.to_no_indent_string(interner, indent + 1) + value.to_no_indent_string(interner, indent_n + 1) ) } PropertyDefinition::SpreadObject(key) => { @@ -83,12 +83,12 @@ impl Object { }, key.to_interned_string(interner), join_nodes(interner, node.parameters()), - block_to_string(node.body(), interner, indent + 1) + block_to_string(node.body(), interner, indent_n + 1) ) } }); } - buf.push_str(&format!("{}}}", " ".repeat(indent))); + buf.push_str(&format!("{}}}", " ".repeat(indent_n))); buf } diff --git a/boa/src/syntax/ast/node/return_smt/mod.rs b/boa/src/syntax/ast/node/return_smt/mod.rs index 14ff0315e9..fc6b010aa5 100644 --- a/boa/src/syntax/ast/node/return_smt/mod.rs +++ b/boa/src/syntax/ast/node/return_smt/mod.rs @@ -59,8 +59,8 @@ impl Return { } impl From for Node { - fn from(return_smt: Return) -> Node { - Node::Return(return_smt) + fn from(return_smt: Return) -> Self { + Self::Return(return_smt) } } diff --git a/boa/src/syntax/ast/node/spread/mod.rs b/boa/src/syntax/ast/node/spread/mod.rs index 11f933f12e..1e59bbb46f 100644 --- a/boa/src/syntax/ast/node/spread/mod.rs +++ b/boa/src/syntax/ast/node/spread/mod.rs @@ -56,7 +56,7 @@ impl ToInternedString for Spread { } impl From for Node { - fn from(spread: Spread) -> Node { + fn from(spread: Spread) -> Self { Self::Spread(spread) } } diff --git a/boa/src/syntax/ast/node/template/mod.rs b/boa/src/syntax/ast/node/template/mod.rs index f6c05366b4..3a3209e1d7 100644 --- a/boa/src/syntax/ast/node/template/mod.rs +++ b/boa/src/syntax/ast/node/template/mod.rs @@ -29,7 +29,7 @@ impl TemplateLit { where E: Into>, { - TemplateLit { + Self { elements: elements.into(), } } @@ -47,7 +47,7 @@ impl ToInternedString for TemplateLit { match elt { TemplateElement::String(s) => buf.push_str(interner.resolve_expect(*s)), TemplateElement::Expr(n) => { - buf.push_str(&format!("${{{}}}", n.to_interned_string(interner))) + buf.push_str(&format!("${{{}}}", n.to_interned_string(interner))); } } } @@ -117,7 +117,7 @@ impl ToInternedString for TaggedTemplate { impl From for Node { fn from(template: TaggedTemplate) -> Self { - Node::TaggedTemplate(template) + Self::TaggedTemplate(template) } } diff --git a/boa/src/syntax/ast/node/throw/mod.rs b/boa/src/syntax/ast/node/throw/mod.rs index 9ae71c5245..73676c6a78 100644 --- a/boa/src/syntax/ast/node/throw/mod.rs +++ b/boa/src/syntax/ast/node/throw/mod.rs @@ -53,7 +53,7 @@ impl ToInternedString for Throw { } impl From for Node { - fn from(trw: Throw) -> Node { + fn from(trw: Throw) -> Self { Self::Throw(trw) } } diff --git a/boa/src/syntax/ast/node/yield/mod.rs b/boa/src/syntax/ast/node/yield/mod.rs index 999c47f683..7b8cc4499f 100644 --- a/boa/src/syntax/ast/node/yield/mod.rs +++ b/boa/src/syntax/ast/node/yield/mod.rs @@ -45,8 +45,8 @@ impl Yield { } impl From for Node { - fn from(r#yield: Yield) -> Node { - Node::Yield(r#yield) + fn from(r#yield: Yield) -> Self { + Self::Yield(r#yield) } } diff --git a/boa/src/syntax/ast/position.rs b/boa/src/syntax/ast/position.rs index ca9fc8c422..b032f735e9 100644 --- a/boa/src/syntax/ast/position.rs +++ b/boa/src/syntax/ast/position.rs @@ -9,8 +9,9 @@ use serde::{Deserialize, Serialize}; /// /// Stores both the column number and the line number. /// -/// Note that spans are of the form [begining, end) i.e. that the begining position is inclusive and the end position is exclusive. -/// See test check_positions from syntax/lexer/tests.rs for an example. +/// Note that spans are of the form [begining, end) i.e. that the begining position is inclusive +/// and the end position is exclusive. See test `check_positions` from `syntax/lexer/tests.rs` for +/// an example. /// /// ## Similar Implementations /// [V8: Location](https://cs.chromium.org/chromium/src/v8/src/parsing/scanner.h?type=cs&q=isValid+Location&g=0&l=216) @@ -126,6 +127,7 @@ impl fmt::Display for Span { } #[cfg(test)] +#[allow(clippy::similar_names)] mod tests { use super::{Position, Span}; diff --git a/boa/src/syntax/lexer/comment.rs b/boa/src/syntax/lexer/comment.rs index 58e34a93ad..8eaf0d2d7c 100644 --- a/boa/src/syntax/lexer/comment.rs +++ b/boa/src/syntax/lexer/comment.rs @@ -40,10 +40,9 @@ impl Tokenizer for SingleLineComment { while let Some(ch) = cursor.peek()? { if ch == b'\n' || ch == b'\r' { break; - } else { - // Consume char. - cursor.next_byte()?.expect("Comment character vanished"); } + // Consume char. + cursor.next_byte()?.expect("Comment character vanished"); } Ok(Token::new( TokenKind::Comment, @@ -91,7 +90,7 @@ impl Tokenizer for MultiLineComment { )) } Ok(c) if c == '\r' || c == '\n' || c == '\u{2028}' || c == '\u{2029}' => { - new_line = true + new_line = true; } _ => {} }; diff --git a/boa/src/syntax/lexer/cursor.rs b/boa/src/syntax/lexer/cursor.rs index b23ae79131..b5e88808d7 100644 --- a/boa/src/syntax/lexer/cursor.rs +++ b/boa/src/syntax/lexer/cursor.rs @@ -38,7 +38,7 @@ impl Cursor { #[inline] pub(super) fn set_strict_mode(&mut self, strict_mode: bool) { - self.strict_mode = strict_mode + self.strict_mode = strict_mode; } } @@ -236,7 +236,7 @@ where // Try to take a newline if it's next, for windows "\r\n" newlines // Otherwise, treat as a Mac OS9 bare '\r' newline if self.peek()? == Some(b'\n') { - let _ = self.iter.next_byte(); + let _next = self.iter.next_byte(); } self.next_line(); } @@ -270,12 +270,12 @@ where // Try to take a newline if it's next, for windows "\r\n" newlines // Otherwise, treat as a Mac OS9 bare '\r' newline if self.peek()? == Some(0xA) { - let _ = self.iter.next_byte(); + let _next = self.iter.next_byte(); } self.next_line(); } // '\n' | '\u{2028}' | '\u{2029}' - Some(0xA) | Some(0x2028) | Some(0x2029) => self.next_line(), + Some(0xA | 0x2028 | 0x2029) => self.next_line(), Some(_) => self.next_column(), _ => {} } @@ -286,6 +286,7 @@ where /// Inner iterator for a cursor. #[derive(Debug)] +#[allow(clippy::option_option)] struct InnerIter { iter: Bytes, num_peeked_bytes: u8, @@ -348,7 +349,7 @@ where match self.iter.next().transpose()? { Some(byte) => { self.num_peeked_bytes = 1; - self.peeked_bytes = byte as u32; + self.peeked_bytes = u32::from(byte); Ok(Some(byte)) } None => Ok(None), @@ -362,7 +363,7 @@ where while self.num_peeked_bytes < n && self.num_peeked_bytes < 4 { match self.iter.next().transpose()? { Some(byte) => { - self.peeked_bytes |= (byte as u32) << (self.num_peeked_bytes * 8); + self.peeked_bytes |= u32::from(byte) << (self.num_peeked_bytes * 8); self.num_peeked_bytes += 1; } None => break, @@ -387,8 +388,8 @@ where // Decode UTF-8 let x = match self.peek_byte()? { Some(b) if b < 128 => { - self.peeked_char = Some(Some(b as u32)); - return Ok(Some(b as u32)); + self.peeked_char = Some(Some(u32::from(b))); + return Ok(Some(u32::from(b))); } Some(b) => b, None => { @@ -407,7 +408,7 @@ where // [[x y z] w] case // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid let z = (self.peek_n_bytes(3)? >> 16) as u8; - let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z); + let y_z = utf8_acc_cont_byte(u32::from(y & CONT_MASK), z); ch = init << 12 | y_z; if x >= 0xF0 { // [x y z w] case @@ -448,7 +449,7 @@ where // Decode UTF-8 let x = match self.next_byte()? { - Some(b) if b < 128 => return Ok(Some(b as u32)), + Some(b) if b < 128 => return Ok(Some(u32::from(b))), Some(b) => b, None => return Ok(None), }; @@ -463,7 +464,7 @@ where // [[x y z] w] case // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid let z = unwrap_or_0(self.next_byte()?); - let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z); + let y_z = utf8_acc_cont_byte(u32::from(y & CONT_MASK), z); ch = init << 12 | y_z; if x >= 0xF0 { // [x y z w] case @@ -485,13 +486,13 @@ const CONT_MASK: u8 = 0b0011_1111; /// for width 3, and 3 bits for width 4. #[inline] fn utf8_first_byte(byte: u8, width: u32) -> u32 { - (byte & (0x7F >> width)) as u32 + u32::from(byte & (0x7F >> width)) } /// Returns the value of `ch` updated with continuation byte `byte`. #[inline] fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { - (ch << 6) | (byte & CONT_MASK) as u32 + (ch << 6) | u32::from(byte & CONT_MASK) } /// Checks whether the byte is a UTF-8 first byte (i.e., ascii byte or starts with the diff --git a/boa/src/syntax/lexer/identifier.rs b/boa/src/syntax/lexer/identifier.rs index 48cf2d8e46..3c9caa0b56 100644 --- a/boa/src/syntax/lexer/identifier.rs +++ b/boa/src/syntax/lexer/identifier.rs @@ -47,7 +47,7 @@ impl Identifier { Self { init } } - /// Checks if a character is IdentifierStart as per ECMAScript standards. + /// Checks if a character is `IdentifierStart` as per ECMAScript standards. /// /// More information: /// - [ECMAScript reference][spec] @@ -62,7 +62,7 @@ impl Identifier { } } - /// Checks if a character is IdentifierPart as per ECMAScript standards. + /// Checks if a character is `IdentifierPart` as per ECMAScript standards. /// /// More information: /// - [ECMAScript reference][spec] @@ -146,6 +146,9 @@ impl Identifier { where R: Read, { + let _timer = + BoaProfiler::global().start_event("Identifier::take_identifier_name", "Lexing"); + let mut contains_escaped_chars = false; let mut identifier_name = if init == '\\' && cursor.next_is(b'u')? { let ch = StringLiteral::take_unicode_escape_sequence(cursor, start_pos)?; @@ -165,8 +168,8 @@ impl Identifier { let ch = match cursor.peek_char()? { Some(0x005C /* \ */) if cursor.peek_n(2)? >> 8 == 0x0075 /* u */ => { let pos = cursor.pos(); - let _ = cursor.next_byte(); - let _ = cursor.next_byte(); + let _next = cursor.next_byte(); + let _next = cursor.next_byte(); let ch = StringLiteral::take_unicode_escape_sequence(cursor, pos)?; if Self::is_identifier_part(ch) { diff --git a/boa/src/syntax/lexer/mod.rs b/boa/src/syntax/lexer/mod.rs index 496bd041a3..a01425151d 100644 --- a/boa/src/syntax/lexer/mod.rs +++ b/boa/src/syntax/lexer/mod.rs @@ -106,7 +106,7 @@ impl Lexer { #[inline] pub(super) fn set_strict_mode(&mut self, strict_mode: bool) { - self.cursor.set_strict_mode(strict_mode) + self.cursor.set_strict_mode(strict_mode); } /// Creates a new lexer. @@ -117,7 +117,7 @@ impl Lexer { { Self { cursor: Cursor::new(reader), - goal_symbol: Default::default(), + goal_symbol: InputElement::default(), } } @@ -333,6 +333,6 @@ pub(crate) enum InputElement { impl Default for InputElement { fn default() -> Self { - InputElement::RegExp + Self::RegExp } } diff --git a/boa/src/syntax/lexer/number.rs b/boa/src/syntax/lexer/number.rs index c8f716dcc0..006f7034df 100644 --- a/boa/src/syntax/lexer/number.rs +++ b/boa/src/syntax/lexer/number.rs @@ -49,17 +49,15 @@ impl NumericKind { fn base(self) -> u32 { match self { Self::Rational => 10, - Self::Integer(base) => base, - Self::BigInt(base) => base, + Self::Integer(base) | Self::BigInt(base) => base, } } - /// Converts `self` to BigInt kind. + /// Converts `self` to `BigInt` kind. fn to_bigint(self) -> Self { match self { Self::Rational => unreachable!("can not convert rational number to BigInt"), - Self::Integer(base) => Self::BigInt(base), - Self::BigInt(base) => Self::BigInt(base), + Self::Integer(base) | Self::BigInt(base) => Self::BigInt(base), } } } @@ -68,7 +66,7 @@ impl NumericKind { fn take_signed_integer( buf: &mut Vec, cursor: &mut Cursor, - kind: &NumericKind, + kind: NumericKind, ) -> Result<(), Error> where R: Read, @@ -118,7 +116,7 @@ where fn take_integer( buf: &mut Vec, cursor: &mut Cursor, - kind: &NumericKind, + kind: NumericKind, separator_allowed: bool, ) -> Result<(), Error> where @@ -156,7 +154,8 @@ where } Ok(()) } -/// Utility function for checking the NumericLiteral is not followed by an `IdentifierStart` or `DecimalDigit` character. + +/// Utility function for checking the `NumericLiteral` is not followed by an `IdentifierStart` or `DecimalDigit` character. /// /// More information: /// - [ECMAScript Specification][spec] @@ -268,14 +267,14 @@ impl Tokenizer for NumberLiteral { "implicit octal literals are not allowed in strict mode", start_pos, )); - } else { - // Remove the initial '0' from buffer. - buf.pop(); + } - buf.push(cursor.next_byte()?.expect("'0' character vanished")); + // Remove the initial '0' from buffer. + buf.pop(); - kind = NumericKind::Integer(8); - } + buf.push(cursor.next_byte()?.expect("'0' character vanished")); + + kind = NumericKind::Integer(8); } else if ch.is_digit(10) { // Indicates a numerical digit comes after then 0 but it isn't an octal digit // so therefore this must be a number with an unneeded leading 0. This is @@ -304,7 +303,7 @@ impl Tokenizer for NumberLiteral { } else { // Consume digits and separators until a non-digit non-separator // character is encountered or all the characters are consumed. - take_integer(&mut buf, cursor, &kind, !legacy_octal)?; + take_integer(&mut buf, cursor, kind, !legacy_octal)?; cursor.peek()? }; @@ -346,18 +345,18 @@ impl Tokenizer for NumberLiteral { // Consume digits and separators until a non-digit non-separator // character is encountered or all the characters are consumed. - take_integer(&mut buf, cursor, &kind, true)?; + take_integer(&mut buf, cursor, kind, true)?; // The non-digit character at this point must be an 'e' or 'E' to indicate an Exponent Part. // Another '.' or 'n' is not allowed. match cursor.peek()? { - Some(b'e') | Some(b'E') => { + Some(b'e' | b'E') => { // Consume the ExponentIndicator. cursor.next_byte()?.expect("e or E token vanished"); buf.push(b'E'); - take_signed_integer(&mut buf, cursor, &kind)?; + take_signed_integer(&mut buf, cursor, kind)?; } Some(_) | None => { // Finished lexing. @@ -365,11 +364,11 @@ impl Tokenizer for NumberLiteral { } } } - Some(b'e') | Some(b'E') => { + Some(b'e' | b'E') => { kind = NumericKind::Rational; cursor.next_byte()?.expect("e or E character vanished"); // Consume the ExponentIndicator. buf.push(b'E'); - take_signed_integer(&mut buf, cursor, &kind)?; + take_signed_integer(&mut buf, cursor, kind)?; } Some(_) | None => { // Indicates lexing finished. @@ -392,7 +391,7 @@ impl Tokenizer for NumberLiteral { // The truncated float should be identically to the non-truncated float for the conversion to be loss-less, // any other different and the number must be stored as a rational. #[allow(clippy::float_cmp)] - if (int_val as f64) == val { + if f64::from(int_val) == val { // For performance reasons we attempt to store values as integers if possible. Numeric::Integer(int_val) } else { diff --git a/boa/src/syntax/lexer/regex.rs b/boa/src/syntax/lexer/regex.rs index 84c20de238..bce5cbe864 100644 --- a/boa/src/syntax/lexer/regex.rs +++ b/boa/src/syntax/lexer/regex.rs @@ -110,7 +110,7 @@ impl Tokenizer for RegexLiteral { let mut flags = Vec::new(); let flags_start = cursor.pos(); - cursor.take_while_ascii_pred(&mut flags, &|c: char| c.is_alphabetic())?; + cursor.take_while_ascii_pred(&mut flags, &char::is_alphabetic)?; let flags_str = unsafe { str::from_utf8_unchecked(flags.as_slice()) }; if let Ok(body_str) = str::from_utf8(body.as_slice()) { @@ -166,9 +166,8 @@ fn parse_regex_flags(s: &str, start: Position, interner: &mut Interner) -> Resul format!("repeated regular expression flag {}", char::from(c)), start, )); - } else { - flags.insert(new_flag); } + flags.insert(new_flag); } Ok(interner.get_or_intern(flags.to_string())) } diff --git a/boa/src/syntax/lexer/string.rs b/boa/src/syntax/lexer/string.rs index af43c73230..aec844135d 100644 --- a/boa/src/syntax/lexer/string.rs +++ b/boa/src/syntax/lexer/string.rs @@ -100,7 +100,7 @@ impl Tokenizer for StringLiteral { } impl StringLiteral { - /// Checks if a character is LineTerminator as per ECMAScript standards. + /// Checks if a character is `LineTerminator` as per ECMAScript standards. /// /// More information: /// - [ECMAScript reference][spec] @@ -212,9 +212,8 @@ impl StringLiteral { "\\8 and \\9 are not allowed in strict mode", start_pos, )); - } else { - Some(escape_ch) } + Some(escape_ch) } _ if (0x0030..=0x0037 /* '0'..='7' */).contains(&escape_ch) => { if is_template_literal { @@ -222,17 +221,19 @@ impl StringLiteral { "octal escape sequences are not allowed in template literal", start_pos, )); - } else if is_strict_mode { + } + + if is_strict_mode { return Err(Error::syntax( "octal escape sequences are not allowed in strict mode", start_pos, )); - } else { - Some(Self::take_legacy_octal_escape_sequence( - cursor, - escape_ch as u8, - )?) } + + Some(Self::take_legacy_octal_escape_sequence( + cursor, + escape_ch as u8, + )?) } _ if Self::is_line_terminator(escape_ch) => { // Grammar: LineContinuation @@ -293,7 +294,7 @@ impl StringLiteral { .and_then(|code_point_str| u16::from_str_radix(code_point_str, 16).ok()) .ok_or_else(|| Error::syntax("invalid Unicode escape sequence", start_pos))?; - Ok(code_point as u32) + Ok(u32::from(code_point)) } } @@ -312,7 +313,7 @@ impl StringLiteral { .and_then(|code_point_str| u16::from_str_radix(code_point_str, 16).ok()) .ok_or_else(|| Error::syntax("invalid Hexadecimal escape sequence", start_pos))?; - Ok(code_point as u32) + Ok(u32::from(code_point)) } #[inline] @@ -324,21 +325,21 @@ impl StringLiteral { R: Read, { // Grammar: OctalDigit - let mut code_point = (init_byte - b'0') as u32; + let mut code_point = u32::from(init_byte - b'0'); // Grammar: ZeroToThree OctalDigit // Grammar: FourToSeven OctalDigit if let Some(byte) = cursor.peek()? { if (b'0'..=b'7').contains(&byte) { let _ = cursor.next_byte()?; - code_point = (code_point * 8) + (byte - b'0') as u32; + code_point = (code_point * 8) + u32::from(byte - b'0'); if (b'0'..=b'3').contains(&init_byte) { // Grammar: ZeroToThree OctalDigit OctalDigit if let Some(byte) = cursor.peek()? { if (b'0'..=b'7').contains(&byte) { let _ = cursor.next_byte()?; - code_point = (code_point * 8) + (byte - b'0') as u32; + code_point = (code_point * 8) + u32::from(byte - b'0'); } } } diff --git a/boa/src/syntax/lexer/template.rs b/boa/src/syntax/lexer/template.rs index a466f44c5b..e7d689241c 100644 --- a/boa/src/syntax/lexer/template.rs +++ b/boa/src/syntax/lexer/template.rs @@ -86,7 +86,7 @@ impl TemplateString { /// Template literal lexing. /// -/// Expects: Initial ` to already be consumed by cursor. +/// Expects: Initial `` ` `` to already be consumed by cursor. /// /// More information: /// - [ECMAScript reference][spec] @@ -147,9 +147,9 @@ impl Tokenizer for TemplateLiteral { )) })?; - buf.push(b'\\' as u16); + buf.push(u16::from(b'\\')); match escape_ch { - b'`' | b'$' | b'\\' => buf.push(cursor.next_byte()?.unwrap() as u16), + b'`' | b'$' | b'\\' => buf.push(u16::from(cursor.next_byte()?.unwrap())), _ => continue, } } diff --git a/boa/src/syntax/lexer/tests.rs b/boa/src/syntax/lexer/tests.rs index a1087000de..a5e7a3e713 100644 --- a/boa/src/syntax/lexer/tests.rs +++ b/boa/src/syntax/lexer/tests.rs @@ -105,7 +105,7 @@ fn check_identifier() { fn check_invalid_identifier_start() { let invalid_identifier_starts = ["\u{200C}", "\u{200D}", "😀"]; - for s in invalid_identifier_starts.iter() { + for s in &invalid_identifier_starts { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); lexer @@ -120,7 +120,7 @@ fn check_invalid_identifier_part() { let mut interner = Interner::default(); let sym = interner.get_or_intern_static("x"); - for part in invalid_identifier_parts.iter() { + for part in &invalid_identifier_parts { let s = String::from("x") + part; let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); @@ -535,7 +535,7 @@ fn numbers_with_bad_separators() { "0b_10", "0x_10", "10_", "1._10", "1e+_10", "1E_10", "10__00", ]; - for n in numbers.iter() { + for n in &numbers { let mut lexer = Lexer::new(n.as_bytes()); let mut interner = Interner::default(); assert!(lexer.next(&mut interner).is_err()); @@ -860,7 +860,7 @@ fn illegal_following_numeric_literal() { .next(&mut interner) .expect_err("DecimalDigit following NumericLiteral not rejected as expected"); if let Error::Syntax(_, pos) = err { - assert_eq!(pos, Position::new(1, 5)) + assert_eq!(pos, Position::new(1, 5)); } else { panic!("invalid error type"); } @@ -1001,7 +1001,7 @@ fn string_legacy_octal_escape() { (r#"'\101'"#, "A"), ]; - for (s, expected) in test_cases.iter() { + for (s, expected) in &test_cases { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); @@ -1011,7 +1011,7 @@ fn string_legacy_octal_escape() { expect_tokens(&mut lexer, &expected_tokens, &mut interner); } - for (s, _) in test_cases.iter() { + for (s, _) in &test_cases { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); lexer.set_strict_mode(true); @@ -1031,7 +1031,7 @@ fn string_legacy_octal_escape() { fn string_zero_escape() { let test_cases = [(r#"'\0'"#, "\u{0}"), (r#"'\0A'"#, "\u{0}A")]; - for (s, expected) in test_cases.iter() { + for (s, expected) in &test_cases { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); @@ -1046,7 +1046,7 @@ fn string_zero_escape() { fn string_non_octal_decimal_escape() { let test_cases = [(r#"'\8'"#, "8"), (r#"'\9'"#, "9")]; - for (s, expected) in test_cases.iter() { + for (s, expected) in &test_cases { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); @@ -1056,7 +1056,7 @@ fn string_non_octal_decimal_escape() { expect_tokens(&mut lexer, &expected_tokens, &mut interner); } - for (s, _) in test_cases.iter() { + for (s, _) in &test_cases { let mut lexer = Lexer::new(s.as_bytes()); let mut interner = Interner::default(); lexer.set_strict_mode(true); diff --git a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs index 45f1c564f1..573891e16c 100644 --- a/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs +++ b/boa/src/syntax/parser/cursor/buffered_lexer/mod.rs @@ -74,7 +74,7 @@ where #[inline] pub(super) fn set_goal(&mut self, elm: InputElement) { let _timer = BoaProfiler::global().start_event("cursor::set_goal()", "Parsing"); - self.lexer.set_goal(elm) + self.lexer.set_goal(elm); } /// Lexes the next tokens as a regex assuming that the starting '/' has already been consumed. @@ -88,7 +88,7 @@ where self.set_goal(InputElement::RegExp); self.lexer .lex_slash_token(start, interner) - .map_err(|e| e.into()) + .map_err(Into::into) } /// Lexes the next tokens as template middle or template tail assuming that the starting @@ -110,7 +110,7 @@ where #[inline] pub(super) fn set_strict_mode(&mut self, strict_mode: bool) { - self.lexer.set_strict_mode(strict_mode) + self.lexer.set_strict_mode(strict_mode); } /// Fills the peeking buffer with the next token. @@ -162,7 +162,7 @@ where /// Moves the cursor to the next token and returns the token. /// - /// If skip_line_terminators is true then line terminators will be discarded. + /// If `skip_line_terminators` is true then line terminators will be discarded. /// /// This follows iterator semantics in that a `peek(0, false)` followed by a `next(false)` will /// return the same value. Note that because a `peek(n, false)` may return a line terminator a diff --git a/boa/src/syntax/parser/cursor/mod.rs b/boa/src/syntax/parser/cursor/mod.rs index 2611eb317f..b0c2f09206 100644 --- a/boa/src/syntax/parser/cursor/mod.rs +++ b/boa/src/syntax/parser/cursor/mod.rs @@ -41,7 +41,7 @@ where #[inline] pub(super) fn set_goal(&mut self, elm: InputElement) { - self.buffered_lexer.set_goal(elm) + self.buffered_lexer.set_goal(elm); } #[inline] @@ -83,7 +83,7 @@ where #[inline] pub(super) fn set_strict_mode(&mut self, strict_mode: bool) { - self.buffered_lexer.set_strict_mode(strict_mode) + self.buffered_lexer.set_strict_mode(strict_mode); } /// Returns an error if the next token is not of kind `kind`. @@ -124,11 +124,8 @@ where ) -> Result, ParseError> { match self.buffered_lexer.peek(0, false, interner)? { Some(tk) => match tk.kind() { - TokenKind::Punctuator(Punctuator::Semicolon) - | TokenKind::LineTerminator - | TokenKind::Punctuator(Punctuator::CloseBlock) => { - Ok(SemicolonResult::Found(Some(tk))) - } + TokenKind::Punctuator(Punctuator::Semicolon | Punctuator::CloseBlock) + | TokenKind::LineTerminator => Ok(SemicolonResult::Found(Some(tk))), _ => Ok(SemicolonResult::NotFound(tk)), }, None => Ok(SemicolonResult::Found(None)), @@ -149,7 +146,7 @@ where match self.peek_semicolon(interner)? { SemicolonResult::Found(Some(tk)) => match *tk.kind() { TokenKind::Punctuator(Punctuator::Semicolon) | TokenKind::LineTerminator => { - let _ = self.buffered_lexer.next(false, interner)?; + let _next = self.buffered_lexer.next(false, interner)?; Ok(()) } _ => Ok(()), @@ -168,7 +165,8 @@ where /// /// It expects that the token stream does not end here. /// - /// This is just syntatic sugar for a .peek(skip_n) call followed by a check that the result is not a line terminator or None. + /// This is just syntatic sugar for a `.peek(skip_n)` call followed by a check that the result + /// is not a line terminator or `None`. #[inline] pub(super) fn peek_expect_no_lineterminator( &mut self, diff --git a/boa/src/syntax/parser/error.rs b/boa/src/syntax/parser/error.rs index aeb611d22a..78219270c0 100644 --- a/boa/src/syntax/parser/error.rs +++ b/boa/src/syntax/parser/error.rs @@ -19,8 +19,8 @@ impl ErrorContext for Result { } impl From for ParseError { - fn from(e: LexError) -> ParseError { - ParseError::lex(e) + fn from(e: LexError) -> Self { + Self::lex(e) } } diff --git a/boa/src/syntax/parser/expression/assignment/arrow_function.rs b/boa/src/syntax/parser/expression/assignment/arrow_function.rs index 84b92444c9..4d45b2fdff 100644 --- a/boa/src/syntax/parser/expression/assignment/arrow_function.rs +++ b/boa/src/syntax/parser/expression/assignment/arrow_function.rs @@ -141,7 +141,7 @@ where { let lexically_declared_names = body.lexically_declared_names(interner); for param in params.parameters.as_ref() { - for param_name in param.names().into_iter() { + for param_name in param.names() { if lexically_declared_names.contains(¶m_name) { return Err(ParseError::lex(LexError::Syntax( format!( @@ -198,7 +198,7 @@ where .kind() { TokenKind::Punctuator(Punctuator::OpenBlock) => { - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; let body = FunctionBody::new(false, false).parse(cursor, interner)?; cursor.expect(Punctuator::CloseBlock, "arrow function", interner)?; Ok(body) diff --git a/boa/src/syntax/parser/expression/assignment/exponentiation.rs b/boa/src/syntax/parser/expression/assignment/exponentiation.rs index c09820c534..6bf97a9d57 100644 --- a/boa/src/syntax/parser/expression/assignment/exponentiation.rs +++ b/boa/src/syntax/parser/expression/assignment/exponentiation.rs @@ -66,13 +66,10 @@ where Ok(if let Some(tok) = cursor.peek(0, interner)? { matches!( tok.kind(), - TokenKind::Keyword(Keyword::Delete) - | TokenKind::Keyword(Keyword::Void) - | TokenKind::Keyword(Keyword::TypeOf) - | TokenKind::Punctuator(Punctuator::Add) - | TokenKind::Punctuator(Punctuator::Sub) - | TokenKind::Punctuator(Punctuator::Not) - | TokenKind::Punctuator(Punctuator::Neg) + TokenKind::Keyword(Keyword::Delete | Keyword::Void | Keyword::TypeOf) + | TokenKind::Punctuator( + Punctuator::Add | Punctuator::Sub | Punctuator::Not | Punctuator::Neg + ) ) } else { false diff --git a/boa/src/syntax/parser/expression/assignment/mod.rs b/boa/src/syntax/parser/expression/assignment/mod.rs index b451311ffe..81b67ffd9d 100644 --- a/boa/src/syntax/parser/expression/assignment/mod.rs +++ b/boa/src/syntax/parser/expression/assignment/mod.rs @@ -96,9 +96,7 @@ where .parse(cursor, interner) } // ArrowFunction[?In, ?Yield, ?Await] -> ArrowParameters[?Yield, ?Await] -> BindingIdentifier[?Yield, ?Await] - TokenKind::Identifier(_) - | TokenKind::Keyword(Keyword::Yield) - | TokenKind::Keyword(Keyword::Await) => { + TokenKind::Identifier(_) | TokenKind::Keyword(Keyword::Yield | Keyword::Await) => { if let Ok(tok) = cursor.peek_expect_no_lineterminator(1, "assignment expression", interner) { diff --git a/boa/src/syntax/parser/expression/assignment/yield.rs b/boa/src/syntax/parser/expression/assignment/yield.rs index 703b40aafb..48e4c9ca74 100644 --- a/boa/src/syntax/parser/expression/assignment/yield.rs +++ b/boa/src/syntax/parser/expression/assignment/yield.rs @@ -1,4 +1,4 @@ -//! YieldExpression parsing. +//! `YieldExpression` parsing. //! //! More information: //! - [MDN documentation][mdn] @@ -23,7 +23,7 @@ use std::io::Read; use super::AssignmentExpression; -/// YieldExpression parsing. +/// `YieldExpression` parsing. /// /// More information: /// - [MDN documentation][mdn] diff --git a/boa/src/syntax/parser/expression/left_hand_side/call.rs b/boa/src/syntax/parser/expression/left_hand_side/call.rs index 2e96a4b9e2..8e4c5a1a11 100644 --- a/boa/src/syntax/parser/expression/left_hand_side/call.rs +++ b/boa/src/syntax/parser/expression/left_hand_side/call.rs @@ -110,7 +110,7 @@ where } } TokenKind::Punctuator(Punctuator::OpenBracket) => { - let _ = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; // We move the parser. + let _next = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; // We move the parser. let idx = Expression::new(true, self.allow_yield, self.allow_await) .parse(cursor, interner)?; cursor.expect(Punctuator::CloseBracket, "call expression", interner)?; diff --git a/boa/src/syntax/parser/expression/left_hand_side/member.rs b/boa/src/syntax/parser/expression/left_hand_side/member.rs index 9d94507291..4b5ad6fbb7 100644 --- a/boa/src/syntax/parser/expression/left_hand_side/member.rs +++ b/boa/src/syntax/parser/expression/left_hand_side/member.rs @@ -70,7 +70,7 @@ where .kind() == &TokenKind::Keyword(Keyword::New) { - let _ = cursor.next(interner).expect("new keyword disappeared"); + let _next = cursor.next(interner).expect("new keyword disappeared"); let lhs = self.parse(cursor, interner)?; let args = match cursor.peek(0, interner)? { Some(next) if next.kind() == &TokenKind::Punctuator(Punctuator::OpenParen) => { @@ -96,7 +96,7 @@ where match token.kind() { TokenKind::Identifier(name) => lhs = GetConstField::new(lhs, *name).into(), TokenKind::Keyword(kw) => { - lhs = GetConstField::new(lhs, kw.to_sym(interner)).into() + lhs = GetConstField::new(lhs, kw.to_sym(interner)).into(); } _ => { return Err(ParseError::expected( diff --git a/boa/src/syntax/parser/expression/mod.rs b/boa/src/syntax/parser/expression/mod.rs index 38d2c1d080..7ca68c8cca 100644 --- a/boa/src/syntax/parser/expression/mod.rs +++ b/boa/src/syntax/parser/expression/mod.rs @@ -63,8 +63,8 @@ impl PartialEq for Keyword { /// ``` /// /// This macro has 2 mandatory identifiers: -/// - The `$name` identifier is the name of the TargetExpression struct that the parser will be implemented for. -/// - The `$lower` identifier is the name of the InnerExpression struct according to the pattern above. +/// - The `$name` identifier is the name of the `TargetExpression` struct that the parser will be implemented for. +/// - The `$lower` identifier is the name of the `InnerExpression` struct according to the pattern above. /// /// A list of punctuators (operands between the and ) are passed as the third parameter. /// @@ -87,7 +87,7 @@ macro_rules! expression { ($name:ident, $lower:ident, [$( $op:path ),*], [$( $lo while let Some(tok) = cursor.peek(0, interner)? { match *tok.kind() { TokenKind::Punctuator(op) if $( op == $op )||* => { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); lhs = BinOp::new( op.as_binop().expect("Could not get binary operation."), lhs, @@ -95,7 +95,7 @@ macro_rules! expression { ($name:ident, $lower:ident, [$( $op:path ),*], [$( $lo ).into(); } TokenKind::Keyword(op) if $( op == $op )||* => { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); lhs = BinOp::new( op.as_binop().expect("Could not get binary operation."), lhs, @@ -233,7 +233,7 @@ where "logical expression (cannot use '??' without parentheses within '||' or '&&')", )); } - let _ = cursor.next(interner)?.expect("'&&' expected"); + let _next = cursor.next(interner)?.expect("'&&' expected"); previous = PreviousExpr::Logical; let rhs = BitwiseORExpression::new(self.allow_in, self.allow_yield, self.allow_await) @@ -249,9 +249,9 @@ where "logical expression (cannot use '??' without parentheses within '||' or '&&')", )); } - let _ = cursor.next(interner)?.expect("'||' expected"); + let _next = cursor.next(interner)?.expect("'||' expected"); previous = PreviousExpr::Logical; - let rhs = ShortCircuitExpression::with_previous( + let rhs = Self::with_previous( self.allow_in, self.allow_yield, self.allow_await, @@ -269,7 +269,7 @@ where "cannot use '??' unparenthesized within '||' or '&&'", )); } - let _ = cursor.next(interner)?.expect("'??' expected"); + let _next = cursor.next(interner)?.expect("'??' expected"); previous = PreviousExpr::Coalesce; let rhs = BitwiseORExpression::new(self.allow_in, self.allow_yield, self.allow_await) @@ -498,7 +498,7 @@ where || op == Punctuator::LessThanOrEq || op == Punctuator::GreaterThanOrEq => { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); lhs = BinOp::new( op.as_binop().expect("Could not get binary operation."), lhs, @@ -511,7 +511,7 @@ where if op == Keyword::InstanceOf || (op == Keyword::In && self.allow_in == AllowIn(true)) => { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); lhs = BinOp::new( op.as_binop().expect("Could not get binary operation."), lhs, diff --git a/boa/src/syntax/parser/expression/primary/array_initializer/mod.rs b/boa/src/syntax/parser/expression/primary/array_initializer/mod.rs index 53f751a87f..d2a4333ae1 100644 --- a/boa/src/syntax/parser/expression/primary/array_initializer/mod.rs +++ b/boa/src/syntax/parser/expression/primary/array_initializer/mod.rs @@ -81,7 +81,7 @@ where break; } - let _ = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd); // Check that there are more tokens to read. + let _next = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd); // Check that there are more tokens to read. if cursor.next_if(Punctuator::Spread, interner)?.is_some() { let node = AssignmentExpression::new(true, self.allow_yield, self.allow_await) diff --git a/boa/src/syntax/parser/expression/primary/async_generator_expression/mod.rs b/boa/src/syntax/parser/expression/primary/async_generator_expression/mod.rs index 3069f018e1..991390e6cd 100644 --- a/boa/src/syntax/parser/expression/primary/async_generator_expression/mod.rs +++ b/boa/src/syntax/parser/expression/primary/async_generator_expression/mod.rs @@ -1,7 +1,7 @@ //! Async Generator Expression Parser //! -//! Implements TokenParser for AsyncGeneratorExpression and outputs -//! an AsyncGeneratorExpr ast node +//! Implements `TokenParser` fo`AsyncGeneratorExpression`on and outputs +//! an `AsyncGeneratorExpr` ast node //! //! More information: //! - [ECMAScript specification][spec] diff --git a/boa/src/syntax/parser/expression/primary/function_expression/mod.rs b/boa/src/syntax/parser/expression/primary/function_expression/mod.rs index 487ea69d92..2cfe0dd6f7 100644 --- a/boa/src/syntax/parser/expression/primary/function_expression/mod.rs +++ b/boa/src/syntax/parser/expression/primary/function_expression/mod.rs @@ -53,9 +53,7 @@ where let name = if let Some(token) = cursor.peek(0, interner)? { match token.kind() { - TokenKind::Identifier(_) - | TokenKind::Keyword(Keyword::Yield) - | TokenKind::Keyword(Keyword::Await) => { + TokenKind::Identifier(_) | TokenKind::Keyword(Keyword::Yield | Keyword::Await) => { Some(BindingIdentifier::new(false, false).parse(cursor, interner)?) } _ => None, diff --git a/boa/src/syntax/parser/expression/primary/object_initializer/mod.rs b/boa/src/syntax/parser/expression/primary/object_initializer/mod.rs index 3ca9e9c15c..36efdc4b86 100644 --- a/boa/src/syntax/parser/expression/primary/object_initializer/mod.rs +++ b/boa/src/syntax/parser/expression/primary/object_initializer/mod.rs @@ -140,57 +140,56 @@ where // IdentifierReference[?Yield, ?Await] if let Some(next_token) = cursor.peek(1, interner)? { - match next_token.kind() { - TokenKind::Punctuator(Punctuator::CloseBlock) - | TokenKind::Punctuator(Punctuator::Comma) => { - let token = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; - let ident = match token.kind() { - TokenKind::Identifier(ident) => Identifier::new(*ident), - TokenKind::Keyword(Keyword::Yield) if self.allow_yield.0 => { - // Early Error: It is a Syntax Error if this production has a [Yield] parameter and StringValue of Identifier is "yield". + if matches!( + next_token.kind(), + TokenKind::Punctuator(Punctuator::CloseBlock | Punctuator::Comma) + ) { + let token = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; + let ident = match token.kind() { + TokenKind::Identifier(ident) => Identifier::new(*ident), + TokenKind::Keyword(Keyword::Yield) if self.allow_yield.0 => { + // Early Error: It is a Syntax Error if this production has a [Yield] parameter and StringValue of Identifier is "yield". + return Err(ParseError::general( + "Unexpected identifier", + token.span().start(), + )); + } + TokenKind::Keyword(Keyword::Yield) if !self.allow_yield.0 => { + if cursor.strict_mode() { + // Early Error: It is a Syntax Error if the code matched by this production is contained in strict mode code. return Err(ParseError::general( - "Unexpected identifier", + "Unexpected strict mode reserved word", token.span().start(), )); } - TokenKind::Keyword(Keyword::Yield) if !self.allow_yield.0 => { - if cursor.strict_mode() { - // Early Error: It is a Syntax Error if the code matched by this production is contained in strict mode code. - return Err(ParseError::general( - "Unexpected strict mode reserved word", - token.span().start(), - )); - } - Identifier::new(Sym::YIELD) - } - TokenKind::Keyword(Keyword::Await) if self.allow_await.0 => { - // Early Error: It is a Syntax Error if this production has an [Await] parameter and StringValue of Identifier is "await". + Identifier::new(Sym::YIELD) + } + TokenKind::Keyword(Keyword::Await) if self.allow_await.0 => { + // Early Error: It is a Syntax Error if this production has an [Await] parameter and StringValue of Identifier is "await". + return Err(ParseError::general( + "Unexpected identifier", + token.span().start(), + )); + } + TokenKind::Keyword(Keyword::Await) if !self.allow_await.0 => { + if cursor.strict_mode() { + // Early Error: It is a Syntax Error if the code matched by this production is contained in strict mode code. return Err(ParseError::general( - "Unexpected identifier", + "Unexpected strict mode reserved word", token.span().start(), )); } - TokenKind::Keyword(Keyword::Await) if !self.allow_await.0 => { - if cursor.strict_mode() { - // Early Error: It is a Syntax Error if the code matched by this production is contained in strict mode code. - return Err(ParseError::general( - "Unexpected strict mode reserved word", - token.span().start(), - )); - } - Identifier::new(Sym::YIELD) - } - _ => { - return Err(ParseError::unexpected( - token.to_string(interner), - token.span(), - "expected IdentifierReference", - )); - } - }; - return Ok(node::PropertyDefinition::property(ident.sym(), ident)); - } - _ => {} + Identifier::new(Sym::YIELD) + } + _ => { + return Err(ParseError::unexpected( + token.to_string(interner), + token.span(), + "expected IdentifierReference", + )); + } + }; + return Ok(node::PropertyDefinition::property(ident.sym(), ident)); } } @@ -286,75 +285,74 @@ where property_name, FunctionExpr::new(None, params.parameters, body), )); - } else { - // MethodDefinition[?Yield, ?Await] -> AsyncMethod[?Yield, ?Await] + } + // MethodDefinition[?Yield, ?Await] -> AsyncMethod[?Yield, ?Await] - let params_start_position = cursor - .expect(Punctuator::OpenParen, "async method definition", interner)? - .span() - .start(); - let params = FormalParameters::new(false, true).parse(cursor, interner)?; - cursor.expect(Punctuator::CloseParen, "async method definition", interner)?; + let params_start_position = cursor + .expect(Punctuator::OpenParen, "async method definition", interner)? + .span() + .start(); + let params = FormalParameters::new(false, true).parse(cursor, interner)?; + cursor.expect(Punctuator::CloseParen, "async method definition", interner)?; - // Early Error: UniqueFormalParameters : FormalParameters - // NOTE: does not appear to be in ECMAScript specs - if params.has_duplicates { - return Err(ParseError::lex(LexError::Syntax( - "Duplicate parameter name not allowed in this context".into(), - params_start_position, - ))); - } + // Early Error: UniqueFormalParameters : FormalParameters + // NOTE: does not appear to be in ECMAScript specs + if params.has_duplicates { + return Err(ParseError::lex(LexError::Syntax( + "Duplicate parameter name not allowed in this context".into(), + params_start_position, + ))); + } - cursor.expect( - TokenKind::Punctuator(Punctuator::OpenBlock), - "async method definition", - interner, - )?; - let body = FunctionBody::new(true, true).parse(cursor, interner)?; - cursor.expect( - TokenKind::Punctuator(Punctuator::CloseBlock), - "async method definition", - interner, - )?; + cursor.expect( + TokenKind::Punctuator(Punctuator::OpenBlock), + "async method definition", + interner, + )?; + let body = FunctionBody::new(true, true).parse(cursor, interner)?; + cursor.expect( + TokenKind::Punctuator(Punctuator::CloseBlock), + "async method definition", + interner, + )?; - // Early Error: It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true - // and IsSimpleParameterList of UniqueFormalParameters is false. - if body.strict() && !params.is_simple { - return Err(ParseError::lex(LexError::Syntax( - "Illegal 'use strict' directive in function with non-simple parameter list" - .into(), - params_start_position, - ))); - } + // Early Error: It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true + // and IsSimpleParameterList of UniqueFormalParameters is false. + if body.strict() && !params.is_simple { + return Err(ParseError::lex(LexError::Syntax( + "Illegal 'use strict' directive in function with non-simple parameter list" + .into(), + params_start_position, + ))); + } - // Early Error: It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also - // occurs in the LexicallyDeclaredNames of GeneratorBody. - { - let lexically_declared_names = body.lexically_declared_names(interner); - for param in params.parameters.as_ref() { - for param_name in param.names() { - if lexically_declared_names.contains(¶m_name) { - return Err(ParseError::lex(LexError::Syntax( - format!( - "Redeclaration of formal parameter `{}`", - interner.resolve_expect(param_name) - ) - .into(), - match cursor.peek(0, interner)? { - Some(token) => token.span().end(), - None => Position::new(1, 1), - }, - ))); - } + // Early Error: It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also + // occurs in the LexicallyDeclaredNames of GeneratorBody. + { + let lexically_declared_names = body.lexically_declared_names(interner); + for param in params.parameters.as_ref() { + for param_name in param.names() { + if lexically_declared_names.contains(¶m_name) { + return Err(ParseError::lex(LexError::Syntax( + format!( + "Redeclaration of formal parameter `{}`", + interner.resolve_expect(param_name) + ) + .into(), + match cursor.peek(0, interner)? { + Some(token) => token.span().end(), + None => Position::new(1, 1), + }, + ))); } } } - return Ok(node::PropertyDefinition::method_definition( - MethodDefinitionKind::Async, - property_name, - FunctionExpr::new(None, params.parameters, body), - )); } + return Ok(node::PropertyDefinition::method_definition( + MethodDefinitionKind::Async, + property_name, + FunctionExpr::new(None, params.parameters, body), + )); } // MethodDefinition[?Yield, ?Await] -> GeneratorMethod[?Yield, ?Await] diff --git a/boa/src/syntax/parser/expression/primary/object_initializer/tests.rs b/boa/src/syntax/parser/expression/primary/object_initializer/tests.rs index 89aa0b6c37..bdfbe9c051 100644 --- a/boa/src/syntax/parser/expression/primary/object_initializer/tests.rs +++ b/boa/src/syntax/parser/expression/primary/object_initializer/tests.rs @@ -405,7 +405,7 @@ fn check_async_method_lineterminator() { dive(){} }; ", - ) + ); } #[test] @@ -416,5 +416,5 @@ fn check_async_gen_method_lineterminator() { * vroom() {} }; ", - ) + ); } diff --git a/boa/src/syntax/parser/expression/update.rs b/boa/src/syntax/parser/expression/update.rs index eab22f76f3..a8dc285556 100644 --- a/boa/src/syntax/parser/expression/update.rs +++ b/boa/src/syntax/parser/expression/update.rs @@ -103,8 +103,7 @@ where { true } - Node::GetConstField(_) => true, - Node::GetField(_) => true, + Node::GetConstField(_) | Node::GetField(_) => true, _ => false, }; if !ok { @@ -128,8 +127,7 @@ where { true } - Node::GetConstField(_) => true, - Node::GetField(_) => true, + Node::GetConstField(_) | Node::GetField(_) => true, _ => false, }; if !ok { diff --git a/boa/src/syntax/parser/function/mod.rs b/boa/src/syntax/parser/function/mod.rs index 6af078fd35..5e7f8d5782 100644 --- a/boa/src/syntax/parser/function/mod.rs +++ b/boa/src/syntax/parser/function/mod.rs @@ -28,7 +28,7 @@ use boa_interner::Sym; use rustc_hash::FxHashSet; use std::io::Read; -/// Intermediate type for a list of FormalParameters with some meta information. +/// Intermediate type for a list of `FormalParameters` with some meta information. pub(in crate::syntax::parser) struct FormalParameterList { pub(in crate::syntax::parser) parameters: Box<[node::FormalParameter]>, pub(in crate::syntax::parser) is_simple: bool, @@ -383,7 +383,7 @@ where /// [spec]: https://tc39.es/ecma262/#prod-FunctionBody pub(in crate::syntax::parser) type FunctionBody = FunctionStatementList; -/// The possible TokenKind which indicate the end of a function statement. +/// The possible `TokenKind` which indicate the end of a function statement. const FUNCTION_BREAK_TOKENS: [TokenKind; 1] = [TokenKind::Punctuator(Punctuator::CloseBlock)]; /// A function statement list diff --git a/boa/src/syntax/parser/statement/block/mod.rs b/boa/src/syntax/parser/statement/block/mod.rs index 6da242f54e..f3452a1877 100644 --- a/boa/src/syntax/parser/statement/block/mod.rs +++ b/boa/src/syntax/parser/statement/block/mod.rs @@ -23,7 +23,7 @@ use crate::{ use std::io::Read; -/// The possible TokenKind which indicate the end of a block statement. +/// The possible `TokenKind` which indicate the end of a block statement. const BLOCK_BREAK_TOKENS: [TokenKind; 1] = [TokenKind::Punctuator(Punctuator::CloseBlock)]; /// A `BlockStatement` is equivalent to a `Block`. diff --git a/boa/src/syntax/parser/statement/break_stm/mod.rs b/boa/src/syntax/parser/statement/break_stm/mod.rs index c2b4aa17a1..c842fb24f5 100644 --- a/boa/src/syntax/parser/statement/break_stm/mod.rs +++ b/boa/src/syntax/parser/statement/break_stm/mod.rs @@ -72,7 +72,7 @@ where let label = if let SemicolonResult::Found(tok) = cursor.peek_semicolon(interner)? { match tok { Some(tok) if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) => { - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; } _ => {} } diff --git a/boa/src/syntax/parser/statement/continue_stm/mod.rs b/boa/src/syntax/parser/statement/continue_stm/mod.rs index ef0d615594..379ba78c92 100644 --- a/boa/src/syntax/parser/statement/continue_stm/mod.rs +++ b/boa/src/syntax/parser/statement/continue_stm/mod.rs @@ -71,7 +71,7 @@ where let label = if let SemicolonResult::Found(tok) = cursor.peek_semicolon(interner)? { match tok { Some(tok) if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) => { - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; } _ => {} } diff --git a/boa/src/syntax/parser/statement/declaration/hoistable/async_generator_decl/mod.rs b/boa/src/syntax/parser/statement/declaration/hoistable/async_generator_decl/mod.rs index 44a4e50ad6..5bd39f2557 100644 --- a/boa/src/syntax/parser/statement/declaration/hoistable/async_generator_decl/mod.rs +++ b/boa/src/syntax/parser/statement/declaration/hoistable/async_generator_decl/mod.rs @@ -1,8 +1,7 @@ //! Async Generator Declaration parsing //! -//! Implements TokenParser for AsyncGeneratorDeclaration and outputs an -//! AsyncGeneratorDecl ast node -//! +//! Implements `TokenParser` for `AsyncGeneratorDeclaration`on and outputs an `AsyncGeneratorDecl` +//! ast node. #[cfg(test)] mod tests; diff --git a/boa/src/syntax/parser/statement/declaration/lexical.rs b/boa/src/syntax/parser/statement/declaration/lexical.rs index 5d5a0d42c2..4b78570c6e 100644 --- a/boa/src/syntax/parser/statement/declaration/lexical.rs +++ b/boa/src/syntax/parser/statement/declaration/lexical.rs @@ -177,7 +177,7 @@ where )); } } else { - const_decls.push(decl) + const_decls.push(decl); } } else { let_decls.push(decl); @@ -195,9 +195,9 @@ where if tk.kind() == &TokenKind::Punctuator(Punctuator::Comma) => { // We discard the comma - let _ = cursor.next(interner)?; + let _comma = cursor.next(interner)?; } - _ => { + SemicolonResult::NotFound(_) => { let next = cursor.next(interner)?.ok_or(ParseError::AbruptEnd)?; return Err(ParseError::expected( [";".to_owned(), "line terminator".to_owned()], diff --git a/boa/src/syntax/parser/statement/declaration/mod.rs b/boa/src/syntax/parser/statement/declaration/mod.rs index da48978e0c..7404fd45ae 100644 --- a/boa/src/syntax/parser/statement/declaration/mod.rs +++ b/boa/src/syntax/parser/statement/declaration/mod.rs @@ -68,19 +68,17 @@ where let tok = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd)?; match tok.kind() { - TokenKind::Keyword(Keyword::Function) | TokenKind::Keyword(Keyword::Async) => { + TokenKind::Keyword(Keyword::Function | Keyword::Async) => { HoistableDeclaration::new(self.allow_yield, self.allow_await, false) .parse(cursor, interner) } - TokenKind::Keyword(Keyword::Const) | TokenKind::Keyword(Keyword::Let) => { - LexicalDeclaration::new( - true, - self.allow_yield, - self.allow_await, - self.const_init_required, - ) - .parse(cursor, interner) - } + TokenKind::Keyword(Keyword::Const | Keyword::Let) => LexicalDeclaration::new( + true, + self.allow_yield, + self.allow_await, + self.const_init_required, + ) + .parse(cursor, interner), _ => unreachable!("unknown token found: {:?}", tok), } } diff --git a/boa/src/syntax/parser/statement/expression/mod.rs b/boa/src/syntax/parser/statement/expression/mod.rs index faacaa25f8..0c1217282b 100644 --- a/boa/src/syntax/parser/statement/expression/mod.rs +++ b/boa/src/syntax/parser/statement/expression/mod.rs @@ -46,7 +46,7 @@ where let next_token = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd)?; match next_token.kind() { - TokenKind::Keyword(Keyword::Function) | TokenKind::Keyword(Keyword::Class) => { + TokenKind::Keyword(Keyword::Function | Keyword::Class) => { return Err(ParseError::general( "expected statement", next_token.span().start(), diff --git a/boa/src/syntax/parser/statement/iteration/for_statement.rs b/boa/src/syntax/parser/statement/iteration/for_statement.rs index a36811676d..f922233581 100644 --- a/boa/src/syntax/parser/statement/iteration/for_statement.rs +++ b/boa/src/syntax/parser/statement/iteration/for_statement.rs @@ -84,14 +84,14 @@ where .kind() { TokenKind::Keyword(Keyword::Var) => { - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; Some( VariableDeclarationList::new(false, self.allow_yield, self.allow_await) .parse(cursor, interner) .map(Node::from)?, ) } - TokenKind::Keyword(Keyword::Let) | TokenKind::Keyword(Keyword::Const) => Some( + TokenKind::Keyword(Keyword::Let | Keyword::Const) => Some( Declaration::new(self.allow_yield, self.allow_await, false) .parse(cursor, interner)?, ), @@ -106,7 +106,7 @@ where Some(tok) if tok.kind() == &TokenKind::Keyword(Keyword::In) && init.is_some() => { let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?; - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; let expr = Expression::new(true, self.allow_yield, self.allow_await) .parse(cursor, interner)?; @@ -128,7 +128,7 @@ where Some(tok) if tok.kind() == &TokenKind::Keyword(Keyword::Of) && init.is_some() => { let init = node_to_iterable_loop_initializer(&init.unwrap(), init_position)?; - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; let iterable = Expression::new(true, self.allow_yield, self.allow_await) .parse(cursor, interner)?; diff --git a/boa/src/syntax/parser/statement/mod.rs b/boa/src/syntax/parser/statement/mod.rs index ddb39a1e49..ec63d96592 100644 --- a/boa/src/syntax/parser/statement/mod.rs +++ b/boa/src/syntax/parser/statement/mod.rs @@ -272,13 +272,13 @@ where { type Output = node::StatementList; - /// The function parses a node::StatementList using the StatementList's - /// break_nodes to know when to terminate. + /// The function parses a `node::StatementList` using the `StatementList`'s + /// `break_nodes` to know when to terminate. /// - /// Returns a ParseError::AbruptEnd if end of stream is reached before a + /// Returns a `ParseError::AbruptEnd` if end of stream is reached before a /// break token. /// - /// Returns a ParseError::unexpected if an unexpected token is found. + /// Returns a `ParseError::unexpected` if an unexpected token is found. /// /// Note that the last token which causes the parse to finish is not /// consumed. @@ -469,7 +469,7 @@ where let tok = cursor.peek(0, interner)?.ok_or(ParseError::AbruptEnd)?; match *tok.kind() { - TokenKind::Keyword(Keyword::Function) | TokenKind::Keyword(Keyword::Async) => { + TokenKind::Keyword(Keyword::Function | Keyword::Async) => { if strict_mode && self.in_block { return Err(ParseError::lex(LexError::Syntax( "Function declaration in blocks not allowed in strict mode".into(), @@ -478,7 +478,7 @@ where } Declaration::new(self.allow_yield, self.allow_await, true).parse(cursor, interner) } - TokenKind::Keyword(Keyword::Const) | TokenKind::Keyword(Keyword::Let) => { + TokenKind::Keyword(Keyword::Const | Keyword::Let) => { Declaration::new(self.allow_yield, self.allow_await, true).parse(cursor, interner) } _ => Statement::new(self.allow_yield, self.allow_await, self.allow_return) @@ -585,7 +585,7 @@ where } } -/// ObjectBindingPattern pattern parsing. +/// `ObjectBindingPattern` pattern parsing. /// /// More information: /// - [ECMAScript specification][spec] @@ -696,7 +696,7 @@ where if let Some(peek_token) = cursor.peek(0, interner)? { match peek_token.kind() { TokenKind::Punctuator(Punctuator::OpenBlock) => { - let bindings = ObjectBindingPattern::new( + let bindings = Self::new( self.allow_in, self.allow_yield, self.allow_await, @@ -866,7 +866,7 @@ where } } -/// ArrayBindingPattern pattern parsing. +/// `ArrayBindingPattern` pattern parsing. /// /// More information: /// - [ECMAScript specification][spec] @@ -970,12 +970,9 @@ where }); } TokenKind::Punctuator(Punctuator::OpenBracket) => { - let bindings = ArrayBindingPattern::new( - self.allow_in, - self.allow_yield, - self.allow_await, - ) - .parse(cursor, interner)?; + let bindings = + Self::new(self.allow_in, self.allow_yield, self.allow_await) + .parse(cursor, interner)?; patterns.push(BindingPatternTypeArray::BindingPatternRest { pattern: DeclarationPattern::Array(DeclarationPatternArray::new( bindings, None, @@ -1037,9 +1034,8 @@ where TokenKind::Punctuator(Punctuator::OpenBracket) => { last_elision_or_first = false; - let bindings = - ArrayBindingPattern::new(self.allow_in, self.allow_yield, self.allow_await) - .parse(cursor, interner)?; + let bindings = Self::new(self.allow_in, self.allow_yield, self.allow_await) + .parse(cursor, interner)?; match cursor .peek(0, interner)? @@ -1083,7 +1079,7 @@ where patterns.push(BindingPatternTypeArray::SingleName { ident, default_init: Some(default_init), - }) + }); } _ => { patterns.push(BindingPatternTypeArray::SingleName { diff --git a/boa/src/syntax/parser/statement/return_stm/mod.rs b/boa/src/syntax/parser/statement/return_stm/mod.rs index cc79b8d77c..dab356b2f6 100644 --- a/boa/src/syntax/parser/statement/return_stm/mod.rs +++ b/boa/src/syntax/parser/statement/return_stm/mod.rs @@ -62,7 +62,7 @@ where if let SemicolonResult::Found(tok) = cursor.peek_semicolon(interner)? { match tok { Some(tok) if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) => { - let _ = cursor.next(interner)?; + let _next = cursor.next(interner)?; } _ => {} } diff --git a/boa/src/syntax/parser/statement/switch/mod.rs b/boa/src/syntax/parser/statement/switch/mod.rs index 1e08bfa386..bf839fd081 100644 --- a/boa/src/syntax/parser/statement/switch/mod.rs +++ b/boa/src/syntax/parser/statement/switch/mod.rs @@ -15,7 +15,7 @@ use crate::{ use std::io::Read; -/// The possible TokenKind which indicate the end of a case statement. +/// The possible `TokenKind` which indicate the end of a case statement. const CASE_BREAK_TOKENS: [TokenKind; 3] = [ TokenKind::Punctuator(Punctuator::CloseBlock), TokenKind::Keyword(Keyword::Case), diff --git a/boa/src/syntax/parser/statement/switch/tests.rs b/boa/src/syntax/parser/statement/switch/tests.rs index d57bf1b6af..4c12ce79e3 100644 --- a/boa/src/syntax/parser/statement/switch/tests.rs +++ b/boa/src/syntax/parser/statement/switch/tests.rs @@ -110,7 +110,7 @@ fn check_switch_seperated_defaults() { ); } -/// Example of JS code https://jsfiddle.net/zq6jx47h/4/. +/// Example of JS code . #[test] fn check_seperated_switch() { let s = r#" diff --git a/boa/src/syntax/parser/statement/throw/mod.rs b/boa/src/syntax/parser/statement/throw/mod.rs index 7bb5e1dd3b..a30864e208 100644 --- a/boa/src/syntax/parser/statement/throw/mod.rs +++ b/boa/src/syntax/parser/statement/throw/mod.rs @@ -61,7 +61,7 @@ where Expression::new(true, self.allow_yield, self.allow_await).parse(cursor, interner)?; if let Some(tok) = cursor.peek(0, interner)? { if tok.kind() == &TokenKind::Punctuator(Punctuator::Semicolon) { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); } } diff --git a/boa/src/syntax/parser/statement/try_stm/catch.rs b/boa/src/syntax/parser/statement/try_stm/catch.rs index 8c1b907cc3..fa5a8505d0 100644 --- a/boa/src/syntax/parser/statement/try_stm/catch.rs +++ b/boa/src/syntax/parser/statement/try_stm/catch.rs @@ -125,7 +125,7 @@ where } } -/// CatchParameter parsing +/// `CatchParameter` parsing /// /// More information: /// - [MDN documentation][mdn] diff --git a/boa/src/syntax/parser/statement/variable/mod.rs b/boa/src/syntax/parser/statement/variable/mod.rs index 1751ebe360..2b1cb6b1cf 100644 --- a/boa/src/syntax/parser/statement/variable/mod.rs +++ b/boa/src/syntax/parser/statement/variable/mod.rs @@ -130,7 +130,7 @@ where SemicolonResult::NotFound(tk) if tk.kind() == &TokenKind::Punctuator(Punctuator::Comma) => { - let _ = cursor.next(interner).expect("token disappeared"); + let _next = cursor.next(interner).expect("token disappeared"); } _ => break, } diff --git a/boa/src/tests.rs b/boa/src/tests.rs index 53a5d6fae8..3a5824c17a 100644 --- a/boa/src/tests.rs +++ b/boa/src/tests.rs @@ -1306,7 +1306,7 @@ fn assignment_to_non_assignable() { "3 -= 5", "3 *= 5", "3 /= 5", "3 %= 5", "3 &= 5", "3 ^= 5", "3 |= 5", "3 += 5", "3 = 5", ]; - for case in test_cases.iter() { + for case in &test_cases { let string = forward(&mut context, case); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); @@ -1322,7 +1322,7 @@ fn multicharacter_assignment_to_non_assignable() { let test_cases = ["3 **= 5", "3 <<= 5", "3 >>= 5"]; - for case in test_cases.iter() { + for case in &test_cases { let string = dbg!(forward(&mut context, case)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); @@ -1337,7 +1337,7 @@ fn multicharacter_bitwise_assignment_to_non_assignable() { // Disabled - awaiting implementation. let test_cases = ["3 >>>= 5", "3 &&= 5", "3 ||= 5", "3 ??= 5"]; - for case in test_cases.iter() { + for case in &test_cases { let string = dbg!(forward(&mut context, case)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); @@ -1357,11 +1357,11 @@ fn assign_to_array_decl() { #[test] fn assign_to_object_decl() { - let mut context = Context::default(); - const ERR_MSG: &str = "Uncaught \"SyntaxError\": \"unexpected token '=', primary expression at line 1, col 8\""; + let mut context = Context::default(); + assert_eq!(forward(&mut context, "{a: 3} = {a: 5};"), ERR_MSG); } @@ -1477,7 +1477,7 @@ fn test_strict_mode_reserved_name() { "var yield = 10;", ]; - for case in test_cases.iter() { + for case in &test_cases { let mut context = Context::default(); let scenario = format!("'use strict'; \n {}", case); diff --git a/boa/src/value/conversions.rs b/boa/src/value/conversions.rs index b0d1417fce..667194642d 100644 --- a/boa/src/value/conversions.rs +++ b/boa/src/value/conversions.rs @@ -1,9 +1,9 @@ -use super::*; +use super::{BoaProfiler, Display, JsBigInt, JsObject, JsString, JsSymbol, JsValue}; use std::convert::TryFrom; -impl From<&JsValue> for JsValue { +impl From<&Self> for JsValue { #[inline] - fn from(value: &JsValue) -> Self { + fn from(value: &Self) -> Self { value.clone() } } @@ -23,14 +23,14 @@ where impl From for JsValue { #[inline] fn from(value: char) -> Self { - JsValue::new(value.to_string()) + Self::new(value.to_string()) } } impl From for JsValue { #[inline] fn from(value: JsSymbol) -> Self { - JsValue::Symbol(value) + Self::Symbol(value) } } @@ -48,67 +48,67 @@ impl From for JsValue { #[inline] fn from(value: f64) -> Self { // if value as i32 as f64 == value { - // JsValue::Integer(value as i32) + // Self::Integer(value as i32) // } else { - JsValue::Rational(value) + Self::Rational(value) // } } } impl From for JsValue { #[inline] - fn from(value: u32) -> JsValue { + fn from(value: u32) -> Self { if let Ok(integer) = i32::try_from(value) { - JsValue::Integer(integer) + Self::Integer(integer) } else { - JsValue::Rational(value.into()) + Self::Rational(value.into()) } } } impl From for JsValue { #[inline] - fn from(value: i32) -> JsValue { - JsValue::Integer(value) + fn from(value: i32) -> Self { + Self::Integer(value) } } impl From for JsValue { #[inline] fn from(value: JsBigInt) -> Self { - JsValue::BigInt(value) + Self::BigInt(value) } } impl From for JsValue { #[inline] - fn from(value: usize) -> JsValue { + fn from(value: usize) -> Self { if let Ok(value) = i32::try_from(value) { - JsValue::Integer(value) + Self::Integer(value) } else { - JsValue::Rational(value as f64) + Self::Rational(value as f64) } } } impl From for JsValue { #[inline] - fn from(value: u64) -> JsValue { + fn from(value: u64) -> Self { if let Ok(value) = i32::try_from(value) { - JsValue::Integer(value) + Self::Integer(value) } else { - JsValue::Rational(value as f64) + Self::Rational(value as f64) } } } impl From for JsValue { #[inline] - fn from(value: i64) -> JsValue { + fn from(value: i64) -> Self { if let Ok(value) = i32::try_from(value) { - JsValue::Integer(value) + Self::Integer(value) } else { - JsValue::Rational(value as f64) + Self::Rational(value as f64) } } } @@ -116,7 +116,7 @@ impl From for JsValue { impl From for JsValue { #[inline] fn from(value: bool) -> Self { - JsValue::Boolean(value) + Self::Boolean(value) } } @@ -124,7 +124,7 @@ impl From for JsValue { #[inline] fn from(object: JsObject) -> Self { let _timer = BoaProfiler::global().start_event("From", "value"); - JsValue::Object(object) + Self::Object(object) } } @@ -141,19 +141,19 @@ impl Display for TryFromObjectError { impl From<()> for JsValue { #[inline] fn from(_: ()) -> Self { - JsValue::null() + Self::null() } } impl From> for JsValue where - T: Into, + T: Into, { #[inline] fn from(value: Option) -> Self { match value { Some(value) => value.into(), - None => JsValue::null(), + None => Self::null(), } } } diff --git a/boa/src/value/display.rs b/boa/src/value/display.rs index 3f8a671131..ab59ff3b3c 100644 --- a/boa/src/value/display.rs +++ b/boa/src/value/display.rs @@ -1,6 +1,6 @@ -use crate::object::ObjectKind; +use crate::{object::ObjectKind, property::PropertyDescriptor}; -use super::*; +use super::{fmt, Display, HashSet, JsValue, PropertyKey}; /// This object is used for displaying a `Value`. #[derive(Debug, Clone, Copy)] @@ -14,7 +14,7 @@ pub struct ValueDisplay<'value> { /// - The object to be printed /// - The function with which to print /// - The indentation for the current level (for nested objects) -/// - A HashSet with the addresses of the already printed objects for the current branch +/// - A `HashSet` with the addresses of the already printed objects for the current branch /// (used to avoid infinite loops when there are cyclic deps) macro_rules! print_obj_value { (all of $obj:expr, $display_fn:ident, $indent:expr, $encounters:expr) => { @@ -126,7 +126,7 @@ pub(crate) fn log_string_from(x: &JsValue, print_internals: bool, print_children .properties() .get(&i.into()) // FIXME: handle accessor descriptors - .and_then(|p| p.value()) + .and_then(PropertyDescriptor::value) .unwrap_or(&JsValue::Undefined), print_internals, false, @@ -196,30 +196,6 @@ pub(crate) fn display_obj(v: &JsValue, print_internals: bool) -> String { my_ptr as usize } - // We keep track of which objects we have encountered by keeping their - // in-memory address in this set - let mut encounters = HashSet::new(); - - if let JsValue::Object(object) = v { - if object.borrow().is_error() { - let name = v - .get_property("name") - .as_ref() - .and_then(|d| d.value()) - .unwrap_or(&JsValue::Undefined) - .display() - .to_string(); - let message = v - .get_property("message") - .as_ref() - .and_then(|d| d.value()) - .unwrap_or(&JsValue::Undefined) - .display() - .to_string(); - return format!("{}: {}", name, message); - } - } - fn display_obj_internal( data: &JsValue, encounters: &mut HashSet, @@ -260,6 +236,30 @@ pub(crate) fn display_obj(v: &JsValue, print_internals: bool) -> String { } } + // We keep track of which objects we have encountered by keeping their + // in-memory address in this set + let mut encounters = HashSet::new(); + + if let JsValue::Object(object) = v { + if object.borrow().is_error() { + let name = v + .get_property("name") + .as_ref() + .and_then(PropertyDescriptor::value) + .unwrap_or(&JsValue::Undefined) + .display() + .to_string(); + let message = v + .get_property("message") + .as_ref() + .and_then(PropertyDescriptor::value) + .unwrap_or(&JsValue::Undefined) + .display() + .to_string(); + return format!("{}: {}", name, message); + } + } + display_obj_internal(v, &mut encounters, 4, print_internals) } diff --git a/boa/src/value/equality.rs b/boa/src/value/equality.rs index 89ef68fbc2..1039d61d90 100644 --- a/boa/src/value/equality.rs +++ b/boa/src/value/equality.rs @@ -1,4 +1,4 @@ -use super::*; +use super::{JsBigInt, JsObject, JsResult, JsValue, PreferredType}; use crate::{builtins::Number, Context}; impl JsValue { @@ -53,12 +53,8 @@ impl JsValue { // 4. If Type(x) is String and Type(y) is Number, return the result of the comparison ! ToNumber(x) == y. // // https://github.com/rust-lang/rust/issues/54883 - (Self::Integer(_), Self::String(_)) - | (Self::Rational(_), Self::String(_)) - | (Self::String(_), Self::Integer(_)) - | (Self::String(_), Self::Rational(_)) - | (Self::Rational(_), Self::Boolean(_)) - | (Self::Integer(_), Self::Boolean(_)) => { + (Self::Integer(_) | Self::Rational(_), Self::String(_) | Self::Boolean(_)) + | (Self::String(_), Self::Integer(_) | Self::Rational(_)) => { let x = self.to_number(context)?; let y = other.to_number(context)?; Number::equal(x, y) @@ -80,10 +76,10 @@ impl JsValue { }, // 8. If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y. - (Self::Boolean(x), _) => return other.equals(&JsValue::new(*x as i32), context), + (Self::Boolean(x), _) => return other.equals(&Self::new(*x as i32), context), // 9. If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y). - (_, Self::Boolean(y)) => return self.equals(&JsValue::new(*y as i32), context), + (_, Self::Boolean(y)) => return self.equals(&Self::new(*y as i32), context), // 10. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return the result // of the comparison x == ? ToPrimitive(y). @@ -119,7 +115,7 @@ impl JsValue { /// - [ECMAScript][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-samevalue - pub fn same_value(x: &JsValue, y: &JsValue) -> bool { + pub fn same_value(x: &Self, y: &Self) -> bool { // 1. If Type(x) is different from Type(y), return false. if x.get_type() != y.get_type() { return false; @@ -128,11 +124,11 @@ impl JsValue { match (x, y) { // 2. If Type(x) is Number or BigInt, then // a. Return ! Type(x)::SameValue(x, y). - (JsValue::BigInt(x), JsValue::BigInt(y)) => JsBigInt::same_value(x, y), - (JsValue::Rational(x), JsValue::Rational(y)) => Number::same_value(*x, *y), - (JsValue::Rational(x), JsValue::Integer(y)) => Number::same_value(*x, f64::from(*y)), - (JsValue::Integer(x), JsValue::Rational(y)) => Number::same_value(f64::from(*x), *y), - (JsValue::Integer(x), JsValue::Integer(y)) => x == y, + (Self::BigInt(x), Self::BigInt(y)) => JsBigInt::same_value(x, y), + (Self::Rational(x), Self::Rational(y)) => Number::same_value(*x, *y), + (Self::Rational(x), Self::Integer(y)) => Number::same_value(*x, f64::from(*y)), + (Self::Integer(x), Self::Rational(y)) => Number::same_value(f64::from(*x), *y), + (Self::Integer(x), Self::Integer(y)) => x == y, // 3. Return ! SameValueNonNumeric(x, y). (_, _) => Self::same_value_non_numeric(x, y), @@ -142,13 +138,13 @@ impl JsValue { /// The internal comparison abstract operation `SameValueZero(x, y)`, /// where `x` and `y` are ECMAScript language values, produces `true` or `false`. /// - /// `SameValueZero` differs from SameValue only in its treatment of `+0` and `-0`. + /// `SameValueZero` differs from `SameValue` only in its treatment of `+0` and `-0`. /// /// More information: /// - [ECMAScript][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-samevaluezero - pub fn same_value_zero(x: &JsValue, y: &JsValue) -> bool { + pub fn same_value_zero(x: &Self, y: &Self) -> bool { if x.get_type() != y.get_type() { return false; } @@ -172,7 +168,7 @@ impl JsValue { } } - fn same_value_non_numeric(x: &JsValue, y: &JsValue) -> bool { + fn same_value_non_numeric(x: &Self, y: &Self) -> bool { debug_assert!(x.get_type() == y.get_type()); match (x, y) { (JsValue::Null, JsValue::Null) | (JsValue::Undefined, JsValue::Undefined) => true, diff --git a/boa/src/value/hash.rs b/boa/src/value/hash.rs index 8ffafc04f3..4498eca035 100644 --- a/boa/src/value/hash.rs +++ b/boa/src/value/hash.rs @@ -1,5 +1,4 @@ -use super::*; - +use super::JsValue; use crate::builtins::Number; use std::hash::{Hash, Hasher}; diff --git a/boa/src/value/mod.rs b/boa/src/value/mod.rs index cdcb74fc60..3406cb973b 100644 --- a/boa/src/value/mod.rs +++ b/boa/src/value/mod.rs @@ -24,7 +24,7 @@ use std::{ collections::HashSet, convert::TryFrom, fmt::{self, Display}, - ops::{Deref, Sub}, + ops::Sub, str::FromStr, }; @@ -75,7 +75,7 @@ pub enum JsValue { Symbol(JsSymbol), } -/// Represents the result of ToIntegerOrInfinity operation +/// Represents the result of `ToIntegerOrInfinity` operation #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum IntegerOrInfinity { Integer(i64), @@ -140,7 +140,7 @@ impl JsValue { /// It determines if the value is a callable function with a `[[Call]]` internal method. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-iscallable #[inline] @@ -207,7 +207,7 @@ impl JsValue { pub fn is_integer(&self) -> bool { // If it can fit in a i32 and the trucated version is // equal to the original then it is an integer. - let is_racional_intiger = |n: f64| n == ((n as i32) as f64); + let is_racional_intiger = |n: f64| n == f64::from(n as i32); match *self { Self::Integer(_) => true, @@ -266,7 +266,7 @@ impl JsValue { matches!(self, Self::BigInt(_)) } - /// Returns an optional reference to a `BigInt` if the value is a BigInt primitive. + /// Returns an optional reference to a `BigInt` if the value is a `BigInt` primitive. #[inline] pub fn as_bigint(&self) -> Option<&JsBigInt> { match self { @@ -314,15 +314,17 @@ impl JsValue { object .prototype() .as_ref() - .map_or(JsValue::Null, |obj| obj.clone().into()) + .map_or(Self::Null, |obj| obj.clone().into()) .get_property(key) } _ => None, } } - /// Resolve the property in the object and get its value, or undefined if this is not an object or the field doesn't exist - /// get_field receives a Property from get_prop(). It should then return the `[[Get]]` result value if that's set, otherwise fall back to `[[Value]]` + /** + Resolve the property in the object and get its value, or undefined if this is not an object or the field doesn't exist + `get_field` receives a Property from get_prop(). It should then return the `[[Get]]` result value if that's set, otherwise fall back to `[[Value]]` + */ pub(crate) fn get_field(&self, key: K, context: &mut Context) -> JsResult where K: Into, @@ -332,7 +334,7 @@ impl JsValue { obj.clone() .__get__(&key.into(), obj.clone().into(), context) } else { - Ok(JsValue::undefined()) + Ok(Self::undefined()) } } @@ -351,10 +353,10 @@ impl JsValue { value: V, throw: bool, context: &mut Context, - ) -> JsResult + ) -> JsResult where K: Into, - V: Into, + V: Into, { // 1. Assert: Type(O) is Object. // TODO: Currently the value may not be an object. @@ -375,9 +377,8 @@ impl JsValue { // 6. Return success. if !success && throw { return context.throw_type_error("Cannot assign value to property"); - } else { - return Ok(value); } + return Ok(value); } Ok(value) } @@ -402,14 +403,14 @@ impl JsValue { } } - /// The abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. + /// The abstract operation `ToPrimitive` takes an input argument and an optional argumen`PreferredType`pe. /// /// pub fn to_primitive( &self, context: &mut Context, preferred_type: PreferredType, - ) -> JsResult { + ) -> JsResult { // 1. Assert: input is an ECMAScript language value. (always a value not need to check) // 2. If Type(input) is Object, then if self.is_object() { @@ -529,7 +530,7 @@ impl JsValue { /// Converts the value to an Object. /// - /// This function is equivalent to `Object(value)` in JavaScript + /// This function is equivalent to `Object(value)` in JavaScript. /// /// See: pub fn to_object(&self, context: &mut Context) -> JsResult { @@ -817,8 +818,8 @@ impl JsValue { let int64_bit = n.as_inner().mod_floor(&TWO_E_64); // 3. If int64bit ≥ 2^63, return ℤ(int64bit - 2^64); otherwise return ℤ(int64bit). - if &int64_bit >= TWO_E_63.deref() { - Ok(int64_bit.sub(TWO_E_64.deref())) + if int64_bit >= *TWO_E_63 { + Ok(int64_bit.sub(&*TWO_E_64)) } else { Ok(int64_bit) } @@ -948,7 +949,7 @@ impl JsValue { /// [table]: https://tc39.es/ecma262/#table-14 /// [spec]: https://tc39.es/ecma262/#sec-requireobjectcoercible #[inline] - pub fn require_object_coercible(&self, context: &mut Context) -> JsResult<&JsValue> { + pub fn require_object_coercible(&self, context: &mut Context) -> JsResult<&Self> { if self.is_null_or_undefined() { context.throw_type_error("cannot convert null or undefined to Object") } else { @@ -1003,7 +1004,7 @@ impl JsValue { /// given ECMA Value. /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-typeof-operator pub fn type_of(&self) -> JsString { diff --git a/boa/src/value/operations.rs b/boa/src/value/operations.rs index 87654d2ca9..5597c1686f 100644 --- a/boa/src/value/operations.rs +++ b/boa/src/value/operations.rs @@ -1,9 +1,12 @@ -use super::*; +use super::{ + Context, FromStr, JsBigInt, JsResult, JsString, JsValue, Numeric, PreferredType, TryFrom, + WellKnownSymbols, +}; use crate::builtins::number::{f64_to_int32, f64_to_uint32, Number}; impl JsValue { #[inline] - pub fn add(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn add(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) + f64::from(*y)), @@ -43,7 +46,7 @@ impl JsValue { } #[inline] - pub fn sub(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn sub(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) - f64::from(*y)), @@ -67,7 +70,7 @@ impl JsValue { } #[inline] - pub fn mul(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn mul(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) * f64::from(*y)), @@ -91,7 +94,7 @@ impl JsValue { } #[inline] - pub fn div(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn div(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) / f64::from(*y)), @@ -125,7 +128,7 @@ impl JsValue { } #[inline] - pub fn rem(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn rem(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => { @@ -172,7 +175,7 @@ impl JsValue { } #[inline] - pub fn pow(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn pow(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x).powi(*y)), @@ -198,7 +201,7 @@ impl JsValue { } #[inline] - pub fn bitand(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn bitand(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(x & y), @@ -228,7 +231,7 @@ impl JsValue { } #[inline] - pub fn bitor(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn bitor(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(x | y), @@ -258,7 +261,7 @@ impl JsValue { } #[inline] - pub fn bitxor(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn bitxor(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(x ^ y), @@ -288,7 +291,7 @@ impl JsValue { } #[inline] - pub fn shl(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn shl(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(x.wrapping_shl(*y as u32)), @@ -322,7 +325,7 @@ impl JsValue { } #[inline] - pub fn shr(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn shr(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new(x.wrapping_shr(*y as u32)), @@ -356,7 +359,7 @@ impl JsValue { } #[inline] - pub fn ushr(&self, other: &Self, context: &mut Context) -> JsResult { + pub fn ushr(&self, other: &Self, context: &mut Context) -> JsResult { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::new((*x as u32).wrapping_shr(*y as u32)), @@ -391,11 +394,11 @@ impl JsValue { /// Abstract operation `InstanceofOperator ( V, target )` /// /// More information: - /// - [EcmaScript reference][spec] + /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-instanceofoperator #[inline] - pub fn instance_of(&self, target: &JsValue, context: &mut Context) -> JsResult { + pub fn instance_of(&self, target: &Self, context: &mut Context) -> JsResult { // 1. If Type(target) is not Object, throw a TypeError exception. if !target.is_object() { return context.throw_type_error(format!( @@ -415,7 +418,7 @@ impl JsValue { } None if target.is_callable() => { // 5. Return ? OrdinaryHasInstance(target, V). - JsValue::ordinary_has_instance(target, self, context) + Self::ordinary_has_instance(target, self, context) } None => { // 4. If IsCallable(target) is false, throw a TypeError exception. @@ -425,7 +428,7 @@ impl JsValue { } #[inline] - pub fn neg(&self, context: &mut Context) -> JsResult { + pub fn neg(&self, context: &mut Context) -> JsResult { Ok(match *self { Self::Symbol(_) | Self::Undefined => Self::new(f64::NAN), Self::Object(_) => Self::new(match self.to_numeric_number(context) { @@ -458,7 +461,7 @@ impl JsValue { /// In addition to `x` and `y` the algorithm takes a Boolean flag named `LeftFirst` as a parameter. /// The flag is used to control the order in which operations with potentially visible side-effects /// are performed upon `x` and `y`. It is necessary because ECMAScript specifies left to right evaluation - /// of expressions. The default value of LeftFirst is `true` and indicates that the `x` parameter + /// of expressions. The default value of `LeftFirst` is `true` and indicates that the `x` parameter /// corresponds to an expression that occurs to the left of the `y` parameter's corresponding expression. /// /// If `LeftFirst` is `false`, the reverse is the case and operations must be performed upon `y` before `x`. @@ -650,9 +653,9 @@ impl From for AbstractRelation { #[inline] fn from(value: bool) -> Self { if value { - AbstractRelation::True + Self::True } else { - AbstractRelation::False + Self::False } } } diff --git a/boa/src/value/tests.rs b/boa/src/value/tests.rs index 836bf4cb1a..71b3a3a1b1 100644 --- a/boa/src/value/tests.rs +++ b/boa/src/value/tests.rs @@ -440,7 +440,7 @@ fn display_boolean_object() { bool "#; let value = forward_val(&mut context, d_obj).unwrap(); - assert_eq!(value.display().to_string(), "Boolean { false }") + assert_eq!(value.display().to_string(), "Boolean { false }"); } #[test] @@ -451,7 +451,7 @@ fn display_number_object() { num "#; let value = forward_val(&mut context, d_obj).unwrap(); - assert_eq!(value.display().to_string(), "Number { 3.14 }") + assert_eq!(value.display().to_string(), "Number { 3.14 }"); } #[test] @@ -462,7 +462,7 @@ fn display_negative_zero_object() { num "#; let value = forward_val(&mut context, d_obj).unwrap(); - assert_eq!(value.display().to_string(), "Number { -0 }") + assert_eq!(value.display().to_string(), "Number { -0 }"); } #[test] @@ -725,7 +725,7 @@ mod cyclic_conversions { console.log(a); "#; - let _ = forward(&mut context, src); + let _res = forward(&mut context, src); // Should not stack overflow } } diff --git a/boa/src/value/type.rs b/boa/src/value/type.rs index 09726bdd66..61e100bae6 100644 --- a/boa/src/value/type.rs +++ b/boa/src/value/type.rs @@ -19,7 +19,7 @@ impl JsValue { /// This is the abstract operation Type(v), as described in /// . /// - /// Check [JsValue::type_of] if you need to call the `typeof` operator. + /// Check [`JsValue::type_of`] if you need to call the `typeof` operator. pub fn get_type(&self) -> Type { match *self { Self::Rational(_) | Self::Integer(_) => Type::Number, diff --git a/boa/src/vm/call_frame.rs b/boa/src/vm/call_frame.rs index cc2d0107c6..1b88163048 100644 --- a/boa/src/vm/call_frame.rs +++ b/boa/src/vm/call_frame.rs @@ -1,5 +1,6 @@ -//! CallFrame -//! This module will provides everything needed to implement the CallFrame +//! `CallFrame` +//! +//! This module will provides everything needed to implement the `CallFrame` use super::CodeBlock; use crate::{gc::Gc, JsValue}; diff --git a/boa/src/vm/code_block.rs b/boa/src/vm/code_block.rs index 8e7bd4b584..8f5bf21489 100644 --- a/boa/src/vm/code_block.rs +++ b/boa/src/vm/code_block.rs @@ -1,6 +1,6 @@ -//! CodeBlock +//! `CodeBlock` //! -//! This module is for the CodeBlock which implements a function representation in the VM +//! This module is for the `CodeBlock` which implements a function representation in the VM use crate::{ builtins::function::{ @@ -14,6 +14,7 @@ use crate::{ }, gc::{Finalize, Gc, Trace}, object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData}, + profiler::BoaProfiler, property::PropertyDescriptor, syntax::ast::node::FormalParameter, vm::{call_frame::FinallyReturn, CallFrame, Opcode}, @@ -46,8 +47,9 @@ unsafe impl Readable for f64 {} /// The internal representation of a JavaScript function. /// -/// A CodeBlock is generated for each function compiled by the [ByteCompiler](crate::bytecompiler::ByteCompiler). -/// It stores the bytecode and the other attributes of the function. +/// A `CodeBlock` is generated for each function compiled by the +/// [`ByteCompiler`](crate::bytecompiler::ByteCompiler). It stores the bytecode and the other +/// attributes of the function. #[derive(Clone, Debug, Trace, Finalize)] pub struct CodeBlock { /// Name of this function @@ -328,7 +330,9 @@ impl ToInternedString for CodeBlock { f.push_str("\nLiterals:\n"); - if !self.literals.is_empty() { + if self.literals.is_empty() { + f.push_str(" "); + } else { for (i, value) in self.literals.iter().enumerate() { f.push_str(&format!( " {:04}: <{}> {}\n", @@ -337,12 +341,12 @@ impl ToInternedString for CodeBlock { value.display() )); } - } else { - f.push_str(" "); } f.push_str("\nNames:\n"); - if !self.variables.is_empty() { + if self.variables.is_empty() { + f.push_str(" "); + } else { for (i, value) in self.variables.iter().enumerate() { f.push_str(&format!( " {:04}: {}\n", @@ -350,12 +354,12 @@ impl ToInternedString for CodeBlock { interner.resolve_expect(*value) )); } - } else { - f.push_str(" "); } f.push_str("\nFunctions:\n"); - if !self.functions.is_empty() { + if self.functions.is_empty() { + f.push_str(" "); + } else { for (i, code) in self.functions.iter().enumerate() { f.push_str(&format!( " {:04}: name: '{}' (length: {})\n", @@ -364,8 +368,6 @@ impl ToInternedString for CodeBlock { code.length )); } - } else { - f.push_str(" "); } f @@ -379,6 +381,8 @@ pub struct JsVmFunction {} impl JsVmFunction { #[allow(clippy::new_ret_no_self)] pub fn new(code: Gc, environment: Environment, context: &mut Context) -> JsObject { + let _timer = BoaProfiler::global().start_event("Identifier", "vm"); + let function_prototype = context.standard_objects().function_object().prototype(); let prototype = context.construct_object(); @@ -510,11 +514,7 @@ impl JsObject { // let local_env = FunctionEnvironmentRecord::new( this_function_object.clone(), - if !lexical_this_mode { - Some(this.clone()) - } else { - None - }, + (!lexical_this_mode).then(|| this.clone()), Some(environment.clone()), // Arrow functions do not have a this binding https://tc39.es/ecma262/#sec-function-environment-records if lexical_this_mode { @@ -544,7 +544,7 @@ impl JsObject { is_simple_parameter_list = is_simple_parameter_list && !param.is_rest_param() && param.is_identifier() - && param.init().is_none() + && param.init().is_none(); } // An arguments object is added when all of the following conditions are met @@ -586,7 +586,7 @@ impl JsObject { }; for arg in args.iter().rev() { - context.vm.push(arg) + context.vm.push(arg); } let param_count = code.params.len(); @@ -677,7 +677,7 @@ impl JsObject { StandardObjects::object_object, context, )?; - JsObject::from_proto_and_data(prototype, ObjectData::ordinary()).into() + Self::from_proto_and_data(prototype, ObjectData::ordinary()).into() }; let lexical_this_mode = code.this_mode == ThisMode::Lexical; @@ -714,7 +714,7 @@ impl JsObject { is_simple_parameter_list = is_simple_parameter_list && !param.is_rest_param() && param.is_identifier() - && param.init().is_none() + && param.init().is_none(); } // An arguments object is added when all of the following conditions are met @@ -756,7 +756,7 @@ impl JsObject { }; for arg in args.iter().rev() { - context.vm.push(arg) + context.vm.push(arg); } let param_count = code.params.len(); diff --git a/boa/src/vm/mod.rs b/boa/src/vm/mod.rs index ba99a3f9ba..d828674566 100644 --- a/boa/src/vm/mod.rs +++ b/boa/src/vm/mod.rs @@ -117,7 +117,7 @@ impl Context { match opcode { Opcode::Nop => {} Opcode::Pop => { - let _ = self.vm.pop(); + let _val = self.vm.pop(); } Opcode::Dup => { let value = self.vm.pop(); @@ -139,11 +139,11 @@ impl Context { Opcode::PushOne => self.vm.push(1), Opcode::PushInt8 => { let value = self.vm.read::(); - self.vm.push(value as i32); + self.vm.push(i32::from(value)); } Opcode::PushInt16 => { let value = self.vm.read::(); - self.vm.push(value as i32); + self.vm.push(i32::from(value)); } Opcode::PushInt32 => { let value = self.vm.read::(); @@ -159,7 +159,7 @@ impl Context { Opcode::PushLiteral => { let index = self.vm.read::() as usize; let value = self.vm.frame().code.literals[index].clone(); - self.vm.push(value) + self.vm.push(value); } Opcode::PushEmptyObject => self.vm.push(self.construct_object()), Opcode::PushNewArray => { @@ -184,9 +184,8 @@ impl Context { if next.done { break; - } else { - Array::add_to_array_object(&array, &[next.value], self)?; } + Array::add_to_array_object(&array, &[next.value], self)?; } self.vm.push(array); @@ -251,7 +250,7 @@ impl Context { self.vm.push(value); } Opcode::Void => { - let _ = self.vm.pop(); + let _old = self.vm.pop(); self.vm.push(JsValue::undefined()); } Opcode::TypeOf => { @@ -275,7 +274,7 @@ impl Context { match value.to_numeric(self)? { Numeric::Number(number) => self.vm.push(number + 1f64), Numeric::BigInt(bigint) => { - self.vm.push(JsBigInt::add(&bigint, &JsBigInt::one())) + self.vm.push(JsBigInt::add(&bigint, &JsBigInt::one())); } } } @@ -284,7 +283,7 @@ impl Context { match value.to_numeric(self)? { Numeric::Number(number) => self.vm.push(number - 1f64), Numeric::BigInt(bigint) => { - self.vm.push(JsBigInt::sub(&bigint, &JsBigInt::one())) + self.vm.push(JsBigInt::sub(&bigint, &JsBigInt::one())); } } } @@ -369,7 +368,7 @@ impl Context { } else { JsValue::Undefined }; - self.vm.push(value) + self.vm.push(value); } Opcode::SetName => { let index = self.vm.read::(); @@ -397,7 +396,7 @@ impl Context { let value = self.vm.pop(); if !value.is_undefined() { self.vm.frame_mut().pc = address as usize; - self.vm.push(value) + self.vm.push(value); } } Opcode::LogicalAnd => { @@ -442,7 +441,7 @@ impl Context { let name: PropertyKey = self.interner().resolve_expect(name).into(); let result = object.get(name, self)?; - self.vm.push(result) + self.vm.push(result); } Opcode::GetPropertyByValue => { let object = self.vm.pop(); @@ -456,7 +455,7 @@ impl Context { let key = key.to_property_key(self)?; let value = object.get(key, self)?; - self.vm.push(value) + self.vm.push(value); } Opcode::SetPropertyByName => { let index = self.vm.read::(); @@ -556,7 +555,7 @@ impl Context { let set = object .__get_own_property__(&name, self)? .as_ref() - .and_then(|a| a.set()) + .and_then(PropertyDescriptor::set) .cloned(); object.__define_own_property__( name, @@ -578,7 +577,7 @@ impl Context { let set = object .__get_own_property__(&name, self)? .as_ref() - .and_then(|a| a.set()) + .and_then(PropertyDescriptor::set) .cloned(); object.__define_own_property__( name, @@ -601,7 +600,7 @@ impl Context { let get = object .__get_own_property__(&name, self)? .as_ref() - .and_then(|a| a.get()) + .and_then(PropertyDescriptor::get) .cloned(); object.__define_own_property__( name, @@ -623,7 +622,7 @@ impl Context { let get = object .__get_own_property__(&name, self)? .as_ref() - .and_then(|a| a.get()) + .and_then(PropertyDescriptor::get) .cloned(); object.__define_own_property__( name, @@ -677,7 +676,7 @@ impl Context { Opcode::TryStart => { let next = self.vm.read::(); let finally = self.vm.read::(); - let finally = if finally != 0 { Some(finally) } else { None }; + let finally = if finally == 0 { None } else { Some(finally) }; self.vm .frame_mut() .catch @@ -685,7 +684,7 @@ impl Context { self.vm.frame_mut().finally_jump.push(None); self.vm.frame_mut().finally_return = FinallyReturn::None; } - Opcode::TryEnd => { + Opcode::TryEnd | Opcode::CatchEnd => { self.vm.frame_mut().catch.pop(); self.vm.frame_mut().finally_return = FinallyReturn::None; } @@ -696,10 +695,6 @@ impl Context { finally: Some(finally), }); } - Opcode::CatchEnd => { - self.vm.frame_mut().catch.pop(); - self.vm.frame_mut().finally_return = FinallyReturn::None; - } Opcode::CatchEnd2 => { self.vm.frame_mut().finally_return = FinallyReturn::None; } @@ -755,15 +750,15 @@ impl Context { let cond = self.vm.pop(); let value = self.vm.pop(); - if !value.strict_equals(&cond) { - self.vm.push(value); - } else { + if value.strict_equals(&cond) { self.vm.frame_mut().pc = address as usize; + } else { + self.vm.push(value); } } Opcode::Default => { let exit = self.vm.read::(); - let _ = self.vm.pop(); + let _val = self.vm.pop(); self.vm.frame_mut().pc = exit as usize; } Opcode::GetFunction => { @@ -938,7 +933,7 @@ impl Context { self.push_environment(new_env); } Opcode::PopEnvironment => { - let _ = self.pop_environment(); + let _env = self.pop_environment(); self.vm.frame_mut().pop_env_on_return -= 1; } Opcode::ForInLoopInitIterator => { @@ -954,7 +949,7 @@ impl Context { let next_function = iterator .get_property("next") .as_ref() - .map(|p| p.expect_value()) + .map(PropertyDescriptor::expect_value) .cloned() .ok_or_else(|| self.construct_type_error("Could not find property `next`"))?; @@ -1051,7 +1046,7 @@ impl Context { } strings.reverse(); let s = JsString::concat_array( - &strings.iter().map(|s| s.as_str()).collect::>(), + &strings.iter().map(JsString::as_str).collect::>(), ); self.vm.push(s); } @@ -1109,14 +1104,14 @@ impl Context { } pub(crate) fn run(&mut self) -> JsResult { - let _timer = BoaProfiler::global().start_event("run", "vm"); - const COLUMN_WIDTH: usize = 26; const TIME_COLUMN_WIDTH: usize = COLUMN_WIDTH / 2; const OPCODE_COLUMN_WIDTH: usize = COLUMN_WIDTH; const OPERAND_COLUMN_WIDTH: usize = COLUMN_WIDTH; const NUMBER_OF_COLUMNS: usize = 4; + let _timer = BoaProfiler::global().start_event("run", "vm"); + if self.vm.trace { let msg = if self.vm.frame().prev.is_some() { " Call Frame " @@ -1218,7 +1213,9 @@ impl Context { if self.vm.trace { println!("\nStack:"); - if !self.vm.stack.is_empty() { + if self.vm.stack.is_empty() { + println!(" "); + } else { for (i, value) in self.vm.stack.iter().enumerate() { println!( "{:04}{:"); } println!("\n"); } diff --git a/boa_cli/Cargo.toml b/boa_cli/Cargo.toml index 92a1f8087e..d8e040db0a 100644 --- a/boa_cli/Cargo.toml +++ b/boa_cli/Cargo.toml @@ -20,7 +20,7 @@ structopt = "0.3.26" serde_json = "1.0.78" colored = "2.0.0" regex = "1.5.4" -lazy_static = "1.4.0" +phf = { version = "0.10.1", features = ["macros"] } [target.x86_64-unknown-linux-gnu.dependencies] jemallocator = "0.3.2" diff --git a/boa_cli/src/helper.rs b/boa_cli/src/helper.rs index 23f6c9ae7d..0db7d70dfc 100644 --- a/boa_cli/src/helper.rs +++ b/boa_cli/src/helper.rs @@ -1,5 +1,5 @@ -use colored::*; -use lazy_static::lazy_static; +use colored::{Color, Colorize}; +use phf::{phf_set, Set}; use regex::{Captures, Regex}; use rustyline::{ error::ReadlineError, @@ -8,7 +8,6 @@ use rustyline::{ }; use rustyline_derive::{Completer, Helper, Hinter}; use std::borrow::Cow; -use std::collections::HashSet; const STRING_COLOR: Color = Color::Green; const KEYWORD_COLOR: Color = Color::Yellow; @@ -86,46 +85,42 @@ impl Highlighter for RLHelper { } } -lazy_static! { - static ref KEYWORDS: HashSet<&'static str> = { - let mut keywords = HashSet::new(); - keywords.insert("break"); - keywords.insert("case"); - keywords.insert("catch"); - keywords.insert("class"); - keywords.insert("const"); - keywords.insert("continue"); - keywords.insert("default"); - keywords.insert("delete"); - keywords.insert("do"); - keywords.insert("else"); - keywords.insert("export"); - keywords.insert("extends"); - keywords.insert("finally"); - keywords.insert("for"); - keywords.insert("function"); - keywords.insert("if"); - keywords.insert("import"); - keywords.insert("instanceof"); - keywords.insert("new"); - keywords.insert("return"); - keywords.insert("super"); - keywords.insert("switch"); - keywords.insert("this"); - keywords.insert("throw"); - keywords.insert("try"); - keywords.insert("typeof"); - keywords.insert("var"); - keywords.insert("void"); - keywords.insert("while"); - keywords.insert("with"); - keywords.insert("yield"); - keywords.insert("await"); - keywords.insert("enum"); - keywords.insert("let"); - keywords - }; -} +static KEYWORDS: Set<&'static str> = phf_set! { + "break", + "case", + "catch", + "class", + "const", + "continue", + "default", + "delete", + "do", + "else", + "export", + "extends", + "finally", + "for", + "function", + "if", + "import", + "instanceof", + "new", + "return", + "super", + "switch", + "this", + "throw", + "try", + "typeof", + "var", + "void", + "while", + "with", + "yield", + "await", + "enum", + "let", +}; struct LineHighlighter; diff --git a/boa_cli/src/main.rs b/boa_cli/src/main.rs index 6ed3de6c34..2cb3fb0d40 100644 --- a/boa_cli/src/main.rs +++ b/boa_cli/src/main.rs @@ -2,8 +2,27 @@ html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" )] +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic +)] #![deny( clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -20,8 +39,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, @@ -32,9 +59,9 @@ )] use boa::{syntax::ast::node::StatementList, Context, Interner}; -use colored::*; +use colored::{Color, Colorize}; use rustyline::{config::Config, error::ReadlineError, EditMode, Editor}; -use std::{fs::read, path::PathBuf}; +use std::{fs::read, io, path::PathBuf}; use structopt::{clap::arg_enum, StructOpt}; mod helper; @@ -143,7 +170,7 @@ where DumpFormat::Debug => println!("{:#?}", ast), DumpFormat::Json => println!("{}", serde_json::to_string(&ast).unwrap()), DumpFormat::JsonPretty => { - println!("{}", serde_json::to_string_pretty(&ast).unwrap()) + println!("{}", serde_json::to_string_pretty(&ast).unwrap()); } }, // Default ast dumping format. @@ -188,7 +215,10 @@ pub fn main() -> Result<(), std::io::Error> { .build(); let mut editor = Editor::with_config(config); - let _ = editor.load_history(CLI_HISTORY); + editor.load_history(CLI_HISTORY).map_err(|err| match err { + ReadlineError::Io(e) => e, + e => io::Error::new(io::ErrorKind::Other, e), + })?; editor.set_helper(Some(helper::RLHelper::new())); let readline = ">> ".color(READLINE_COLOR).bold().to_string(); @@ -196,7 +226,7 @@ pub fn main() -> Result<(), std::io::Error> { loop { match editor.readline(&readline) { Ok(line) if line == ".exit" => break, - Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => break, + Err(ReadlineError::Interrupted | ReadlineError::Eof) => break, Ok(line) => { editor.add_history_entry(&line); @@ -209,7 +239,11 @@ pub fn main() -> Result<(), std::io::Error> { match context.eval(line.trim_end()) { Ok(v) => println!("{}", v.display()), Err(v) => { - eprintln!("{}: {}", "Uncaught".red(), v.display().to_string().red()) + eprintln!( + "{}: {}", + "Uncaught".red(), + v.display().to_string().red() + ); } } } diff --git a/boa_interner/src/lib.rs b/boa_interner/src/lib.rs index db8eb6df9b..b2879bbbaf 100644 --- a/boa_interner/src/lib.rs +++ b/boa_interner/src/lib.rs @@ -12,8 +12,27 @@ html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" )] +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic +)] #![deny( clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -30,8 +49,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, @@ -63,7 +90,7 @@ pub struct Interner { } impl Interner { - /// Creates a new StringInterner with the given initial capacity. + /// Creates a new `StringInterner` with the given initial capacity. #[inline] pub fn with_capacity(cap: usize) -> Self { Self { @@ -128,7 +155,7 @@ impl Interner { /// Shrink backend capacity to fit the interned strings exactly. #[inline] pub fn shrink_to_fit(&mut self) { - self.inner.shrink_to_fit() + self.inner.shrink_to_fit(); } /// Returns the string for the given symbol if any. @@ -189,7 +216,7 @@ where where I: IntoIterator, { - self.inner.extend(iter) + self.inner.extend(iter); } } @@ -218,6 +245,7 @@ impl Default for Interner { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Finalize)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] +#[allow(clippy::unsafe_derive_deserialize)] pub struct Sym { value: NonZeroUsize, } @@ -267,7 +295,7 @@ impl Sym { Self { value } } - /// Retrieves the raw `NonZeroUsize` for this symbol.` + /// Retrieves the raw `NonZeroUsize` for this symbol. const fn as_raw(self) -> NonZeroUsize { self.value } diff --git a/boa_interner/src/tests.rs b/boa_interner/src/tests.rs index 0e833be278..859a92a524 100644 --- a/boa_interner/src/tests.rs +++ b/boa_interner/src/tests.rs @@ -11,7 +11,7 @@ fn check_static_strings() { let mut interner = Interner::default(); for (i, str) in Interner::STATIC_STRINGS.into_iter().enumerate() { - assert_eq!(interner.get_or_intern(str), sym_from_usize(i + 1)) + assert_eq!(interner.get_or_intern(str), sym_from_usize(i + 1)); } } diff --git a/boa_tester/src/exec/js262.rs b/boa_tester/src/exec/js262.rs index b7b3791820..9369502aa9 100644 --- a/boa_tester/src/exec/js262.rs +++ b/boa_tester/src/exec/js262.rs @@ -26,6 +26,7 @@ pub(super) fn init(context: &mut Context) -> JsObject { /// /// Creates a new ECMAScript Realm, defines this API on the new realm's global object, and /// returns the `$262` property of the new realm's global object. +#[allow(clippy::unnecessary_wraps)] fn create_realm(_this: &JsValue, _: &[JsValue], _context: &mut Context) -> JsResult { // eprintln!("called $262.createRealm()"); @@ -52,8 +53,7 @@ fn detach_array_buffer( let array_buffer = args .get(0) - .map(JsValue::as_object) - .flatten() + .and_then(JsValue::as_object) .ok_or_else(|| type_err(context))?; let mut array_buffer = array_buffer.borrow_mut(); let array_buffer = array_buffer @@ -83,7 +83,7 @@ fn detach_array_buffer( /// /// Accepts a string value as its first argument and executes it as an ECMAScript script. fn eval_script(_this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { - if let Some(source_text) = args.get(0).and_then(|val| val.as_string()) { + if let Some(source_text) = args.get(0).and_then(JsValue::as_string) { match context.parse(source_text.as_str()) { // TODO: check strict Err(e) => context.throw_type_error(format!("Uncaught Syntax Error: {}", e)), diff --git a/boa_tester/src/exec/mod.rs b/boa_tester/src/exec/mod.rs index 99ec70053d..b77d606706 100644 --- a/boa_tester/src/exec/mod.rs +++ b/boa_tester/src/exec/mod.rs @@ -33,14 +33,12 @@ impl TestSuite { let tests: Vec<_> = if parallel { self.tests .par_iter() - .map(|test| test.run(harness, verbose)) - .flatten() + .flat_map(|test| test.run(harness, verbose)) .collect() } else { self.tests .iter() - .map(|test| test.run(harness, verbose)) - .flatten() + .flat_map(|test| test.run(harness, verbose)) .collect() }; @@ -79,7 +77,7 @@ impl TestSuite { ignored.to_string().yellow(), (total - passed - ignored).to_string().red(), if panic == 0 {"0".normal()} else {panic.to_string().red()}, - if panic != 0 {" ⚠"} else {""}.red(), + if panic == 0 {""} else {" ⚠"}.red(), (passed as f64 / total as f64) * 100.0 ); } @@ -167,11 +165,7 @@ impl Test { } } Outcome::Negative { - phase: Phase::Parse, - ref error_type, - } - | Outcome::Negative { - phase: Phase::Early, + phase: Phase::Parse | Phase::Early, ref error_type, } => { assert_eq!( @@ -220,18 +214,19 @@ impl Test { } }); - let result = res - .map(|(res, text)| { + let result = res.map_or_else( + |_| { + eprintln!("last panic was on test \"{}\"", self.name); + (TestOutcomeResult::Panic, String::new()) + }, + |(res, text)| { if res { (TestOutcomeResult::Passed, text) } else { (TestOutcomeResult::Failed, text) } - }) - .unwrap_or_else(|_| { - eprintln!("last panic was on test \"{}\"", self.name); - (TestOutcomeResult::Panic, String::new()) - }); + }, + ); if verbose > 1 { println!( @@ -306,7 +301,7 @@ impl Test { })?; // add the $262 object. - let _ = js262::init(&mut context); + let _js262 = js262::init(&mut context); if strict { context diff --git a/boa_tester/src/main.rs b/boa_tester/src/main.rs index 0c82ab6c3c..b0bd6d78dc 100644 --- a/boa_tester/src/main.rs +++ b/boa_tester/src/main.rs @@ -2,13 +2,27 @@ //! //! This crate will run the full ECMAScript test suite (Test262) and report compliance of the //! `boa` context. -#![doc( - html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic )] #![deny( - unused_qualifications, clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -25,8 +39,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, @@ -94,9 +116,9 @@ impl Ignored { impl Default for Ignored { fn default() -> Self { Self { - tests: Default::default(), - features: Default::default(), - files: Default::default(), + tests: FxHashSet::default(), + features: FxHashSet::default(), + files: FxHashSet::default(), flags: TestFlags::empty(), } } @@ -144,10 +166,15 @@ static IGNORED: Lazy = Lazy::new(|| { .trim() .parse::() .expect("invalid flag found"); - ign.flags.insert(flag.into()) + ign.flags.insert(flag.into()); } else { let mut test = line.trim(); - if test.ends_with(".js") { + if test + .rsplit('.') + .next() + .map(|ext| ext.eq_ignore_ascii_case("js")) + == Some(true) + { test = test.strip_suffix(".js").expect("suffix disappeared"); } ign.tests.insert(test.to_owned().into_boxed_str()); @@ -155,7 +182,7 @@ static IGNORED: Lazy = Lazy::new(|| { ign }) } else { - Default::default() + Ignored::default() } }); @@ -396,7 +423,7 @@ impl Test { where N: Into>, { - self.name = name.into() + self.name = name.into(); } } @@ -474,7 +501,7 @@ where } if !result.intersects(Self::default()) { - result |= Self::default() + result |= Self::default(); } result diff --git a/boa_tester/src/read.rs b/boa_tester/src/read.rs index 25407bd875..e02f5883f3 100644 --- a/boa_tester/src/read.rs +++ b/boa_tester/src/read.rs @@ -134,7 +134,7 @@ pub(super) fn read_suite(path: &Path) -> io::Result { } else if IGNORED.contains_file(&entry.file_name().to_string_lossy()) { let mut test = Test::default(); test.set_name(entry.file_name().to_string_lossy()); - tests.push(test) + tests.push(test); } else { tests.push(read_test(entry.path().as_path())?); } diff --git a/boa_tester/src/results.rs b/boa_tester/src/results.rs index 57bddab29e..60c571d6ab 100644 --- a/boa_tester/src/results.rs +++ b/boa_tester/src/results.rs @@ -211,10 +211,10 @@ pub(crate) fn compare_results(base: &Path, new: &Path, markdown: bool) { fn diff_format(diff: isize) -> String { format!( "{}{}{}{}", - if diff != 0 { "**" } else { "" }, + if diff == 0 { "" } else { "**" }, if diff > 0 { "+" } else { "" }, diff.to_formatted_string(&Locale::en), - if diff != 0 { "**" } else { "" } + if diff == 0 { "" } else { "**" } ) } @@ -435,6 +435,7 @@ fn compute_result_diff( ) .into_boxed_str(); + #[allow(clippy::match_same_arms)] match (base_test.result, new_test.result) { (a, b) if a == b => {} (TestOutcomeResult::Ignored, TestOutcomeResult::Failed) => {} @@ -458,7 +459,7 @@ fn compute_result_diff( let new_base = base.join(new_suite.name.as_ref()); let diff = compute_result_diff(new_base.as_path(), base_suite, new_suite); - final_diff.extend(diff) + final_diff.extend(diff); } } diff --git a/boa_unicode/src/lib.rs b/boa_unicode/src/lib.rs index 94af294357..01129b6444 100644 --- a/boa_unicode/src/lib.rs +++ b/boa_unicode/src/lib.rs @@ -10,8 +10,27 @@ html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" )] +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic +)] #![deny( clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -28,8 +47,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, @@ -59,22 +86,22 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (14, 0, 0); /// /// [uax31]: http://unicode.org/reports/tr31 pub trait UnicodeProperties: Sized + Copy { - /// Returns `true` if this value is a member of "ID_Start". + /// Returns `true` if this value is a member of `ID_Start`. fn is_id_start(self) -> bool; - /// Returns `true` if this value is a member of "ID_Continue". + /// Returns `true` if this value is a member of `ID_Continue`. fn is_id_continue(self) -> bool; - /// Returns `true` if this value is a member of "Other_ID_Start". + /// Returns `true` if this value is a member of `Other_ID_Start`. fn is_other_id_start(self) -> bool; - /// Returns `true` if this value is a member of "Other_ID_Continue". + /// Returns `true` if this value is a member of `Other_ID_Continue`. fn is_other_id_continue(self) -> bool; - /// Returns `true` if this value is a member of "Pattern_Syntax". + /// Returns `true` if this value is a member of `Pattern_Syntax`. fn is_pattern_syntax(self) -> bool; - /// Returns `true` if this value is a member of "Pattern_White_Space". + /// Returns `true` if this value is a member of `Pattern_White_Space`. fn is_pattern_whitespace(self) -> bool; } diff --git a/boa_wasm/src/lib.rs b/boa_wasm/src/lib.rs index 9b6efefdd9..81b5309877 100644 --- a/boa_wasm/src/lib.rs +++ b/boa_wasm/src/lib.rs @@ -2,8 +2,27 @@ html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg" )] +#![warn( + clippy::perf, + clippy::single_match_else, + clippy::dbg_macro, + clippy::doc_markdown, + clippy::wildcard_imports, + clippy::struct_excessive_bools, + clippy::doc_markdown, + clippy::semicolon_if_nothing_returned, + clippy::pedantic +)] #![deny( clippy::all, + clippy::cast_lossless, + clippy::redundant_closure_for_method_calls, + clippy::use_self, + clippy::unnested_or_patterns, + clippy::trivially_copy_pass_by_ref, + clippy::needless_pass_by_value, + clippy::match_wildcard_for_single_variants, + clippy::map_unwrap_or, unused_qualifications, unused_import_braces, unused_lifetimes, @@ -20,8 +39,16 @@ future_incompatible, nonstandard_style, )] -#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)] #![allow( + clippy::module_name_repetitions, + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss, + clippy::cast_possible_wrap, + clippy::cast_ptr_alignment, + clippy::missing_panics_doc, + clippy::too_many_lines, + clippy::unreadable_literal, clippy::missing_inline_in_public_items, clippy::cognitive_complexity, clippy::must_use_candidate, diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000000..01610f39cb --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +doc-valid-idents = ['ECMAScript', 'JavaScript', 'SpiderMonkey', 'GitHub'] diff --git a/docs/profiling.md b/docs/profiling.md index 5cf9345803..b532f29b8f 100644 --- a/docs/profiling.md +++ b/docs/profiling.md @@ -19,7 +19,7 @@ when the feature flag is not enabled, you have an empty dummy implementation tha You can run boa using the "profiler" feature flag to enable profiling. Seeing as you'll most likely be using boa_cli you can pass this through, like so: -`cargo run --features Boa/profiler ../tests/js/test.js` +`cargo run --release --features Boa/profiler ../tests/js/test.js` Once finished you should see some trace files left in the directory (boa_cli in this case). In the same directory as the `.events, string_data, string_index` files run `crox my_trace` or whatever the name of the files are. This will generate a chrome_profiler.json file, you can load this into Chrome Dev tools.