| //! Module that define a common trait for things that represent a crate definition, | |
| //! such as, a function, a trait, an enum, and any other definitions. | |
| use crate::ty::{GenericArgs, Span, Ty, index_impl}; | |
| use crate::{Crate, Symbol, ThreadLocalIndex, with}; | |
| /// A unique identification number for each item accessible for the current compilation unit. | |
| #[derive(Clone, Copy, PartialEq, Eq, Hash)] | |
| pub struct DefId(pub(crate) usize, ThreadLocalIndex); | |
| index_impl!(DefId); | |
| impl DefId { | |
| /// Return fully qualified name of this definition | |
| pub fn name(&self) -> Symbol { | |
| with(|cx| cx.def_name(*self, false)) | |
| } | |
| /// Return a trimmed name of this definition. | |
| /// | |
| /// This can be used to print more user friendly diagnostic messages. | |
| /// | |
| /// If a symbol name can only be imported from one place for a type, and as | |
| /// long as it was not glob-imported anywhere in the current crate, we trim its | |
| /// path and print only the name. | |
| /// | |
| /// For example, this function may shorten `std::vec::Vec` to just `Vec`, | |
| /// as long as there is no other `Vec` importable anywhere. | |
| pub fn trimmed_name(&self) -> Symbol { | |
| with(|cx| cx.def_name(*self, true)) | |
| } | |
| /// Return the parent of this definition, or `None` if this is the root of a | |
| /// crate. | |
| pub fn parent(&self) -> Option<DefId> { | |
| with(|cx| cx.def_parent(*self)) | |
| } | |
| pub fn span(&self) -> Span { | |
| with(|cx| cx.span_of_a_def(*self)) | |
| } | |
| } | |
| /// A trait for retrieving information about a particular definition. | |
| /// | |
| /// Implementors must provide the implementation of `def_id` which will be used to retrieve | |
| /// information about a crate's definition. | |
| pub trait CrateDef { | |
| /// Retrieve the unique identifier for the current definition. | |
| fn def_id(&self) -> DefId; | |
| /// Return the fully qualified name of the current definition. | |
| /// | |
| /// See [`DefId::name`] for more details | |
| fn name(&self) -> Symbol { | |
| self.def_id().name() | |
| } | |
| /// Return a trimmed name of this definition. | |
| /// | |
| /// See [`DefId::trimmed_name`] for more details | |
| fn trimmed_name(&self) -> Symbol { | |
| self.def_id().trimmed_name() | |
| } | |
| /// Return information about the crate where this definition is declared. | |
| /// | |
| /// This will return the crate number and its name. | |
| fn krate(&self) -> Crate { | |
| let def_id = self.def_id(); | |
| with(|cx| cx.krate(def_id)) | |
| } | |
| /// Return the span of this definition. | |
| fn span(&self) -> Span { | |
| self.def_id().span() | |
| } | |
| /// Return registered tool attributes with the given attribute name. | |
| /// | |
| /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool | |
| /// attributes will simply return an empty list. | |
| /// | |
| /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. | |
| /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. | |
| fn tool_attrs(&self, attr: &[Symbol]) -> Vec<Attribute> { | |
| let def_id = self.def_id(); | |
| with(|cx| cx.tool_attrs(def_id, attr)) | |
| } | |
| /// Return all tool attributes of this definition. | |
| fn all_tool_attrs(&self) -> Vec<Attribute> { | |
| let def_id = self.def_id(); | |
| with(|cx| cx.all_tool_attrs(def_id)) | |
| } | |
| } | |
| /// A trait that can be used to retrieve a definition's type. | |
| /// | |
| /// Note that not every CrateDef has a type `Ty`. They should not implement this trait. | |
| pub trait CrateDefType: CrateDef { | |
| /// Returns the type of this crate item. | |
| fn ty(&self) -> Ty { | |
| with(|cx| cx.def_ty(self.def_id())) | |
| } | |
| /// Retrieve the type of this definition by instantiating and normalizing it with `args`. | |
| /// | |
| /// This will panic if instantiation fails. | |
| fn ty_with_args(&self, args: &GenericArgs) -> Ty { | |
| with(|cx| cx.def_ty_with_args(self.def_id(), args)) | |
| } | |
| } | |
| #[derive(Clone, Debug, PartialEq, Eq)] | |
| pub struct Attribute { | |
| value: String, | |
| span: Span, | |
| } | |
| impl Attribute { | |
| pub fn new(value: String, span: Span) -> Attribute { | |
| Attribute { value, span } | |
| } | |
| /// Get the span of this attribute. | |
| pub fn span(&self) -> Span { | |
| self.span | |
| } | |
| /// Get the string representation of this attribute. | |
| pub fn as_str(&self) -> &str { | |
| &self.value | |
| } | |
| } | |
| macro_rules! crate_def { | |
| ( $(#[$attr:meta])* | |
| $vis:vis $name:ident $(;)? | |
| ) => { | |
| $(#[$attr])* | |
| #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | |
| $vis struct $name(pub DefId); | |
| impl CrateDef for $name { | |
| fn def_id(&self) -> DefId { | |
| self.0 | |
| } | |
| } | |
| }; | |
| } | |
| macro_rules! crate_def_with_ty { | |
| ( $(#[$attr:meta])* | |
| $vis:vis $name:ident $(;)? | |
| ) => { | |
| $(#[$attr])* | |
| #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | |
| $vis struct $name(pub DefId); | |
| impl CrateDef for $name { | |
| fn def_id(&self) -> DefId { | |
| self.0 | |
| } | |
| } | |
| impl CrateDefType for $name {} | |
| }; | |
| ( $(#[$attr:meta])* | |
| $vis:vis $name:ident { | |
| $( | |
| $(#[$f_attr:meta])* | |
| $f_vis:vis $f_name:ident: $f_ty:ty, | |
| )* | |
| } | |
| ) => { | |
| $(#[$attr])* | |
| #[derive(Clone, PartialEq, Eq, Debug)] | |
| $vis struct $name { | |
| pub(crate) def: DefId, | |
| $( | |
| $(#[$f_attr])* | |
| $f_vis $f_name: $f_ty, | |
| )* | |
| } | |
| impl CrateDef for $name { | |
| fn def_id(&self) -> DefId { | |
| self.def | |
| } | |
| } | |
| impl CrateDefType for $name {} | |
| }; | |
| } |