]> git.lizzy.rs Git - rust.git/blob - crates/ra_hir_expand/src/hygiene.rs
Replace `ra_hir_expand::either` with crate
[rust.git] / crates / ra_hir_expand / src / hygiene.rs
1 //! This modules handles hygiene information.
2 //!
3 //! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at
4 //! this moment, this is horribly incomplete and handles only `$crate`.
5 use either::Either;
6 use ra_db::CrateId;
7 use ra_syntax::ast;
8
9 use crate::{
10     db::AstDatabase,
11     name::{AsName, Name},
12     HirFileId, HirFileIdRepr, MacroDefKind,
13 };
14
15 #[derive(Debug)]
16 pub struct Hygiene {
17     // This is what `$crate` expands to
18     def_crate: Option<CrateId>,
19 }
20
21 impl Hygiene {
22     pub fn new(db: &impl AstDatabase, file_id: HirFileId) -> Hygiene {
23         let def_crate = match file_id.0 {
24             HirFileIdRepr::FileId(_) => None,
25             HirFileIdRepr::MacroFile(macro_file) => {
26                 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
27                 match loc.def.kind {
28                     MacroDefKind::Declarative => Some(loc.def.krate),
29                     MacroDefKind::BuiltIn(_) => None,
30                 }
31             }
32         };
33         Hygiene { def_crate }
34     }
35
36     pub fn new_unhygienic() -> Hygiene {
37         Hygiene { def_crate: None }
38     }
39
40     // FIXME: this should just return name
41     pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> {
42         if let Some(def_crate) = self.def_crate {
43             if name_ref.text() == "$crate" {
44                 return Either::Right(def_crate);
45             }
46         }
47         Either::Left(name_ref.as_name())
48     }
49 }