diff options
-rw-r--r-- | src/ir/context.rs | 170 |
1 files changed, 91 insertions, 79 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs index 24213ebc..07731dde 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -34,38 +34,105 @@ use std::mem; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ItemId(usize); -/// An identifier for an `Item` whose `ItemKind` is known to be -/// `ItemKind::Type`. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct TypeId(ItemId); +macro_rules! item_id_newtype { + ( + $( #[$attr:meta] )* + pub struct $name:ident(ItemId) + where + $( #[$checked_attr:meta] )* + checked = $checked:ident with $check_method:ident, + $( #[$expected_attr:meta] )* + expected = $expected:ident, + $( #[$unchecked_attr:meta] )* + unchecked = $unchecked:ident; + ) => { + $( #[$attr] )* + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct $name(ItemId); + + impl $name { + /// Create an `ItemResolver` from this id. + pub fn into_resolver(self) -> ItemResolver { + let id: ItemId = self.into(); + id.into() + } + } -/// An identifier for an `Item` whose `ItemKind` is known to be -/// `ItemKind::Module`. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ModuleId(ItemId); + impl From<$name> for ItemId { + fn from(id: $name) -> ItemId { + id.0 + } + } -impl From<TypeId> for ItemId { - fn from(tid: TypeId) -> ItemId { - tid.0 - } -} + impl<'a> From<&'a $name> for ItemId { + fn from(id: &'a $name) -> ItemId { + id.0 + } + } + + impl ItemId { + $( #[$checked_attr] )* + pub fn $checked(&self, ctx: &BindgenContext) -> Option<$name> { + if ctx.resolve_item(*self).kind().$check_method() { + Some($name(*self)) + } else { + None + } + } + + $( #[$expected_attr] )* + pub fn $expected(&self, ctx: &BindgenContext) -> $name { + self.$checked(ctx) + .expect(concat!( + stringify!($expected), + " called with ItemId that points to the wrong ItemKind" + )) + } -impl<'a> From<&'a TypeId> for ItemId { - fn from(tid: &'a TypeId) -> ItemId { - tid.0 + $( #[$unchecked_attr] )* + pub fn $unchecked(&self) -> $name { + $name(*self) + } + } } } -impl From<ModuleId> for ItemId { - fn from(mid: ModuleId) -> ItemId { - mid.0 - } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Type`. + pub struct TypeId(ItemId) + where + /// Convert this `ItemId` into a `TypeId` if its associated item is a type, + /// otherwise return `None`. + checked = as_type_id with is_type, + + /// Convert this `ItemId` into a `TypeId`. + /// + /// If this `ItemId` does not point to a type, then panic. + expected = expect_type_id, + + /// Convert this `ItemId` into a `TypeId` without actually checking whether + /// this id actually points to a `Type`. + unchecked = as_type_id_unchecked; } -impl<'a> From<&'a ModuleId> for ItemId { - fn from(mid: &'a ModuleId) -> ItemId { - mid.0 - } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Module`. + pub struct ModuleId(ItemId) + where + /// Convert this `ItemId` into a `ModuleId` if its associated item is a + /// module, otherwise return `None`. + checked = as_module_id with is_module, + + /// Convert this `ItemId` into a `ModuleId`. + /// + /// If this `ItemId` does not point to a module, then panic. + expected = expect_module_id, + + /// Convert this `ItemId` into a `ModuleId` without actually checking + /// whether this id actually points to a `Module`. + unchecked = as_module_id_unchecked; } impl From<ItemId> for usize { @@ -79,54 +146,6 @@ impl ItemId { pub fn as_usize(&self) -> usize { (*self).into() } - - /// Convert this `ItemId` into a `TypeId` if its associated item is a type, - /// otherwise return `None`. - pub fn as_type_id(&self, ctx: &BindgenContext) -> Option<TypeId> { - if ctx.resolve_item(*self).kind().is_type() { - Some(TypeId(*self)) - } else { - None - } - } - - /// Convert this `ItemId` into a `TypeId`. - /// - /// If this `ItemId` does not point to a type, then panic. - pub fn expect_type_id(&self, ctx: &BindgenContext) -> TypeId { - self.as_type_id(ctx) - .expect("expect_type_id called with ItemId that doesn't point to a type") - } - - /// Convert this `ItemId` into a `TypeId` without actually checking whether - /// this id actually points to a `Type`. - pub fn as_type_id_unchecked(&self) -> TypeId { - TypeId(*self) - } - - /// Convert this `ItemId` into a `ModuleId` if its associated item is a module, - /// otherwise return `None`. - pub fn as_module_id(&self, ctx: &BindgenContext) -> Option<ModuleId> { - if ctx.resolve_item(*self).kind().is_module() { - Some(ModuleId(*self)) - } else { - None - } - } - - /// Convert this `ItemId` into a `ModuleId`. - /// - /// If this `ItemId` does not point to a module, then panic. - pub fn expect_module_id(&self, ctx: &BindgenContext) -> ModuleId { - self.as_module_id(ctx) - .expect("expect_module_id called with ItemId that doesn't point to a module") - } - - /// Convert this `ItemId` into a `ModuleId` without actually checking whether - /// this id actually points to a `Module`. - pub fn as_module_id_unchecked(&self) -> ModuleId { - ModuleId(*self) - } } impl<T> CanDeriveDebug for T @@ -2375,13 +2394,6 @@ impl ItemId { } } -impl TypeId { - pub fn into_resolver(self) -> ItemResolver { - let id: ItemId = self.into(); - id.into() - } -} - impl<T> From<T> for ItemResolver where T: Into<ItemId> |