Skip to content

Commit

Permalink
Added attribute to class and some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Aug 18, 2020
1 parent 3406880 commit d0e8b03
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
38 changes: 26 additions & 12 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ mod tests;
/// Static `prototype`, usually set on constructors as a key to point to their respective prototype object.
pub static PROTOTYPE: &str = "prototype";

/// This trait allows Rust types to be passed around as objects.
///
/// This is automatically implemented, when a type implements `Debug`, `Any` and `Trace`.
pub trait NativeObject: Debug + Any + Trace {
fn as_any(&self) -> &dyn Any;
fn as_mut_any(&mut self) -> &mut dyn Any;
Expand All @@ -62,13 +65,32 @@ impl<T: Any + Debug + Trace> NativeObject for T {
}
}

pub trait Class: NativeObject {
/// Native class.
pub trait Class: NativeObject + Sized {
/// The binding name of the object.
const NAME: &'static str;
/// The amount of arguments the class `constructor` takes.
/// The amount of arguments the class `constructor` takes, default is `0`.
const LENGTH: usize = 0;
/// The attibutes the class will be binded with, default is `writable`, `enumerable`, `configurable`.
const ATTRIBUTE: Attribute = Attribute::ALL;

/// The constructor of the class.
fn constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result<Self>;

/// Initializes the internals and the methods of the class.
fn methods(class: &mut ClassBuilder<'_>) -> Result<()>;
}

/// This is a wrapper around `Class::constructor` that sets the internal data of a class.
///
/// This is automatically implemented, when a type implements `Class`.
pub trait ClassConstructor: Class {
fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result<Value>
where
Self: Sized;
}

/// This is a wrapper around `Self::constructor` that sets the internal data of the class.
impl<T: Class> ClassConstructor for T {
fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result<Value>
where
Self: Sized,
Expand All @@ -77,14 +99,6 @@ pub trait Class: NativeObject {
this.set_data(ObjectData::NativeObject(Box::new(object_instance)));
Ok(this.clone())
}

/// The constructor of the class.
fn constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result<Self>
where
Self: Sized;

/// Initializes the internals and the methods of the class.
fn methods(class: &mut ClassBuilder<'_>) -> Result<()>;
}

/// Class builder which allows adding methods and static methods to the class.
Expand All @@ -98,7 +112,7 @@ pub struct ClassBuilder<'context> {
impl<'context> ClassBuilder<'context> {
pub(crate) fn new<T>(context: &'context mut Interpreter) -> Self
where
T: Class,
T: ClassConstructor,
{
let global = context.global();

Expand Down
4 changes: 4 additions & 0 deletions boa/src/builtins/property/attribute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ bitflags! {
/// None of the flags are present.
const NONE = 0b0000_0000;

/// All the flags set (`WRITABLE`, `ENUMERABLE`, `CONFIGURABLE`).
const ALL = 0b0011_1111;

/// The `Writable` attribute decides whether the value associated with the property can be changed or not, from its initial value.
const WRITABLE = 0b0000_0011;

Expand All @@ -46,6 +49,7 @@ bitflags! {

/// Is the `Configurable` flag defined.
const HAS_CONFIGURABLE = 0b0010_0000;

}
}

Expand Down
8 changes: 6 additions & 2 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
builtins::{
function::{Function, FunctionFlags, NativeFunction},
object::{Class, ClassBuilder, GcObject, Object, ObjectData, PROTOTYPE},
property::PropertyKey,
property::{Property, PropertyKey},
value::{PreferredType, Type, Value},
Console,
},
Expand Down Expand Up @@ -367,7 +367,11 @@ impl Interpreter {
T::methods(&mut class_builder)?;

let class = class_builder.build();
self.global().set_field(T::NAME, class);
let property = Property::data_descriptor(class.into(), T::ATTRIBUTE);
self.global()
.as_object_mut()
.unwrap()
.insert_property(T::NAME, property);
Ok(())
}
}
Expand Down

0 comments on commit d0e8b03

Please sign in to comment.