aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model/src.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model/src.rs')
-rw-r--r--crates/ra_hir/src/code_model/src.rs45
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 @@
1use ra_syntax::ast; 1use ra_syntax::{
2 ast::{self, AstNode},
3 SyntaxNode,
4};
2 5
3use crate::{ 6use 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)]
9pub struct Source<T> { 13pub 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
23impl<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.
21impl Module { 34impl 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
125pub trait HasBodySource: HasBody + HasSource
126where
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
142impl<T> HasBodySource for T
143where
144 T: HasBody + HasSource,
145 T::Ast: AstNode,
146{
147}