From 9c3b25177e3c8d609dd24d2c2e01cbb82cab665f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 3 Sep 2019 11:04:38 +0300 Subject: Correctly build BodySourceMap for macro-expanded expressions --- crates/ra_hir/src/code_model/src.rs | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'crates/ra_hir/src/code_model') 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 @@ -use ra_syntax::ast::{self, AstNode}; +use ra_syntax::{ + ast::{self, AstNode}, + SyntaxNode, +}; use crate::{ - ids::AstItemDef, AstDatabase, Const, DefDatabase, Enum, EnumVariant, FieldSource, Function, - HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, StructField, - Trait, TypeAlias, Union, + ids::AstItemDef, AstDatabase, Const, DefDatabase, Either, Enum, EnumVariant, FieldSource, + Function, HasBody, HirDatabase, HirFileId, MacroDef, Module, ModuleSource, Static, Struct, + StructField, Trait, TypeAlias, Union, }; +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct Source { pub file_id: HirFileId, pub ast: T, @@ -16,6 +20,15 @@ pub trait HasSource { fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source; } +impl Source { + pub(crate) fn map U, U>(self, f: F) -> Source { + Source { file_id: self.file_id, ast: f(self.ast) } + } + pub(crate) fn file_syntax(&self, db: &impl AstDatabase) -> SyntaxNode { + db.parse_or_expand(self.file_id).expect("source created from invalid file") + } +} + /// NB: Module is !HasSource, because it has two source nodes at the same time: /// definition and declaration. impl Module { @@ -117,12 +130,12 @@ where self, db: &impl HirDatabase, expr_id: crate::expr::ExprId, - ) -> Option> { + ) -> Option>> { let source_map = self.body_source_map(db); - let expr_syntax = source_map.expr_syntax(expr_id)?.a()?; - let source = self.source(db); - let ast = expr_syntax.to_node(&source.ast.syntax()); - Some(Source { file_id: source.file_id, ast }) + let source_ptr = source_map.expr_syntax(expr_id)?; + let root = source_ptr.file_syntax(db); + let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root))); + Some(source) } } -- cgit v1.2.3