1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use std::collections::BTreeMap; 6 use std::mem; 7 8 use crate::bindgen::config::Config; 9 use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; 10 use crate::bindgen::dependencies::Dependencies; 11 use crate::bindgen::ir::{ 12 AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Path, Static, Struct, Type, Typedef, Union, 13 }; 14 use crate::bindgen::library::Library; 15 use crate::bindgen::monomorph::Monomorphs; 16 17 /// An item is any type of rust item besides a function 18 pub trait Item { path(&self) -> &Path19 fn path(&self) -> &Path; name(&self) -> &str20 fn name(&self) -> &str { 21 self.path().name() 22 } export_name(&self) -> &str23 fn export_name(&self) -> &str { 24 self.name() 25 } cfg(&self) -> Option<&Cfg>26 fn cfg(&self) -> Option<&Cfg>; annotations(&self) -> &AnnotationSet27 fn annotations(&self) -> &AnnotationSet; annotations_mut(&mut self) -> &mut AnnotationSet28 fn annotations_mut(&mut self) -> &mut AnnotationSet; 29 container(&self) -> ItemContainer30 fn container(&self) -> ItemContainer; 31 collect_declaration_types(&self, _resolver: &mut DeclarationTypeResolver)32 fn collect_declaration_types(&self, _resolver: &mut DeclarationTypeResolver) { 33 unimplemented!() 34 } resolve_declaration_types(&mut self, _resolver: &DeclarationTypeResolver)35 fn resolve_declaration_types(&mut self, _resolver: &DeclarationTypeResolver) { 36 unimplemented!() 37 } rename_for_config(&mut self, _config: &Config)38 fn rename_for_config(&mut self, _config: &Config) {} add_dependencies(&self, _library: &Library, _out: &mut Dependencies)39 fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) {} instantiate_monomorph(&self, _generics: &[Type], _library: &Library, _out: &mut Monomorphs)40 fn instantiate_monomorph(&self, _generics: &[Type], _library: &Library, _out: &mut Monomorphs) { 41 unreachable!("Cannot instantiate {} as a generic.", self.name()) 42 } 43 } 44 45 #[derive(Debug, Clone)] 46 pub enum ItemContainer { 47 Constant(Constant), 48 Static(Static), 49 OpaqueItem(OpaqueItem), 50 Struct(Struct), 51 Union(Union), 52 Enum(Enum), 53 Typedef(Typedef), 54 } 55 56 impl ItemContainer { deref(&self) -> &dyn Item57 pub fn deref(&self) -> &dyn Item { 58 match *self { 59 ItemContainer::Constant(ref x) => x, 60 ItemContainer::Static(ref x) => x, 61 ItemContainer::OpaqueItem(ref x) => x, 62 ItemContainer::Struct(ref x) => x, 63 ItemContainer::Union(ref x) => x, 64 ItemContainer::Enum(ref x) => x, 65 ItemContainer::Typedef(ref x) => x, 66 } 67 } 68 } 69 70 #[derive(Debug, Clone)] 71 pub enum ItemValue<T: Item> { 72 Cfg(Vec<T>), 73 Single(T), 74 } 75 76 #[derive(Debug, Clone)] 77 pub struct ItemMap<T: Item> { 78 data: BTreeMap<Path, ItemValue<T>>, 79 } 80 81 impl<T: Item + Clone> ItemMap<T> { new() -> ItemMap<T>82 pub fn new() -> ItemMap<T> { 83 ItemMap { 84 data: BTreeMap::new(), 85 } 86 } 87 rebuild(&mut self)88 pub fn rebuild(&mut self) { 89 let old = mem::replace(self, ItemMap::new()); 90 old.for_all_items(|x| { 91 self.try_insert(x.clone()); 92 }); 93 } 94 try_insert(&mut self, item: T) -> bool95 pub fn try_insert(&mut self, item: T) -> bool { 96 match (item.cfg().is_some(), self.data.get_mut(item.path())) { 97 (true, Some(&mut ItemValue::Cfg(ref mut items))) => { 98 items.push(item); 99 return true; 100 } 101 (false, Some(&mut ItemValue::Cfg(_))) => { 102 return false; 103 } 104 (true, Some(&mut ItemValue::Single(_))) => { 105 return false; 106 } 107 (false, Some(&mut ItemValue::Single(_))) => { 108 return false; 109 } 110 _ => {} 111 } 112 113 let path = item.path().clone(); 114 if item.cfg().is_some() { 115 self.data.insert(path, ItemValue::Cfg(vec![item])); 116 } else { 117 self.data.insert(path, ItemValue::Single(item)); 118 } 119 120 true 121 } 122 extend_with(&mut self, other: &ItemMap<T>)123 pub fn extend_with(&mut self, other: &ItemMap<T>) { 124 other.for_all_items(|x| { 125 self.try_insert(x.clone()); 126 }); 127 } 128 to_vec(&self) -> Vec<T>129 pub fn to_vec(&self) -> Vec<T> { 130 let mut result = Vec::with_capacity(self.data.len()); 131 for container in self.data.values() { 132 match *container { 133 ItemValue::Cfg(ref items) => result.extend_from_slice(items), 134 ItemValue::Single(ref item) => { 135 result.push(item.clone()); 136 } 137 } 138 } 139 result 140 } 141 get_items(&self, path: &Path) -> Option<Vec<ItemContainer>>142 pub fn get_items(&self, path: &Path) -> Option<Vec<ItemContainer>> { 143 Some(match *self.data.get(path)? { 144 ItemValue::Cfg(ref items) => items.iter().map(|x| x.container()).collect(), 145 ItemValue::Single(ref item) => vec![item.container()], 146 }) 147 } 148 filter<F>(&mut self, callback: F) where F: Fn(&T) -> bool,149 pub fn filter<F>(&mut self, callback: F) 150 where 151 F: Fn(&T) -> bool, 152 { 153 let data = mem::replace(&mut self.data, BTreeMap::new()); 154 155 for (name, container) in data { 156 match container { 157 ItemValue::Cfg(items) => { 158 let mut new_items = Vec::new(); 159 for item in items { 160 if !callback(&item) { 161 new_items.push(item); 162 } 163 } 164 if !new_items.is_empty() { 165 self.data.insert(name, ItemValue::Cfg(new_items)); 166 } 167 } 168 ItemValue::Single(item) => { 169 if !callback(&item) { 170 self.data.insert(name, ItemValue::Single(item)); 171 } 172 } 173 } 174 } 175 } 176 for_all_items<F>(&self, mut callback: F) where F: FnMut(&T),177 pub fn for_all_items<F>(&self, mut callback: F) 178 where 179 F: FnMut(&T), 180 { 181 for container in self.data.values() { 182 match *container { 183 ItemValue::Cfg(ref items) => { 184 for item in items { 185 callback(item); 186 } 187 } 188 ItemValue::Single(ref item) => callback(item), 189 } 190 } 191 } 192 for_all_items_mut<F>(&mut self, mut callback: F) where F: FnMut(&mut T),193 pub fn for_all_items_mut<F>(&mut self, mut callback: F) 194 where 195 F: FnMut(&mut T), 196 { 197 for container in self.data.values_mut() { 198 match *container { 199 ItemValue::Cfg(ref mut items) => { 200 for item in items { 201 callback(item); 202 } 203 } 204 ItemValue::Single(ref mut item) => callback(item), 205 } 206 } 207 } 208 for_items<F>(&self, path: &Path, mut callback: F) where F: FnMut(&T),209 pub fn for_items<F>(&self, path: &Path, mut callback: F) 210 where 211 F: FnMut(&T), 212 { 213 match self.data.get(path) { 214 Some(&ItemValue::Cfg(ref items)) => { 215 for item in items { 216 callback(item); 217 } 218 } 219 Some(&ItemValue::Single(ref item)) => { 220 callback(item); 221 } 222 None => {} 223 } 224 } 225 for_items_mut<F>(&mut self, path: &Path, mut callback: F) where F: FnMut(&mut T),226 pub fn for_items_mut<F>(&mut self, path: &Path, mut callback: F) 227 where 228 F: FnMut(&mut T), 229 { 230 match self.data.get_mut(path) { 231 Some(&mut ItemValue::Cfg(ref mut items)) => { 232 for item in items { 233 callback(item); 234 } 235 } 236 Some(&mut ItemValue::Single(ref mut item)) => { 237 callback(item); 238 } 239 None => {} 240 } 241 } 242 } 243