diff options
Diffstat (limited to 'crates/ra_hir/src/code_model')
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 32bd9c661..b9ffb0c7a 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,11 +1,15 @@ | |||
1 | use ra_syntax::ast; | 1 | use ra_syntax::{ |
2 | ast::{self, AstNode}, | ||
3 | SyntaxNode, | ||
4 | }; | ||
2 | 5 | ||
3 | use crate::{ | 6 | use crate::{ |
4 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, | 7 | ids::AstItemDef, AstDatabase, Const, DefDatabase, Either, Enum, EnumVariant, FieldSource, |
5 | HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, | 8 | Function, HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, |
6 | Union, | 9 | StructField, Trait, TypeAlias, Union, |
7 | }; | 10 | }; |
8 | 11 | ||
12 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
9 | pub struct Source<T> { | 13 | pub struct Source<T> { |
10 | pub file_id: HirFileId, | 14 | pub file_id: HirFileId, |
11 | pub ast: T, | 15 | pub ast: T, |
@@ -16,6 +20,15 @@ pub trait HasSource { | |||
16 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; | 20 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; |
17 | } | 21 | } |
18 | 22 | ||
23 | impl<T> Source<T> { | ||
24 | pub(crate) fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { | ||
25 | Source { file_id: self.file_id, ast: f(self.ast) } | ||
26 | } | ||
27 | pub(crate) fn file_syntax(&self, db: &impl AstDatabase) -> SyntaxNode { | ||
28 | db.parse_or_expand(self.file_id).expect("source created from invalid file") | ||
29 | } | ||
30 | } | ||
31 | |||
19 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | 32 | /// NB: Module is !HasSource, because it has two source nodes at the same time: |
20 | /// definition and declaration. | 33 | /// definition and declaration. |
21 | impl Module { | 34 | impl Module { |
@@ -108,3 +121,27 @@ impl HasSource for MacroDef { | |||
108 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } | 121 | Source { file_id: self.id.0.file_id(), ast: self.id.0.to_node(db) } |
109 | } | 122 | } |
110 | } | 123 | } |
124 | |||
125 | pub trait HasBodySource: HasBody + HasSource | ||
126 | where | ||
127 | Self::Ast: AstNode, | ||
128 | { | ||
129 | fn expr_source( | ||
130 | self, | ||
131 | db: &impl HirDatabase, | ||
132 | expr_id: crate::expr::ExprId, | ||
133 | ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> { | ||
134 | let source_map = self.body_source_map(db); | ||
135 | let source_ptr = source_map.expr_syntax(expr_id)?; | ||
136 | let root = source_ptr.file_syntax(db); | ||
137 | let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root))); | ||
138 | Some(source) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl<T> HasBodySource for T | ||
143 | where | ||
144 | T: HasBody + HasSource, | ||
145 | T::Ast: AstNode, | ||
146 | { | ||
147 | } | ||