From ae71a631fd657368e8593feb5e025d23147afe60 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:36:55 +0200 Subject: Rename ra_hir -> hir --- crates/hir/src/has_source.rs | 135 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 crates/hir/src/has_source.rs (limited to 'crates/hir/src/has_source.rs') diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs new file mode 100644 index 000000000..a50d4ff02 --- /dev/null +++ b/crates/hir/src/has_source.rs @@ -0,0 +1,135 @@ +//! FIXME: write short doc here + +use either::Either; +use hir_def::{ + nameres::{ModuleOrigin, ModuleSource}, + src::{HasChildSource, HasSource as _}, + Lookup, VariantId, +}; +use syntax::ast; + +use crate::{ + db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, MacroDef, + Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, +}; + +pub use hir_expand::InFile; + +pub trait HasSource { + type Ast; + fn source(self, db: &dyn HirDatabase) -> InFile; +} + +/// NB: Module is !HasSource, because it has two source nodes at the same time: +/// definition and declaration. +impl Module { + /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. + pub fn definition_source(self, db: &dyn HirDatabase) -> InFile { + let def_map = db.crate_def_map(self.id.krate); + def_map[self.id.local_id].definition_source(db.upcast()) + } + + pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { + let def_map = db.crate_def_map(self.id.krate); + match def_map[self.id.local_id].origin { + ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs, + _ => false, + } + } + + /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. + /// `None` for the crate root. + pub fn declaration_source(self, db: &dyn HirDatabase) -> Option> { + let def_map = db.crate_def_map(self.id.krate); + def_map[self.id.local_id].declaration_source(db.upcast()) + } +} + +impl HasSource for Field { + type Ast = FieldSource; + fn source(self, db: &dyn HirDatabase) -> InFile { + let var = VariantId::from(self.parent); + let src = var.child_source(db.upcast()); + src.map(|it| match it[self.id].clone() { + Either::Left(it) => FieldSource::Pos(it), + Either::Right(it) => FieldSource::Named(it), + }) + } +} +impl HasSource for Struct { + type Ast = ast::Struct; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for Union { + type Ast = ast::Union; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for Enum { + type Ast = ast::Enum; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for EnumVariant { + type Ast = ast::Variant; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()) + } +} +impl HasSource for Function { + type Ast = ast::Fn; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for Const { + type Ast = ast::Const; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for Static { + type Ast = ast::Static; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for Trait { + type Ast = ast::Trait; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for TypeAlias { + type Ast = ast::TypeAlias; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} +impl HasSource for MacroDef { + type Ast = ast::MacroCall; + fn source(self, db: &dyn HirDatabase) -> InFile { + InFile { + file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, + value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()), + } + } +} +impl HasSource for ImplDef { + type Ast = ast::Impl; + fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } +} + +impl HasSource for TypeParam { + type Ast = Either; + fn source(self, db: &dyn HirDatabase) -> InFile { + let child_source = self.id.parent.child_source(db.upcast()); + child_source.map(|it| it[self.id.local_id].clone()) + } +} -- cgit v1.2.3