From 9a0de8e48597f376163490db06b0f112a8a38457 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 25 Nov 2021 22:31:11 +0800 Subject: [PATCH] feat(napi): allow return self as this --- crates/backend/src/codegen/fn.rs | 28 +++++++++++++------ crates/backend/src/typegen/fn.rs | 2 ++ .../napi/src/bindgen_runtime/callback_info.rs | 2 +- .../src/bindgen_runtime/js_values/array.rs | 4 +-- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/crates/backend/src/codegen/fn.rs b/crates/backend/src/codegen/fn.rs index 5f962137..2e805d52 100644 --- a/crates/backend/src/codegen/fn.rs +++ b/crates/backend/src/codegen/fn.rs @@ -245,6 +245,8 @@ impl NapiFn { let js_name = &self.js_name; if let Some(ty) = &self.ret { + let ty_string = ty.into_token_stream().to_string(); + let is_return_self = ty_string == "& Self" || ty_string == "&mut Self"; if self.kind == FnKind::Constructor { if self.is_ret_result { quote! { cb.construct(#js_name, #ret?) } @@ -263,19 +265,27 @@ impl NapiFn { <#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret) } } else { - quote! { - match #ret { - Ok(value) => napi::bindgen_prelude::ToNapiValue::to_napi_value(env, value), - Err(err) => { - napi::bindgen_prelude::JsError::from(err).throw_into(env); - Ok(std::ptr::null_mut()) - }, + if is_return_self { + quote! { #ret.map(|_| cb.this) } + } else { + quote! { + match #ret { + Ok(value) => napi::bindgen_prelude::ToNapiValue::to_napi_value(env, value), + Err(err) => { + napi::bindgen_prelude::JsError::from(err).throw_into(env); + Ok(std::ptr::null_mut()) + }, + } } } } } else { - quote! { - <#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret) + if is_return_self { + quote! { Ok(cb.this) } + } else { + quote! { + <#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret) + } } } } else { diff --git a/crates/backend/src/typegen/fn.rs b/crates/backend/src/typegen/fn.rs index 7b05c5f5..6f2ed754 100644 --- a/crates/backend/src/typegen/fn.rs +++ b/crates/backend/src/typegen/fn.rs @@ -112,6 +112,8 @@ impl NapiFn { let (ts_type, _) = ty_to_ts_type(ret, true); if ts_type == "undefined" { "void".to_owned() + } else if ts_type == "Self" { + "this".to_owned() } else { ts_type } diff --git a/crates/napi/src/bindgen_runtime/callback_info.rs b/crates/napi/src/bindgen_runtime/callback_info.rs index 0e68c7c0..d52cbd5c 100644 --- a/crates/napi/src/bindgen_runtime/callback_info.rs +++ b/crates/napi/src/bindgen_runtime/callback_info.rs @@ -12,7 +12,7 @@ pub static ___CALL_FROM_FACTORY: AtomicBool = AtomicBool::new(false); pub struct CallbackInfo { env: sys::napi_env, - this: sys::napi_value, + pub this: sys::napi_value, pub args: [sys::napi_value; N], } diff --git a/crates/napi/src/bindgen_runtime/js_values/array.rs b/crates/napi/src/bindgen_runtime/js_values/array.rs index ae9c5c9f..e8c21dbe 100644 --- a/crates/napi/src/bindgen_runtime/js_values/array.rs +++ b/crates/napi/src/bindgen_runtime/js_values/array.rs @@ -123,8 +123,8 @@ impl Array { T: ToNapiValue, { let mut arr = Array::new(env.0, value.len() as u32)?; - value.into_iter().try_for_each(|val| { - arr.insert(val)?; + value.into_iter().enumerate().try_for_each(|(index, val)| { + arr.set(index as u32, val)?; Ok::<(), Error>(()) })?; Ok(arr)