Repository: denoland/deno_core
Pull request #1001 (2024-12-14 05:55:02)

Add #[rename] attribute
For when auto-camelCasing isn't enough.

```rust
#[op2]
impl StatementSync {
  #[rename("sourceSQL")]
  fn source_sql(&self) -> String { /* ... */ }
}
```


Patch:
diff --git a/ops/op2/config.rs b/ops/op2/config.rs
index 150b998..6534dc0 100644
--- a/ops/op2/config.rs
+++ b/ops/op2/config.rs
@@ -3,6 +3,7 @@ use proc_macro2::TokenStream;
 use proc_macro2::TokenTree;
 use proc_macro_rules::rules;
 use quote::ToTokens;
+use syn::LitStr;
 
 use crate::op2::Op2Error;
 
@@ -40,6 +41,8 @@ pub(crate) struct MacroConfig {
   pub stack_trace: bool,
   /// Total required number of arguments for the op.
   pub required: u8,
+  /// Rename the op to the given name.
+  pub rename: Option<String>,
 }
 
 impl MacroConfig {
@@ -137,6 +140,9 @@ impl MacroConfig {
           .to_string()
           .parse()
           .map_err(|_| Op2Error::InvalidAttribute(flag))?;
+      } else if flag.starts_with("rename(") {
+        let tokens = syn::parse_str::<LitStr>(&flag[7..flag.len() - 1])?;
+        config.rename = Some(tokens.value());
       } else {
         return Err(Op2Error::InvalidAttribute(flag));
       }
diff --git a/ops/op2/mod.rs b/ops/op2/mod.rs
index a0855d1..86625b9 100644
--- a/ops/op2/mod.rs
+++ b/ops/op2/mod.rs
@@ -117,6 +117,7 @@ pub(crate) fn generate_op2(
       FnArg::Typed(ty) => ty.attrs.clear(),
     }
   }
+
   if config.setter {
     // Prepend "__set_" to the setter function name.
     func.sig.ident = format_ident!("__set_{}", func.sig.ident);
diff --git a/ops/op2/object_wrap.rs b/ops/op2/object_wrap.rs
index a9e0a4c..3867c96 100644
--- a/ops/op2/object_wrap.rs
+++ b/ops/op2/object_wrap.rs
@@ -93,8 +93,7 @@ pub(crate) fn generate_impl_ops(
         stringcase::camel_case(&method.sig.ident.to_string())
       );
 
-      let ident = method.sig.ident.clone();
-      let func = ItemFn {
+      let mut func = ItemFn {
         attrs: item_fn_attrs,
         vis: method.vis,
         sig: method.sig,
@@ -105,6 +104,11 @@ pub(crate) fn generate_impl_ops(
         #(#attrs)*
       })?;
 
+      if let Some(ref rename) = config.rename {
+        func.sig.ident = format_ident!("{}", rename);
+      }
+
+      let ident = func.sig.ident.clone();
       if config.constructor {
         if constructor.is_some() {
           return Err(Op2Error::MultipleConstructors);
diff --git a/ops/op2/signature.rs b/ops/op2/signature.rs
index 2123e39..51caeb5 100644
--- a/ops/op2/signature.rs
+++ b/ops/op2/signature.rs
@@ -1253,6 +1253,7 @@ fn parse_attribute(
       (#[to_v8]) => Some(AttributeModifier::ToV8),
       (#[from_v8]) => Some(AttributeModifier::FromV8),
       (#[required ($_attr:literal)]) => Some(AttributeModifier::Ignore),
+      (#[rename ($_attr:literal)]) => Some(AttributeModifier::Ignore),
       (#[method ($_attr:literal)]) => Some(AttributeModifier::Ignore),
       (#[method]) => Some(AttributeModifier::Ignore),
       (#[getter]) => Some(AttributeModifier::Ignore),


Test patch:
diff --git a/testing/checkin/runner/ops.rs b/testing/checkin/runner/ops.rs
index 645b498..095aba4 100644
--- a/testing/checkin/runner/ops.rs
+++ b/testing/checkin/runner/ops.rs
@@ -90,6 +90,10 @@ impl TestObjectWrap {
   ) -> u32 {
     args.map(|args| args.length() as u32).unwrap_or(0)
   }
+
+  #[fast]
+  #[rename("with_RENAME")]
+  fn with_rename(&self) {}
 }
 
 pub struct DOMPoint {
diff --git a/testing/ops.d.ts b/testing/ops.d.ts
index 2011762..823cd13 100644
--- a/testing/ops.d.ts
+++ b/testing/ops.d.ts
@@ -35,4 +35,5 @@ export class DOMPoint {
 export class TestObjectWrap {
   constructor();
   withVarargs(...args: any[]): number;
+  with_RENAME(): void;
 }
diff --git a/testing/unit/resource_test.ts b/testing/unit/resource_test.ts
index 5c819ea..8703633 100644
--- a/testing/unit/resource_test.ts
+++ b/testing/unit/resource_test.ts
@@ -98,4 +98,6 @@ test(function testDomPoint() {
   assertEquals(wrap.withVarargs(1, 2, 3, 4, 5), 5);
   assertEquals(wrap.withVarargs(), 0);
   assertEquals(wrap.withVarargs(undefined), 1);
+
+  wrap.with_RENAME();
 });