Skip to content

Commit

Permalink
Restructure lint lists in boa_engine (#2455)
Browse files Browse the repository at this point in the history
This Pull Request restructures the lint deny/warn/allow lists in `boa_engine`. It adds a lot of documentation to pup functions. There are still a few clippy lints that are not fixed, mainly regarding casting of number types. Fixing those lints effectiveley would in some cases probably require bigger refactors.

This should probably wait for #2449 to be merged, because that PR already fixes that lints regarding the `Date` built-in.
  • Loading branch information
raskad committed Nov 23, 2022
1 parent de737dc commit 5435ae0
Show file tree
Hide file tree
Showing 86 changed files with 1,916 additions and 956 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion boa_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ flowgraph = []
console = []

[dependencies]
boa_unicode.workspace = true
boa_interner.workspace = true
boa_gc.workspace = true
boa_profiler.workspace = true
Expand Down
74 changes: 48 additions & 26 deletions boa_engine/src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ pub struct JsBigInt {
impl JsBigInt {
/// Create a new [`JsBigInt`].
#[inline]
#[must_use]
pub fn new<T: Into<Self>>(value: T) -> Self {
value.into()
}

/// Create a [`JsBigInt`] with value `0`.
#[inline]
#[must_use]
pub fn zero() -> Self {
Self {
inner: Rc::new(RawBigInt::zero()),
Expand All @@ -39,12 +41,14 @@ impl JsBigInt {

/// Check if is zero.
#[inline]
#[must_use]
pub fn is_zero(&self) -> bool {
self.inner.is_zero()
}

/// Create a [`JsBigInt`] with value `1`.
#[inline]
#[must_use]
pub fn one() -> Self {
Self {
inner: Rc::new(RawBigInt::one()),
Expand All @@ -53,12 +57,14 @@ impl JsBigInt {

/// Check if is one.
#[inline]
#[must_use]
pub fn is_one(&self) -> bool {
self.inner.is_one()
}

/// Convert bigint to string with radix.
#[inline]
#[must_use]
pub fn to_string_radix(&self, radix: u32) -> String {
self.inner.to_str_radix(radix)
}
Expand All @@ -67,12 +73,14 @@ impl JsBigInt {
///
/// Returns `f64::INFINITY` if the `BigInt` is too big.
#[inline]
#[must_use]
pub fn to_f64(&self) -> f64 {
self.inner.to_f64().unwrap_or(f64::INFINITY)
}

/// Converts a string to a `BigInt` with the specified radix.
#[inline]
#[must_use]
pub fn from_string_radix(buf: &str, radix: u32) -> Option<Self> {
Some(Self {
inner: Rc::new(RawBigInt::parse_bytes(buf.as_bytes(), radix)?),
Expand All @@ -86,6 +94,7 @@ impl JsBigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-stringtobigint
#[inline]
#[must_use]
pub fn from_string(mut string: &str) -> Option<Self> {
string = string.trim();

Expand Down Expand Up @@ -115,6 +124,7 @@ impl JsBigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-equal
#[inline]
#[must_use]
pub fn same_value_zero(x: &Self, y: &Self) -> bool {
// Return BigInt::equal(x, y)
Self::equal(x, y)
Expand All @@ -128,6 +138,7 @@ impl JsBigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-sameValue
#[inline]
#[must_use]
pub fn same_value(x: &Self, y: &Self) -> bool {
// Return BigInt::equal(x, y)
Self::equal(x, y)
Expand All @@ -143,10 +154,12 @@ impl JsBigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-numeric-types-bigint-sameValueZero
#[inline]
#[must_use]
pub fn equal(x: &Self, y: &Self) -> bool {
x == y
}

/// Returns `x` to the power `y`.
#[inline]
pub fn pow(x: &Self, y: &Self) -> JsResult<Self> {
let y = y
Expand All @@ -168,37 +181,27 @@ impl JsBigInt {
Ok(Self::new(x.inner.as_ref().clone().pow(y)))
}

/// Performs the `>>` operation.
#[inline]
pub fn shift_right(x: &Self, y: &Self) -> JsResult<Self> {
if let Some(n) = y.inner.to_i32() {
let inner = if n > 0 {
x.inner.as_ref().clone().shr(n as usize)
} else {
x.inner.as_ref().clone().shl(n.unsigned_abs())
};

Ok(Self::new(inner))
} else {
Err(JsNativeError::range()
match y.inner.to_i32() {
Some(n) if n > 0 => Ok(Self::new(x.inner.as_ref().clone().shr(n as usize))),
Some(n) => Ok(Self::new(x.inner.as_ref().clone().shl(n.unsigned_abs()))),
None => Err(JsNativeError::range()
.with_message("Maximum BigInt size exceeded")
.into())
.into()),
}
}

/// Performs the `<<` operation.
#[inline]
pub fn shift_left(x: &Self, y: &Self) -> JsResult<Self> {
if let Some(n) = y.inner.to_i32() {
let inner = if n > 0 {
x.inner.as_ref().clone().shl(n as usize)
} else {
x.inner.as_ref().clone().shr(n.unsigned_abs())
};

Ok(Self::new(inner))
} else {
Err(JsNativeError::range()
match y.inner.to_i32() {
Some(n) if n > 0 => Ok(Self::new(x.inner.as_ref().clone().shl(n as usize))),
Some(n) => Ok(Self::new(x.inner.as_ref().clone().shr(n.unsigned_abs()))),
None => Err(JsNativeError::range()
.with_message("Maximum BigInt size exceeded")
.into())
.into()),
}
}

Expand All @@ -211,56 +214,77 @@ impl JsBigInt {
/// assert_eq!((8).mod_floor(&-3), -1);
/// ```
#[inline]
#[must_use]
pub fn mod_floor(x: &Self, y: &Self) -> Self {
Self::new(x.inner.mod_floor(&y.inner))
}

/// Performs the `+` operation.
#[inline]
#[must_use]
pub fn add(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().add(y.inner.as_ref()))
}

/// Performs the `-` operation.
#[inline]
#[must_use]
pub fn sub(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().sub(y.inner.as_ref()))
}

/// Performs the `*` operation.
#[inline]
#[must_use]
pub fn mul(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().mul(y.inner.as_ref()))
}

/// Performs the `/` operation.
#[inline]
#[must_use]
pub fn div(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().div(y.inner.as_ref()))
}

/// Performs the `%` operation.
#[inline]
#[must_use]
pub fn rem(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().rem(y.inner.as_ref()))
}

/// Performs the `&` operation.
#[inline]
#[must_use]
pub fn bitand(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().bitand(y.inner.as_ref()))
}

/// Performs the `|` operation.
#[inline]
#[must_use]
pub fn bitor(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().bitor(y.inner.as_ref()))
}

/// Performs the `^` operation.
#[inline]
#[must_use]
pub fn bitxor(x: &Self, y: &Self) -> Self {
Self::new(x.inner.as_ref().clone().bitxor(y.inner.as_ref()))
}

/// Performs the unary `-` operation.
#[inline]
#[must_use]
pub fn neg(x: &Self) -> Self {
Self::new(x.as_inner().neg())
}

/// Performs the unary `!` operation.
#[inline]
#[must_use]
pub fn not(x: &Self) -> Self {
Self::new(!x.as_inner())
}
Expand Down Expand Up @@ -386,6 +410,7 @@ impl From<usize> for JsBigInt {
}
}

/// The error indicates that the conversion from [`f64`] to [`JsBigInt`] failed.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TryFromF64Error;

Expand All @@ -407,10 +432,7 @@ impl TryFrom<f64> for JsBigInt {
if !Number::equal(n.trunc(), n) {
return Err(TryFromF64Error);
}
match RawBigInt::from_f64(n) {
Some(bigint) => Ok(Self::new(bigint)),
None => Err(TryFromF64Error),
}
RawBigInt::from_f64(n).map_or(Err(TryFromF64Error), |bigint| Ok(Self::new(bigint)))
}
}

Expand Down
7 changes: 7 additions & 0 deletions boa_engine/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! This module implements the `ArrayIterator` object.
//!
//! More information:
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-array-iterator-objects
use crate::{
builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, JsValue},
error::JsNativeError,
Expand Down
30 changes: 14 additions & 16 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,8 @@ impl Array {
// 3. Let A be ! MakeBasicObject(« [[Prototype]], [[Extensible]] »).
// 4. Set A.[[Prototype]] to proto.
// 5. Set A.[[DefineOwnProperty]] as specified in 10.4.2.1.
let prototype = match prototype {
Some(prototype) => prototype,
None => context.intrinsics().constructors().array().prototype(),
};
let prototype =
prototype.unwrap_or_else(|| context.intrinsics().constructors().array().prototype());
let array = JsObject::from_proto_and_data(prototype, ObjectData::array());

// 6. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
Expand Down Expand Up @@ -380,15 +378,15 @@ impl Array {
return Self::array_create(length, None, context);
}

// 7. If IsConstructor(C) is false, throw a TypeError exception.
if let Some(c) = c.as_constructor() {
// 8. Return ? Construct(C, « 𝔽(length) »).
c.construct(&[JsValue::new(length)], Some(c), context)
} else {
Err(JsNativeError::typ()
.with_message("Symbol.species must be a constructor")
.into())
return c.construct(&[JsValue::new(length)], Some(c), context);
}

// 7. If IsConstructor(C) is false, throw a TypeError exception.
Err(JsNativeError::typ()
.with_message("Symbol.species must be a constructor")
.into())
}

/// `Array.from(arrayLike)`
Expand Down Expand Up @@ -670,7 +668,7 @@ impl Array {
let mut n = 0;
// 4. Prepend O to items.
// 5. For each element E of items, do
for item in [JsValue::new(obj)].iter().chain(args.iter()) {
for item in std::iter::once(&JsValue::new(obj)).chain(args.iter()) {
// a. Let spreadable be ? IsConcatSpreadable(E).
let spreadable = Self::is_concat_spreadable(item, context)?;
// b. If spreadable is true, then
Expand Down Expand Up @@ -1776,13 +1774,13 @@ impl Array {
}

// iii. Let shouldFlatten be false
let mut should_flatten = false;

// iv. If depth > 0, then
if depth > 0 {
let should_flatten = if depth > 0 {
// 1. Set shouldFlatten to ? IsArray(element).
should_flatten = element.is_array()?;
}
element.is_array()?
} else {
false
};

// v. If shouldFlatten is true
if should_flatten {
Expand Down
Loading

0 comments on commit 5435ae0

Please sign in to comment.