1 //! Provides set of implementation for hir's objects that allows get back location in file.
5 nameres::{ModuleOrigin, ModuleSource},
6 src::{HasChildSource, HasSource as _},
9 use hir_expand::InFile;
13 db::HirDatabase, Const, ConstParam, Enum, Field, FieldSource, Function, Impl, LifetimeParam,
14 MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
19 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast>;
22 /// NB: Module is !HasSource, because it has two source nodes at the same time:
23 /// definition and declaration.
25 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
26 pub fn definition_source(self, db: &dyn HirDatabase) -> InFile<ModuleSource> {
27 let def_map = db.crate_def_map(self.id.krate);
28 def_map[self.id.local_id].definition_source(db.upcast())
31 pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool {
32 let def_map = db.crate_def_map(self.id.krate);
33 match def_map[self.id.local_id].origin {
34 ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs,
39 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
40 /// `None` for the crate root.
41 pub fn declaration_source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Module>> {
42 let def_map = db.crate_def_map(self.id.krate);
43 def_map[self.id.local_id].declaration_source(db.upcast())
47 impl HasSource for Field {
48 type Ast = FieldSource;
49 fn source(self, db: &dyn HirDatabase) -> InFile<FieldSource> {
50 let var = VariantId::from(self.parent);
51 let src = var.child_source(db.upcast());
52 src.map(|it| match it[self.id].clone() {
53 Either::Left(it) => FieldSource::Pos(it),
54 Either::Right(it) => FieldSource::Named(it),
58 impl HasSource for Struct {
59 type Ast = ast::Struct;
60 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Struct> {
61 self.id.lookup(db.upcast()).source(db.upcast())
64 impl HasSource for Union {
65 type Ast = ast::Union;
66 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Union> {
67 self.id.lookup(db.upcast()).source(db.upcast())
70 impl HasSource for Enum {
72 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Enum> {
73 self.id.lookup(db.upcast()).source(db.upcast())
76 impl HasSource for Variant {
77 type Ast = ast::Variant;
78 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> {
79 self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone())
82 impl HasSource for Function {
84 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Fn> {
85 self.id.lookup(db.upcast()).source(db.upcast())
88 impl HasSource for Const {
89 type Ast = ast::Const;
90 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Const> {
91 self.id.lookup(db.upcast()).source(db.upcast())
94 impl HasSource for Static {
95 type Ast = ast::Static;
96 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Static> {
97 self.id.lookup(db.upcast()).source(db.upcast())
100 impl HasSource for Trait {
101 type Ast = ast::Trait;
102 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Trait> {
103 self.id.lookup(db.upcast()).source(db.upcast())
106 impl HasSource for TypeAlias {
107 type Ast = ast::TypeAlias;
108 fn source(self, db: &dyn HirDatabase) -> InFile<ast::TypeAlias> {
109 self.id.lookup(db.upcast()).source(db.upcast())
112 impl HasSource for MacroDef {
113 type Ast = ast::Macro;
114 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Macro> {
116 file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id,
117 value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()),
121 impl HasSource for Impl {
122 type Ast = ast::Impl;
123 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> {
124 self.id.lookup(db.upcast()).source(db.upcast())
128 impl HasSource for TypeParam {
129 type Ast = Either<ast::Trait, ast::TypeParam>;
130 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
131 let child_source = self.id.parent.child_source(db.upcast());
132 child_source.map(|it| it[self.id.local_id].clone())
136 impl HasSource for LifetimeParam {
137 type Ast = ast::LifetimeParam;
138 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
139 let child_source = self.id.parent.child_source(db.upcast());
140 child_source.map(|it| it[self.id.local_id].clone())
144 impl HasSource for ConstParam {
145 type Ast = ast::ConstParam;
146 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
147 let child_source = self.id.parent.child_source(db.upcast());
148 child_source.map(|it| it[self.id.local_id].clone())