Skip to content

Commit

Permalink
Merge pull request #210 from DelSkayn/impl_module
Browse files Browse the repository at this point in the history
Reimplement a macro for creating javascript modules with exports.
  • Loading branch information
DelSkayn authored Sep 12, 2023
2 parents ea06f78 + 48bc4c3 commit 9cee95a
Show file tree
Hide file tree
Showing 11 changed files with 983 additions and 83 deletions.
12 changes: 11 additions & 1 deletion core/src/value/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,11 @@ impl Declarations {
}
Ok(())
}

/// Returns an iterator over existing declarations.
pub fn iter(&self) -> impl Iterator<Item = &Cow<'static, CStr>> {
self.declarations.iter()
}
}

struct Export<'js> {
Expand Down Expand Up @@ -387,6 +392,11 @@ impl<'js> Exports<'js> {
}
Ok(())
}

/// Returns an iterator over existing imports.
pub fn iter(&self) -> impl Iterator<Item = (&CStr, &Value<'js>)> {
self.exports.iter().map(|x| (x.name.as_c_str(), &x.value))
}
}

/// A JavaScript module.
Expand Down Expand Up @@ -932,7 +942,7 @@ mod test {
}

fn evaluate<'js>(ctx: &Ctx<'js>, _exports: &mut Exports<'js>) -> Result<()> {
let _ = ctx.eval(r#"throw new Error("kaboom")"#)?;
ctx.eval::<(), _>(r#"throw new Error("kaboom")"#)?;
Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion macro/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
fields::Fields,
};

#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub(crate) struct ClassConfig {
pub frozen: bool,
pub crate_: Option<String>,
Expand Down
18 changes: 18 additions & 0 deletions macro/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use convert_case::Case as ConvertCase;
use proc_macro2::Span;
use proc_macro_crate::FoundCrate;
use proc_macro_error::{abort, abort_call_site};
use quote::{ToTokens, TokenStreamExt};
use syn::{
fold::Fold,
parse::{Parse, ParseStream},
Expand Down Expand Up @@ -46,6 +47,19 @@ impl Parse for Case {
}
}

impl ToTokens for Case {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
match self {
Case::Lower => tokens.append_all(["lowercase"]),
Case::Upper => tokens.append_all(["UPPERCASE"]),
Case::Camel => tokens.append_all(["camelCase"]),
Case::Pascal => tokens.append_all(["PascalCase"]),
Case::Snake => tokens.append_all(["snake_case"]),
Case::ScreamingSnake => tokens.append_all(["SCREAMING_SNAKE"]),
}
}
}

pub(crate) trait AbortResultExt {
type Ouput;
fn unwrap_or_abort(self) -> Self::Ouput;
Expand Down Expand Up @@ -132,11 +146,15 @@ pub(crate) mod kw {
syn::custom_keyword!(skip_trace);
syn::custom_keyword!(rename);
syn::custom_keyword!(rename_all);
syn::custom_keyword!(rename_vars);
syn::custom_keyword!(rename_types);
syn::custom_keyword!(get);
syn::custom_keyword!(set);
syn::custom_keyword!(constructor);
syn::custom_keyword!(skip);
syn::custom_keyword!(configurable);
syn::custom_keyword!(enumerable);
syn::custom_keyword!(prefix);
syn::custom_keyword!(declare);
syn::custom_keyword!(evaluate);
}
35 changes: 29 additions & 6 deletions macro/src/function.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use convert_case::Casing;
use proc_macro2::{Ident, TokenStream};
use proc_macro_error::abort;
use quote::{format_ident, quote};
Expand All @@ -11,7 +12,7 @@ use syn::{

use crate::{
attrs::{take_attributes, OptionList, ValueOption},
common::{crate_ident, kw, AbortResultExt, SelfReplacer, BASE_PREFIX},
common::{crate_ident, kw, AbortResultExt, Case, SelfReplacer, BASE_PREFIX},
};

#[derive(Debug, Default)]
Expand Down Expand Up @@ -51,14 +52,35 @@ impl FunctionConfig {
self.rename = Some(x.value.value());
}
FunctionOption::Prefix(ref x) => {
self.rename = Some(x.value.value());
self.prefix = Some(x.value.value());
}
}
}

/// Returns a name under which we can access the rquickjs crate.
pub fn crate_name(&self) -> String {
self.crate_.clone().unwrap_or_else(crate_ident)
}

/// Returns the name of the carry type for which JsFunction will be implemented
pub fn carry_name(&self, name: &Ident) -> Ident {
Ident::new(
&format!("{}{}", self.prefix.as_deref().unwrap_or("js_"), name),
name.span(),
)
}

/// The name for the javascript side
pub fn js_name(&self, rust_name: &Ident, case: Option<Case>) -> String {
if let Some(x) = self.rename.as_ref() {
return x.clone();
}
let name = rust_name.to_string();
if let Some(case) = case {
return name.to_case(case.to_convert_case());
}
name
}
}

pub(crate) fn expand(options: OptionList<FunctionOption>, mut item: syn::ItemFn) -> TokenStream {
Expand All @@ -82,13 +104,14 @@ pub(crate) fn expand(options: OptionList<FunctionOption>, mut item: syn::ItemFn)
.unwrap_or_abort();

let crate_name = format_ident!("{}", config.crate_name());
let prefix = config.prefix.unwrap_or_else(|| BASE_PREFIX.to_string());
let prefix = config.prefix.as_deref().unwrap_or(BASE_PREFIX);

let func = JsFunction::new(item.vis.clone(), &item.sig, None);

let carry_type = func.expand_carry_type(&prefix);
let impl_ = func.expand_to_js_function_impl(&prefix, &crate_name);
let into_js = func.expand_into_js_impl(&prefix, &crate_name);
let carry_type = func.expand_carry_type(prefix);
let impl_ = func.expand_to_js_function_impl(prefix, &crate_name);
let into_js = func.expand_into_js_impl(prefix, &crate_name);
let _js_name = config.js_name(&item.sig.ident, None);

quote! {
#item
Expand Down
14 changes: 11 additions & 3 deletions macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use attrs::OptionList;
use class::ClassOption;
use function::FunctionOption;
use methods::ImplOption;
use module::ModuleOption;
use proc_macro::TokenStream as TokenStream1;
use proc_macro_error::{abort, proc_macro_error};
use syn::{parse_macro_input, DeriveInput, Item};
Expand All @@ -22,7 +23,7 @@ mod embed;
mod fields;
mod function;
mod methods;
//mod module;
mod module;
mod trace;

#[proc_macro_attribute]
Expand Down Expand Up @@ -61,8 +62,15 @@ pub fn methods(attr: TokenStream1, item: TokenStream1) -> TokenStream1 {

#[proc_macro_attribute]
#[proc_macro_error]
pub fn module(_attr: TokenStream1, _item: TokenStream1) -> TokenStream1 {
todo!()
pub fn module(attr: TokenStream1, item: TokenStream1) -> TokenStream1 {
let options = parse_macro_input!(attr as OptionList<ModuleOption>);
let item = parse_macro_input!(item as Item);
match item {
Item::Mod(item) => module::expand(options, item).into(),
item => {
abort!(item, "#[module] macro can only be used on modules")
}
}
}

#[proc_macro_derive(Trace, attributes(qjs))]
Expand Down
72 changes: 0 additions & 72 deletions macro/src/module.rs

This file was deleted.

Loading

0 comments on commit 9cee95a

Please sign in to comment.