• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Context for lowering paths.
2 use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile};
3 use once_cell::unsync::OnceCell;
4 use syntax::ast;
5 use triomphe::Arc;
6 
7 use crate::{db::DefDatabase, path::Path};
8 
9 pub struct LowerCtx<'a> {
10     pub db: &'a dyn DefDatabase,
11     hygiene: Hygiene,
12     ast_id_map: Option<(HirFileId, OnceCell<Arc<AstIdMap>>)>,
13 }
14 
15 impl<'a> LowerCtx<'a> {
new(db: &'a dyn DefDatabase, hygiene: &Hygiene, file_id: HirFileId) -> Self16     pub fn new(db: &'a dyn DefDatabase, hygiene: &Hygiene, file_id: HirFileId) -> Self {
17         LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: Some((file_id, OnceCell::new())) }
18     }
19 
with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self20     pub fn with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self {
21         LowerCtx {
22             db,
23             hygiene: Hygiene::new(db.upcast(), file_id),
24             ast_id_map: Some((file_id, OnceCell::new())),
25         }
26     }
27 
with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self28     pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self {
29         LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: None }
30     }
31 
hygiene(&self) -> &Hygiene32     pub(crate) fn hygiene(&self) -> &Hygiene {
33         &self.hygiene
34     }
35 
lower_path(&self, ast: ast::Path) -> Option<Path>36     pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
37         Path::from_src(ast, self)
38     }
39 
ast_id<N: syntax::AstNode>(&self, item: &N) -> Option<AstId<N>>40     pub(crate) fn ast_id<N: syntax::AstNode>(&self, item: &N) -> Option<AstId<N>> {
41         let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?;
42         let ast_id_map = ast_id_map.get_or_init(|| self.db.ast_id_map(file_id));
43         Some(InFile::new(file_id, ast_id_map.ast_id(item)))
44     }
45 }
46