git.delta.rocks / unique-network / refs/commits / 731fc56abf21

difftreelog

refactor remove AbiType

Trubnikov Sergey2022-11-01parent: #2ef175a.patch.diff
in: master

3 files changed

modifiedcrates/evm-coder/procedural/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/lib.rs
+++ b/crates/evm-coder/procedural/src/lib.rs
@@ -107,7 +107,7 @@
 	if path.segments.len() != 1 {
 		return Err(syn::Error::new(
 			path.span(),
-			"expected path to have only segment",
+			"expected path to have only one segment",
 		));
 	}
 	let last_segment = &path.segments.last().unwrap();
modifiedcrates/evm-coder/procedural/src/solidity_interface.rsdiffbeforeafterboth
329 }329 }
330}330}
331331
332#[derive(Debug)]
333enum AbiType {332trait AbiType {
334 // type
335 Plain(Ident),333 fn plain(&self) -> syn::Result<&Ident>;
336 // (type1,type2)
337 Tuple(Vec<AbiType>),334 fn is_value(&self) -> bool;
338 // type[]
339 Vec(Box<AbiType>),335 fn is_caller(&self) -> bool;
340 // type[20]
341 Array(Box<AbiType>, usize),336 fn is_special(&self) -> bool;
342}337}
338
343impl AbiType {339impl AbiType for Type {
344 fn try_from(value: &Type) -> syn::Result<Self> {
345 let value = Self::try_maybe_special_from(value)?;
346 if value.is_special() {
347 return Err(syn::Error::new(value.span(), "unexpected special type"));
348 }
349 Ok(value)
350 }
351 fn try_maybe_special_from(value: &Type) -> syn::Result<Self> {340 fn plain(&self) -> syn::Result<&Ident> {
352 match value {
353 Type::Array(arr) => {
354 let wrapped = AbiType::try_from(&arr.elem)?;
355 match &arr.len {
356 Expr::Lit(l) => match &l.lit {
357 Lit::Int(i) => {
358 let num = i.base10_parse::<usize>()?;
359 Ok(AbiType::Array(Box::new(wrapped), num as usize))
360 }
361 _ => Err(syn::Error::new(arr.len.span(), "should be int literal")),
362 },
363 _ => Err(syn::Error::new(arr.len.span(), "should be literal")),
364 }
365 }
366 Type::Path(_) => {
367 let path = parse_path(value)?;341 let path = parse_path(self)?;
368 let segment = parse_path_segment(path)?;342 let segment = parse_path_segment(path)?;
369 if segment.ident == "Vec" {343 if !segment.arguments.is_empty() {
370 let args = match &segment.arguments {
371 PathArguments::AngleBracketed(e) => e,
372 _ => {
373 return Err(syn::Error::new(
374 segment.arguments.span(),
375 "missing Vec generic",
376 ))
377 }
378 };
379 let args = &args.args;
380 if args.len() != 1 {
381 return Err(syn::Error::new(
382 args.span(),
383 "expected only one generic for vec",
384 ));
385 }
386 let arg = args.first().expect("first arg");
387
388 let ty = match arg {
389 GenericArgument::Type(ty) => ty,
390 _ => {
391 return Err(syn::Error::new(
392 arg.span(),
393 "expected first generic to be type",
394 ))
395 }
396 };
397
398 let wrapped = AbiType::try_from(ty)?;
399 Ok(Self::Vec(Box::new(wrapped)))
400 } else {
401 if !segment.arguments.is_empty() {
402 return Err(syn::Error::new(344 return Err(syn::Error::new(self.span(), "Not plain type"));
403 segment.arguments.span(),
404 "unexpected generic arguments for non-vec type",
405 ));
406 }345 }
407 Ok(Self::Plain(segment.ident.clone()))346 Ok(&segment.ident)
408 }
409 }347 }
410 Type::Tuple(t) => {348
411 let mut out = Vec::with_capacity(t.elems.len());
412 for el in t.elems.iter() {
413 out.push(AbiType::try_from(el)?)
414 }
415 Ok(Self::Tuple(out))
416 }
417 _ => Err(syn::Error::new(
418 value.span(),
419 "unexpected type, only arrays, plain types and tuples are supported",
420 )),
421 }
422 }
423 fn is_value(&self) -> bool {349 fn is_value(&self) -> bool {
424 matches!(self, Self::Plain(v) if v == "value")350 if let Ok(ident) = self.plain() {
351 return ident == "value";
352 }
353 false
425 }354 }
355
426 fn is_caller(&self) -> bool {356 fn is_caller(&self) -> bool {
427 matches!(self, Self::Plain(v) if v == "caller")357 if let Ok(ident) = self.plain() {
358 return ident == "caller";
359 }
360 false
428 }361 }
362
429 fn is_special(&self) -> bool {363 fn is_special(&self) -> bool {
430 self.is_caller() || self.is_value()364 self.is_caller() || self.is_value()
431 }365 }
432 fn selector_ty_buf(&self, buf: &mut String) -> std::fmt::Result {366}
433 match self {
434 AbiType::Plain(t) => {
435 write!(buf, "{}", t)
436 }
437 AbiType::Tuple(t) => {
438 write!(buf, "(")?;
439 for (i, t) in t.iter().enumerate() {
440 if i != 0 {
441 write!(buf, ",")?;
442 }
443 t.selector_ty_buf(buf)?;
444 }
445 write!(buf, ")")
446 }
447 AbiType::Vec(v) => {
448 v.selector_ty_buf(buf)?;
449 write!(buf, "[]")
450 }
451 AbiType::Array(v, len) => {
452 v.selector_ty_buf(buf)?;
453 write!(buf, "[{}]", len)
454 }
455 }
456 }
457 fn selector_ty(&self) -> String {
458 let mut out = String::new();
459 self.selector_ty_buf(&mut out).expect("no fmt error");
460 out
461 }
462}
463impl ToTokens for AbiType {
464 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
465 match self {
466 AbiType::Plain(t) => tokens.extend(quote! {#t}),
467 AbiType::Tuple(t) => {
468 tokens.extend(quote! {(
469 #(#t),*
470 )});
471 }
472 AbiType::Vec(v) => tokens.extend(quote! {Vec<#v>}),
473 AbiType::Array(v, l) => tokens.extend(quote! {[#v; #l]}),
474 }
475 }
476}
477367
478#[derive(Debug)]368#[derive(Debug)]
479struct MethodArg {369struct MethodArg {
480 name: Ident,370 name: Ident,
481 camel_name: String,371 camel_name: String,
482 ty: AbiType,372 ty: Type,
483}373}
484impl MethodArg {374impl MethodArg {
485 fn try_from(value: &PatType) -> syn::Result<Self> {375 fn try_from(value: &PatType) -> syn::Result<Self> {
486 let name = parse_ident_from_pat(&value.pat)?.clone();376 let name = parse_ident_from_pat(&value.pat)?.clone();
487 Ok(Self {377 Ok(Self {
488 camel_name: cases::camelcase::to_camel_case(&name.to_string()),378 camel_name: cases::camelcase::to_camel_case(&name.to_string()),
489 name,379 name,
490 ty: AbiType::try_maybe_special_from(&value.ty)?,380 ty: value.ty.as_ref().clone(),
491 })381 })
492 }382 }
493 fn is_value(&self) -> bool {383 fn is_value(&self) -> bool {
499 fn is_special(&self) -> bool {389 fn is_special(&self) -> bool {
500 self.ty.is_special()390 self.ty.is_special()
501 }391 }
502 fn selector_ty(&self) -> String {
503 assert!(!self.is_special());
504 self.ty.selector_ty()
505 }
506392
507 fn expand_call_def(&self) -> proc_macro2::TokenStream {393 fn expand_call_def(&self) -> proc_macro2::TokenStream {
508 assert!(!self.is_special());394 assert!(!self.is_special());
578 camel_name: String,464 camel_name: String,
579 pascal_name: Ident,465 pascal_name: Ident,
580 screaming_name: Ident,466 screaming_name: Ident,
581 selector_str: String,
582 selector: u32,
583 hide: bool,467 hide: bool,
584 args: Vec<MethodArg>,468 args: Vec<MethodArg>,
585 has_normal_args: bool,469 has_normal_args: bool,
670 let camel_name = info554 let camel_name = info
671 .rename_selector555 .rename_selector
672 .unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));556 .unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));
673 let mut selector_str = camel_name.clone();
674 selector_str.push('(');
675 let mut has_normal_args = false;557 let has_normal_args = args.iter().filter(|arg| !arg.is_special()).count() != 0;
676 for (i, arg) in args.iter().filter(|arg| !arg.is_special()).enumerate() {
677 if i != 0 {
678 selector_str.push(',');
679 }
680 write!(selector_str, "{}", arg.selector_ty()).unwrap();
681 has_normal_args = true;
682 }
683 let has_value_args = args.iter().any(|a| a.is_value());558 let has_value_args = args.iter().any(|a| a.is_value());
684 selector_str.push(')');
685 let selector = fn_selector_str(&selector_str);
686559
687 Ok(Self {560 Ok(Self {
688 name: ident.clone(),561 name: ident.clone(),
689 camel_name,562 camel_name,
690 pascal_name: snake_ident_to_pascal(ident),563 pascal_name: snake_ident_to_pascal(ident),
691 screaming_name: snake_ident_to_screaming(ident),564 screaming_name: snake_ident_to_screaming(ident),
692 selector_str,
693 selector,
694 hide: info.hide,565 hide: info.hide,
695 args,566 args,
696 has_normal_args,567 has_normal_args,
728 fn expand_const(&self) -> proc_macro2::TokenStream {599 fn expand_const(&self) -> proc_macro2::TokenStream {
729 let screaming_name = &self.screaming_name;600 let screaming_name = &self.screaming_name;
730 let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);601 let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);
731 let selector_str = &self.selector_str;
732 let custom_signature = self.expand_custom_signature();602 let custom_signature = self.expand_custom_signature();
733 quote! {603 quote! {
734 #[doc = #selector_str]
735 const #screaming_name_signature: ::evm_coder::custom_signature::FunctionSignature = #custom_signature;604 const #screaming_name_signature: ::evm_coder::custom_signature::FunctionSignature = #custom_signature;
736 const #screaming_name: ::evm_coder::types::bytes4 = {605 const #screaming_name: ::evm_coder::types::bytes4 = {
737 let mut sum = ::evm_coder::sha3_const::Keccak256::new();606 let mut sum = ::evm_coder::sha3_const::Keccak256::new();
845 }714 }
846 }715 }
847716
848 fn expand_type(717 fn expand_type(ty: &Type, token_stream: &mut proc_macro2::TokenStream, read_signature: bool) {
849 ty: &AbiType,
850 token_stream: &mut proc_macro2::TokenStream,
851 read_signature: bool,
852 ) {
853 match ty {718 match ty {
854 AbiType::Plain(ref ident) => {719 Type::Path(tp) => {
720 if let Some(qself) = &tp.qself {
721 panic!("no receiver expected {:?}", qself.ty.span());
722 }
723 let path = &tp.path;
724 if path.segments.len() != 1 {
725 panic!("expected path to have only one segment {:?}", path.span());
726 }
727 let last_segment = path.segments.last().unwrap();
728
729 if last_segment.ident == "Vec" {
730 let args = match &last_segment.arguments {
731 PathArguments::AngleBracketed(e) => e,
732 _ => {
733 panic!("missing Vec generic {:?}", last_segment.arguments.span());
734 }
735 };
736 let args = &args.args;
737 if args.len() != 1 {
738 panic!("expected only one generic for vec {:?}", args.span());
739 }
740 let arg = args.first().expect("first arg");
741
742 let ty = match arg {
743 GenericArgument::Type(ty) => ty,
744 _ => {
745 panic!("expected first generic to be type {:?}", arg.span());
746 }
747 };
748
749 let mut vec_token = proc_macro2::TokenStream::new();
750 Self::expand_type(ty, &mut vec_token, false);
751 vec_token = if read_signature {
752 quote! { (<Vec<#vec_token>>::SIGNATURE) }
753 } else {
754 quote! { <Vec<#vec_token>> }
755 };
756 token_stream.extend(vec_token);
757 } else {
758 if !last_segment.arguments.is_empty() {
759 panic!(
760 "unexpected generic arguments for non-vec type {:?}",
761 last_segment.arguments.span()
762 );
763 }
764
765 let ident = &last_segment.ident;
855 let plain_token = if read_signature {766 let plain_token = if read_signature {
856 quote! {767 quote! {
857 (<#ident>::SIGNATURE)768 (<#ident>::SIGNATURE)
864775
865 token_stream.extend(plain_token);776 token_stream.extend(plain_token);
866 }777 }
778 }
867779
868 AbiType::Tuple(ref tuple_type) => {780 Type::Tuple(tt) => {
781 // for ty in tt.elems.iter() {
782 // out.push(AbiType::try_from(ty)?)
783 // }
784
869 let mut tuple_types = proc_macro2::TokenStream::new();785 let mut tuple_types = proc_macro2::TokenStream::new();
870 let mut is_first = true;786 let mut is_first = true;
871787
872 for ty in tuple_type {788 for ty in tt.elems.iter() {
873 if is_first {789 if is_first {
874 is_first = false790 is_first = false
875 } else {791 } else {
885 token_stream.extend(tuple_types);801 token_stream.extend(tuple_types);
886 }802 }
887803
888 AbiType::Vec(ref vec_type) => {804 // Type::Array(arr) => {
889 let mut vec_token = proc_macro2::TokenStream::new();805 // let wrapped = AbiType::try_from(&arr.elem)?;
890 Self::expand_type(vec_type.as_ref(), &mut vec_token, false);806 // match &arr.len {
891 vec_token = if read_signature {807 // Expr::Lit(l) => match &l.lit {
892 quote! { (<Vec<#vec_token>>::SIGNATURE) }808 // Lit::Int(i) => {
893 } else {809 // let num = i.base10_parse::<usize>()?;
894 quote! { <Vec<#vec_token>> }810 // Ok(AbiType::Array(Box::new(wrapped), num as usize))
895 };811 // }
896 token_stream.extend(vec_token);812 // _ => Err(syn::Error::new(arr.len.span(), "should be int literal")),
897 }813 // },
898814 // _ => Err(syn::Error::new(arr.len.span(), "should be literal")),
815 // }
816 // }
899 AbiType::Array(_, _) => todo!("Array eth signature"),817 _ => panic!("Unexpected type {ty:?}"),
900 };818 }
819 // match ty {
820 // AbiType::Plain(ref ident) => {
821 // let plain_token = if read_signature {
822 // quote! {
823 // (<#ident>::SIGNATURE)
824 // }
825 // } else {
826 // quote! {
827 // #ident
828 // }
829 // };
830
831 // token_stream.extend(plain_token);
832 // }
833
834 // AbiType::Tuple(ref tuple_type) => {
835 // let mut tuple_types = proc_macro2::TokenStream::new();
836 // let mut is_first = true;
837
838 // for ty in tuple_type {
839 // if is_first {
840 // is_first = false
841 // } else {
842 // tuple_types.extend(quote!(,));
843 // }
844 // Self::expand_type(ty, &mut tuple_types, false);
845 // }
846 // tuple_types = if read_signature {
847 // quote! { (<(#tuple_types)>::SIGNATURE) }
848 // } else {
849 // quote! { (#tuple_types) }
850 // };
851 // token_stream.extend(tuple_types);
852 // }
853
854 // AbiType::Vec(ref vec_type) => {
855 // let mut vec_token = proc_macro2::TokenStream::new();
856 // Self::expand_type(vec_type.as_ref(), &mut vec_token, false);
857 // vec_token = if read_signature {
858 // quote! { (<Vec<#vec_token>>::SIGNATURE) }
859 // } else {
860 // quote! { <Vec<#vec_token>> }
861 // };
862 // token_stream.extend(vec_token);
863 // }
864
865 // AbiType::Array(_, _) => todo!("Array eth signature"),
866 // };
901 }867 }
902868
903 fn expand_custom_signature(&self) -> proc_macro2::TokenStream {869 fn expand_custom_signature(&self) -> proc_macro2::TokenStream {
947 .filter(|a| !a.is_special())913 .filter(|a| !a.is_special())
948 .map(MethodArg::expand_solidity_argument);914 .map(MethodArg::expand_solidity_argument);
949 let docs = &self.docs;915 let docs = &self.docs;
950 let selector_str = &self.selector_str;
951 let screaming_name = &self.screaming_name;916 let screaming_name = &self.screaming_name;
952 let hide = self.hide;917 let hide = self.hide;
953 let custom_signature = self.expand_custom_signature();918 let custom_signature = self.expand_custom_signature();
962 quote! {927 quote! {
963 SolidityFunction {928 SolidityFunction {
964 docs: &[#(#docs),*],929 docs: &[#(#docs),*],
965 selector_str: #selector_str,
966 hide: #hide,930 hide: #hide,
967 selector: u32::from_be_bytes(Self::#screaming_name),931 selector: u32::from_be_bytes(Self::#screaming_name),
968 custom_signature: #custom_signature,932 custom_signature: #custom_signature,
modifiedcrates/evm-coder/src/solidity.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity.rs
+++ b/crates/evm-coder/src/solidity.rs
@@ -484,7 +484,6 @@
 }
 pub struct SolidityFunction<A, R> {
 	pub docs: &'static [&'static str],
-	pub selector_str: &'static str,
 	pub selector: u32,
 	pub hide: bool,
 	pub custom_signature: FunctionSignature,
@@ -513,15 +512,8 @@
 		writeln!(
 			writer,
 			"\t{hide_comment}///  or in textual repr: {}",
-			self.selector_str
+			self.custom_signature.as_str()
 		)?;
-		if self.selector_str != self.custom_signature.as_str() {
-			writeln!(
-				writer,
-				"\t{hide_comment}///  or in the expanded repr: {}",
-				self.custom_signature.as_str()
-			)?;
-		}
 		write!(writer, "\t{hide_comment}function {}(", self.name)?;
 		self.args.solidity_name(writer, tc)?;
 		write!(writer, ")")?;