From 57030f587bb0bbe4dea9a97016b4e0f49a7ef5f3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 31 Dec 2018 19:19:50 +0300 Subject: use macros database in analysis --- crates/ra_analysis/src/db.rs | 3 ++ crates/ra_analysis/src/extend_selection.rs | 8 ++-- crates/ra_analysis/src/macros.rs | 67 +++++---------------------- crates/ra_analysis/src/syntax_highlighting.rs | 6 +-- crates/ra_hir/src/lib.rs | 1 + crates/ra_hir/src/macros.rs | 53 ++++++++++++++++++--- 6 files changed, 70 insertions(+), 68 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index b072a5eba..712f72484 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -98,5 +98,8 @@ salsa::database_storage! { fn struct_data() for hir::db::StructDataQuery; fn enum_data() for hir::db::EnumDataQuery; } + impl hir::MacroDatabase { + fn expand_macro() for hir::ExpandMacroQuery; + } } } diff --git a/crates/ra_analysis/src/extend_selection.rs b/crates/ra_analysis/src/extend_selection.rs index 805e9059e..62133ef29 100644 --- a/crates/ra_analysis/src/extend_selection.rs +++ b/crates/ra_analysis/src/extend_selection.rs @@ -23,10 +23,10 @@ fn extend_selection_in_macro( frange: FileRange, ) -> Option { let macro_call = find_macro_call(source_file.syntax(), frange.range)?; - let exp = crate::macros::expand(db, frange.file_id, macro_call)?; - let dst_range = exp.map_range_forward(frange.range)?; - let dst_range = ra_editor::extend_selection(exp.source_file().syntax(), dst_range)?; - let src_range = exp.map_range_back(dst_range)?; + let (off, exp) = crate::macros::expand(db, frange.file_id, macro_call)?; + let dst_range = exp.map_range_forward(frange.range - off)?; + let dst_range = ra_editor::extend_selection(exp.syntax().borrowed(), dst_range)?; + let src_range = exp.map_range_back(dst_range)? + off; Some(src_range) } diff --git a/crates/ra_analysis/src/macros.rs b/crates/ra_analysis/src/macros.rs index b9feb7fad..21ec36cd6 100644 --- a/crates/ra_analysis/src/macros.rs +++ b/crates/ra_analysis/src/macros.rs @@ -1,15 +1,18 @@ /// Begining of macro expansion. /// /// This code should be moved out of ra_analysis into hir (?) ideally. -use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; +use std::sync::Arc; + +use ra_syntax::{ast, AstNode, TextUnit}; +use hir::MacroDatabase; use crate::{db::RootDatabase, FileId}; pub(crate) fn expand( - _db: &RootDatabase, + db: &RootDatabase, _file_id: FileId, macro_call: ast::MacroCall, -) -> Option { +) -> Option<(TextUnit, Arc)> { let path = macro_call.path()?; if path.qualifier().is_some() { return None; @@ -18,58 +21,12 @@ pub(crate) fn expand( if name_ref.text() != "ctry" { return None; } + let arg = macro_call.token_tree()?.syntax(); - let arg = macro_call.token_tree()?; - let text = format!( - r" - fn dummy() {{ - match {} {{ - None => return Ok(None), - Some(it) => it, - }} - }}", - arg.syntax().text() - ); - let file = SourceFileNode::parse(&text); - let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; - let match_arg = match_expr.expr()?; - let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())]; - let res = MacroExpansion { - source_file: file, - ranges_map, + let def = hir::MacroDef::CTry; + let input = hir::MacroInput { + text: arg.text().to_string(), }; - Some(res) -} - -pub(crate) struct MacroExpansion { - pub(crate) source_file: SourceFileNode, - pub(crate) ranges_map: Vec<(TextRange, TextRange)>, -} - -impl MacroExpansion { - pub(crate) fn source_file(&self) -> &SourceFileNode { - &self.source_file - } - pub(crate) fn map_range_back(&self, tgt_range: TextRange) -> Option { - for (s_range, t_range) in self.ranges_map.iter() { - if tgt_range.is_subrange(&t_range) { - let tgt_at_zero_range = tgt_range - tgt_range.start(); - let tgt_range_offset = tgt_range.start() - t_range.start(); - let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); - return Some(src_range); - } - } - None - } - pub(crate) fn map_range_forward(&self, src_range: TextRange) -> Option { - for (s_range, t_range) in self.ranges_map.iter() { - if src_range.is_subrange(&s_range) { - let src_at_zero_range = src_range - src_range.start(); - let src_range_offset = src_range.start() - s_range.start(); - let src_range = src_at_zero_range + src_range_offset + t_range.start(); - return Some(src_range); - } - } - None - } + let exp = db.expand_macro(def, input)?; + Some((arg.range().start(), exp)) } diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 7e9139a74..35a4630e9 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -15,13 +15,13 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable, + ptr: LocalSyntaxPtr, } salsa::query_group! { -pub trait MacrosDatabase: SyntaxDatabase { +pub trait MacroDatabase: SyntaxDatabase { fn expand_macro(def: MacroDef, input: MacroInput) -> Option> { type ExpandMacroQuery; } @@ -32,7 +36,7 @@ pub trait MacrosDatabase: SyntaxDatabase { } fn expand_macro( - _db: &impl MacrosDatabase, + _db: &impl MacroDatabase, def: MacroDef, input: MacroInput, ) -> Option> { @@ -50,8 +54,45 @@ fn expand_macro( let file = SourceFileNode::parse(&text); let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; let match_arg = match_expr.expr()?; + let ptr = LocalSyntaxPtr::new(match_arg.syntax()); let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); let ranges_map = vec![(src_range, match_arg.syntax().range())]; - let res = MacroExpansion { text, ranges_map }; + let res = MacroExpansion { + text, + ranges_map, + ptr, + }; Some(Arc::new(res)) } + +impl MacroExpansion { + pub fn file(&self) -> SourceFileNode { + SourceFileNode::parse(&self.text) + } + + pub fn syntax(&self) -> SyntaxNode { + self.ptr.resolve(&self.file()) + } + pub fn map_range_back(&self, tgt_range: TextRange) -> Option { + for (s_range, t_range) in self.ranges_map.iter() { + if tgt_range.is_subrange(&t_range) { + let tgt_at_zero_range = tgt_range - tgt_range.start(); + let tgt_range_offset = tgt_range.start() - t_range.start(); + let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); + return Some(src_range); + } + } + None + } + pub fn map_range_forward(&self, src_range: TextRange) -> Option { + for (s_range, t_range) in self.ranges_map.iter() { + if src_range.is_subrange(&s_range) { + let src_at_zero_range = src_range - src_range.start(); + let src_range_offset = src_range.start() - s_range.start(); + let src_range = src_at_zero_range + src_range_offset + t_range.start(); + return Some(src_range); + } + } + None + } +} -- cgit v1.2.3