1 use std::io::Write; 2 use std::ops::Deref; 3 4 use crate::bindgen::config::{Config, Language}; 5 use crate::bindgen::declarationtyperesolver::{DeclarationType, DeclarationTypeResolver}; 6 use crate::bindgen::ir::{Path, Type}; 7 use crate::bindgen::utilities::IterHelpers; 8 use crate::bindgen::writer::{Source, SourceWriter}; 9 10 #[derive(Default, Debug, Clone)] 11 pub struct GenericParams(pub Vec<Path>); 12 13 impl GenericParams { new(generics: &syn::Generics) -> Self14 pub fn new(generics: &syn::Generics) -> Self { 15 GenericParams( 16 generics 17 .params 18 .iter() 19 .filter_map(|x| match *x { 20 syn::GenericParam::Type(syn::TypeParam { ref ident, .. }) => { 21 Some(Path::new(ident.to_string())) 22 } 23 _ => None, 24 }) 25 .collect(), 26 ) 27 } 28 write_internal<F: Write>( &self, config: &Config, out: &mut SourceWriter<F>, with_default: bool, )29 fn write_internal<F: Write>( 30 &self, 31 config: &Config, 32 out: &mut SourceWriter<F>, 33 with_default: bool, 34 ) { 35 if !self.0.is_empty() && config.language == Language::Cxx { 36 out.write("template<"); 37 for (i, item) in self.0.iter().enumerate() { 38 if i != 0 { 39 out.write(", "); 40 } 41 write!(out, "typename {}", item); 42 if with_default { 43 write!(out, " = void"); 44 } 45 } 46 out.write(">"); 47 out.new_line(); 48 } 49 } 50 write_with_default<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>)51 pub fn write_with_default<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) { 52 self.write_internal(config, out, true); 53 } 54 } 55 56 impl Deref for GenericParams { 57 type Target = [Path]; 58 deref(&self) -> &[Path]59 fn deref(&self) -> &[Path] { 60 &self.0 61 } 62 } 63 64 impl Source for GenericParams { write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>)65 fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) { 66 self.write_internal(config, out, false); 67 } 68 } 69 70 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 71 pub struct GenericPath { 72 path: Path, 73 export_name: String, 74 generics: Vec<Type>, 75 ctype: Option<DeclarationType>, 76 } 77 78 impl GenericPath { new(path: Path, generics: Vec<Type>) -> Self79 pub fn new(path: Path, generics: Vec<Type>) -> Self { 80 let export_name = path.name().to_owned(); 81 Self { 82 path, 83 export_name, 84 generics, 85 ctype: None, 86 } 87 } 88 self_path() -> Self89 pub fn self_path() -> Self { 90 Self::new(Path::new("Self"), vec![]) 91 } 92 replace_self_with(&mut self, self_ty: &Path)93 pub fn replace_self_with(&mut self, self_ty: &Path) { 94 if self.path.replace_self_with(self_ty) { 95 self.export_name = self_ty.name().to_owned(); 96 } 97 // Caller deals with generics. 98 } 99 path(&self) -> &Path100 pub fn path(&self) -> &Path { 101 &self.path 102 } 103 generics(&self) -> &[Type]104 pub fn generics(&self) -> &[Type] { 105 &self.generics 106 } 107 generics_mut(&mut self) -> &mut [Type]108 pub fn generics_mut(&mut self) -> &mut [Type] { 109 &mut self.generics 110 } 111 ctype(&self) -> Option<&DeclarationType>112 pub fn ctype(&self) -> Option<&DeclarationType> { 113 self.ctype.as_ref() 114 } 115 name(&self) -> &str116 pub fn name(&self) -> &str { 117 self.path.name() 118 } 119 export_name(&self) -> &str120 pub fn export_name(&self) -> &str { 121 &self.export_name 122 } 123 rename_for_config(&mut self, config: &Config, generic_params: &GenericParams)124 pub fn rename_for_config(&mut self, config: &Config, generic_params: &GenericParams) { 125 for generic in &mut self.generics { 126 generic.rename_for_config(config, generic_params); 127 } 128 if !generic_params.contains(&self.path) { 129 config.export.rename(&mut self.export_name); 130 } 131 } 132 resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver)133 pub fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) { 134 self.ctype = resolver.type_for(&self.path); 135 } 136 load(path: &syn::Path) -> Result<Self, String>137 pub fn load(path: &syn::Path) -> Result<Self, String> { 138 assert!( 139 !path.segments.is_empty(), 140 "{:?} doesn't have any segments", 141 path 142 ); 143 let last_segment = path.segments.last().unwrap(); 144 let name = last_segment.ident.to_string(); 145 146 let path = Path::new(name); 147 let phantom_data_path = Path::new("PhantomData"); 148 if path == phantom_data_path { 149 return Ok(Self::new(path, Vec::new())); 150 } 151 152 let generics = match last_segment.arguments { 153 syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { 154 ref args, 155 .. 156 }) => args.iter().try_skip_map(|x| match *x { 157 syn::GenericArgument::Type(ref x) => Type::load(x), 158 syn::GenericArgument::Lifetime(_) => Ok(None), 159 _ => Err(format!("can't handle generic argument {:?}", x)), 160 })?, 161 syn::PathArguments::Parenthesized(_) => { 162 return Err("Path contains parentheses.".to_owned()); 163 } 164 _ => Vec::new(), 165 }; 166 167 Ok(Self::new(path, generics)) 168 } 169 } 170