diff options
Diffstat (limited to 'crates/ra_hir/src/code_model')
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 7c9454c0b..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::{self, AstNode}; | 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 | HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, | 8 | Function, HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, |
6 | Trait, TypeAlias, 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 { |
@@ -117,12 +130,12 @@ where | |||
117 | self, | 130 | self, |
118 | db: &impl HirDatabase, | 131 | db: &impl HirDatabase, |
119 | expr_id: crate::expr::ExprId, | 132 | expr_id: crate::expr::ExprId, |
120 | ) -> Option<Source<ast::Expr>> { | 133 | ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> { |
121 | let source_map = self.body_source_map(db); | 134 | let source_map = self.body_source_map(db); |
122 | let expr_syntax = source_map.expr_syntax(expr_id)?.a()?; | 135 | let source_ptr = source_map.expr_syntax(expr_id)?; |
123 | let source = self.source(db); | 136 | let root = source_ptr.file_syntax(db); |
124 | let ast = expr_syntax.to_node(&source.ast.syntax()); | 137 | let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root))); |
125 | Some(Source { file_id: source.file_id, ast }) | 138 | Some(source) |
126 | } | 139 | } |
127 | } | 140 | } |
128 | 141 | ||