From 0d69797ce93dc089a1eebd2becfbd7b94f1004e5 Mon Sep 17 00:00:00 2001 From: Redfire Date: Wed, 15 Nov 2023 23:03:40 +0800 Subject: [PATCH] Added From Value Implementations for References to Native Classes Added More Targets to Unused Dependency Check in CI --- .github/workflows/rust.yml | 2 +- ion-proc/src/class/struct.rs | 32 +++++++++++++++++++++--- runtime/src/globals/fetch/header.rs | 12 --------- runtime/src/globals/fetch/request/mod.rs | 15 +---------- runtime/src/globals/file/blob.rs | 13 ---------- runtime/src/globals/url/search_params.rs | 13 ---------- 6 files changed, 30 insertions(+), 57 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e159d2d4..974c87ee 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -120,4 +120,4 @@ jobs: - name: Check for Unused Dependencies env: RUSTC_WRAPPER: sccache - run: cargo udeps + run: cargo udeps --all-targets --locked diff --git a/ion-proc/src/class/struct.rs b/ion-proc/src/class/struct.rs index 81222a9e..1dd804af 100644 --- a/ion-proc/src/class/struct.rs +++ b/ion-proc/src/class/struct.rs @@ -7,14 +7,14 @@ use std::ffi::CString; use proc_macro2::{Ident, Span, TokenStream}; -use syn::{Error, Fields, ImplItemFn, ItemImpl, ItemStruct, Member, parse2, Path, Result, Type}; +use syn::{Error, Fields, ImplItemFn, ItemImpl, ItemStruct, LitStr, Member, parse2, Path, Result, Type}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use crate::attribute::krate::crate_from_attributes; use crate::utils::path_ends_with; -pub(super) fn impl_js_class_struct(r#struct: &mut ItemStruct) -> Result<[ItemImpl; 4]> { +pub(super) fn impl_js_class_struct(r#struct: &mut ItemStruct) -> Result<[ItemImpl; 6]> { let ion = &crate_from_attributes(&r#struct.attrs); let repr_c = r#struct.attrs.iter().fold(Ok(false), |acc, attr| { @@ -81,7 +81,10 @@ pub(super) fn impl_js_class_struct(r#struct: &mut ItemStruct) -> Result<[ItemImp class_impls(ion, r#struct.span(), &ident.to_string(), &r#type, &super_field, &super_type) } -fn class_impls(ion: &TokenStream, span: Span, name: &str, r#type: &Type, super_field: &Member, super_type: &Type) -> Result<[ItemImpl; 4]> { +fn class_impls(ion: &TokenStream, span: Span, name: &str, r#type: &Type, super_field: &Member, super_type: &Type) -> Result<[ItemImpl; 6]> { + let from_value = impl_from_value(ion, span, name, r#type, false)?; + let from_value_mut = impl_from_value(ion, span, name, r#type, true)?; + let derived_from = parse2(quote_spanned!(span => unsafe impl #ion::class::DerivedFrom<#super_type> for #r#type {}))?; let castable = parse2(quote_spanned!(span => impl #ion::class::Castable for #r#type {}))?; @@ -147,7 +150,28 @@ fn class_impls(ion: &TokenStream, span: Span, name: &str, r#type: &Type, super_f }))?; operations_native_class.attrs.push(parse_quote!(#[doc(hidden)])); - Ok([derived_from, castable, native_object, operations_native_class]) + Ok([from_value, from_value_mut, derived_from, castable, native_object, operations_native_class]) +} + +fn impl_from_value(ion: &TokenStream, span: Span, name: &str, r#type: &Type, mutable: bool) -> Result { + let from_value_error = LitStr::new(&format!("Expected {}", name), span); + let function = if mutable { quote!(get_mut_private) } else { quote!(get_private) }; + let mutable = mutable.then(::default); + + parse2( + quote_spanned!(span => impl<'cx> #ion::conversions::FromValue<'cx> for &'cx #mutable #r#type { + type Config = (); + + fn from_value(cx: &'cx #ion::Context, value: &#ion::Value, strict: ::core::primitive::bool, _: ()) -> #ion::Result<&'cx #mutable #r#type> { + let #mutable object = #ion::Object::from_value(cx, value, strict, ())?; + if <#r#type as #ion::class::ClassDefinition>::instance_of(cx, &object, None) { + Ok(<#r#type as #ion::class::ClassDefinition>::#function(&#mutable object)) + } else { + Err(#ion::Error::new(#from_value_error, #ion::ErrorKind::Type)) + } + } + }), + ) } fn class_operations(span: Span) -> Result> { diff --git a/runtime/src/globals/fetch/header.rs b/runtime/src/globals/fetch/header.rs index c25e9662..56b32b9b 100644 --- a/runtime/src/globals/fetch/header.rs +++ b/runtime/src/globals/fetch/header.rs @@ -262,18 +262,6 @@ impl Headers { } } -impl<'cx> FromValue<'cx> for &'cx Headers { - type Config = (); - fn from_value(cx: &'cx Context, value: &Value, strict: bool, _: ()) -> Result<&'cx Headers> { - let object = Object::from_value(cx, value, strict, ())?; - if Headers::instance_of(cx, &object, None) { - Ok(Headers::get_private(&object)) - } else { - Err(Error::new("Expected Headers", ErrorKind::Type)) - } - } -} - pub struct HeadersIterator { keys: vec::IntoIter, cookies: vec::IntoIter, diff --git a/runtime/src/globals/fetch/request/mod.rs b/runtime/src/globals/fetch/request/mod.rs index 09e87fbc..32f15809 100644 --- a/runtime/src/globals/fetch/request/mod.rs +++ b/runtime/src/globals/fetch/request/mod.rs @@ -12,9 +12,8 @@ use hyper::{Body, Method, Uri}; use mozjs::jsapi::{Heap, JSObject}; use url::Url; -use ion::{ClassDefinition, Context, Error, ErrorKind, Object, Result, Value}; +use ion::{ClassDefinition, Context, Error, ErrorKind, Result}; use ion::class::Reflector; -use ion::conversions::FromValue; pub use options::*; use crate::globals::abort::AbortSignal; @@ -340,15 +339,3 @@ impl Clone for Request { } } } - -impl<'cx> FromValue<'cx> for &'cx Request { - type Config = (); - fn from_value(cx: &'cx Context, value: &Value, _: bool, _: ()) -> Result<&'cx Request> { - let object = Object::from_value(cx, value, true, ())?; - if Request::instance_of(cx, &object, None) { - Ok(Request::get_private(&object)) - } else { - Err(Error::new("Expected Request", ErrorKind::Type)) - } - } -} diff --git a/runtime/src/globals/file/blob.rs b/runtime/src/globals/file/blob.rs index d6f4765f..e5240335 100644 --- a/runtime/src/globals/file/blob.rs +++ b/runtime/src/globals/file/blob.rs @@ -207,16 +207,3 @@ impl Blob { future_to_promise(cx, async move { Ok::<_, ()>(ion::typedarray::ArrayBuffer::from(bytes.to_vec())) }) } } - -impl<'cx> FromValue<'cx> for &'cx Blob { - type Config = (); - - fn from_value(cx: &'cx Context, value: &Value, _: bool, _: ()) -> Result<&'cx Blob> { - let object = Object::from_value(cx, value, true, ())?; - if Blob::instance_of(cx, &object, None) { - Ok(Blob::get_private(&object)) - } else { - Err(Error::new("Expected Blob", ErrorKind::Type)) - } - } -} diff --git a/runtime/src/globals/url/search_params.rs b/runtime/src/globals/url/search_params.rs index 878c9b74..d82ae691 100644 --- a/runtime/src/globals/url/search_params.rs +++ b/runtime/src/globals/url/search_params.rs @@ -180,19 +180,6 @@ impl URLSearchParams { } } -impl<'cx> FromValue<'cx> for &'cx URLSearchParams { - type Config = (); - - fn from_value(cx: &'cx Context, value: &Value, strict: bool, _: ()) -> Result<&'cx URLSearchParams> { - let object = Object::from_value(cx, value, strict, ())?; - if URLSearchParams::instance_of(cx, &object, None) { - Ok(URLSearchParams::get_private(&object)) - } else { - Err(Error::new("Expected URLSearchParams", ErrorKind::Type)) - } - } -} - #[derive(Default)] pub struct SearchParamsIterator(usize);