From afdf08e964345ac4a884a5630772611ba81f6969 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 8 Mar 2020 11:02:14 +0100 Subject: Move hypothetical expansion to hir_expand --- crates/ra_hir/src/semantics.rs | 24 ++---------- crates/ra_hir_expand/src/db.rs | 43 +++++++++++++++++----- crates/ra_hir_expand/src/lib.rs | 9 +---- crates/ra_ide/src/completion/completion_context.rs | 6 ++- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 56bd763c7..3782a9984 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -12,8 +12,7 @@ use hir_expand::ExpansionInfo; use ra_db::{FileId, FileRange}; use ra_prof::profile; use ra_syntax::{ - algo::{self, skip_trivia_token}, - ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, + algo::skip_trivia_token, ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, }; use rustc_hash::{FxHashMap, FxHashSet}; @@ -74,7 +73,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { pub fn expand_hypothetical( &self, actual_macro_call: &ast::MacroCall, - hypothetical_call: &ast::MacroCall, + hypothetical_args: &ast::TokenTree, token_to_map: SyntaxToken, ) -> Option<(SyntaxNode, SyntaxToken)> { let macro_call = @@ -82,24 +81,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); let macro_call_id = macro_call .as_call_id(self.db, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; - let macro_file = macro_call_id.as_file().macro_file().unwrap(); - let (tt, tmap_1) = - hir_expand::syntax_node_to_token_tree(hypothetical_call.token_tree().unwrap().syntax()) - .unwrap(); - let range = token_to_map - .text_range() - .checked_sub(hypothetical_call.token_tree().unwrap().syntax().text_range().start())?; - let token_id = tmap_1.token_by_range(range)?; - let macro_def = hir_expand::db::expander(self.db, macro_call_id)?; - let (node, tmap_2) = hir_expand::db::parse_macro_with_arg( - self.db, - macro_file, - Some(std::sync::Arc::new((tt, tmap_1))), - )?; - let token_id = macro_def.0.map_id_down(token_id); - let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; - let token = algo::find_covering_element(&node.syntax_node(), range).into_token()?; - Some((node.syntax_node(), token)) + hir_expand::db::expand_hypothetical(self.db, macro_call_id, hypothetical_args, token_to_map) } pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index f5c8bc22f..29dde3d80 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -72,6 +72,30 @@ pub trait AstDatabase: SourceDatabase { fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; } +/// This expands the given macro call, but with different arguments. This is +/// used for completion, where we want to see what 'would happen' if we insert a +/// token. The `token_to_map` mapped down into the expansion, with the mapped +/// token returned. +pub fn expand_hypothetical( + db: &impl AstDatabase, + actual_macro_call: MacroCallId, + hypothetical_args: &ra_syntax::ast::TokenTree, + token_to_map: ra_syntax::SyntaxToken, +) -> Option<(SyntaxNode, ra_syntax::SyntaxToken)> { + let macro_file = MacroFile { macro_call_id: actual_macro_call }; + let (tt, tmap_1) = mbe::syntax_node_to_token_tree(hypothetical_args.syntax()).unwrap(); + let range = + token_to_map.text_range().checked_sub(hypothetical_args.syntax().text_range().start())?; + let token_id = tmap_1.token_by_range(range)?; + let macro_def = expander(db, actual_macro_call)?; + let (node, tmap_2) = + parse_macro_with_arg(db, macro_file, Some(std::sync::Arc::new((tt, tmap_1))))?; + let token_id = macro_def.0.map_id_down(token_id); + let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; + let token = ra_syntax::algo::find_covering_element(&node.syntax_node(), range).into_token()?; + Some((node.syntax_node(), token)) +} + pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc { let map = db.parse_or_expand(file_id).map_or_else(AstIdMap::default, |it| AstIdMap::from_source(&it)); @@ -133,10 +157,7 @@ pub(crate) fn macro_expand( macro_expand_with_arg(db, id, None) } -pub fn expander( - db: &dyn AstDatabase, - id: MacroCallId, -) -> Option> { +fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option> { let lazy_id = match id { MacroCallId::LazyMacro(id) => id, MacroCallId::EagerMacro(_id) => { @@ -149,7 +170,7 @@ pub fn expander( Some(macro_rules) } -pub(crate) fn macro_expand_with_arg( +fn macro_expand_with_arg( db: &dyn AstDatabase, id: MacroCallId, arg: Option>, @@ -158,7 +179,9 @@ pub(crate) fn macro_expand_with_arg( MacroCallId::LazyMacro(id) => id, MacroCallId::EagerMacro(id) => { if arg.is_some() { - return Err("hypothetical macro expansion not implemented for eager macro".to_owned()); + return Err( + "hypothetical macro expansion not implemented for eager macro".to_owned() + ); } else { return Ok(db.lookup_intern_eager_expansion(id).subtree); } @@ -225,13 +248,15 @@ pub fn parse_macro_with_arg( .collect::>() .join("\n"); - eprintln!( + log::warn!( "fail on macro_parse: (reason: {} macro_call: {:#}) parents: {}", - err, node.value, parents + err, + node.value, + parents ); } _ => { - eprintln!("fail on macro_parse: (reason: {})", err); + log::warn!("fail on macro_parse: (reason: {})", err); } } }) diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 92f3902dd..3fce73e8a 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -157,13 +157,6 @@ impl HirFileId { } } } - - pub fn macro_file(self) -> Option { - match self.0 { - HirFileIdRepr::FileId(_) => None, - HirFileIdRepr::MacroFile(m) => Some(m), - } - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -303,7 +296,7 @@ pub struct ExpansionInfo { exp_map: Arc, } -pub use mbe::{syntax_node_to_token_tree, Origin}; +pub use mbe::Origin; use ra_parser::FragmentKind; impl ExpansionInfo { diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index e7a8c78d0..40535c09e 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -119,11 +119,15 @@ impl<'a> CompletionContext<'a> { { break; } + let hypothetical_args = match macro_call_with_fake_ident.token_tree() { + Some(tt) => tt, + None => break, + }; if let (Some(actual_expansion), Some(hypothetical_expansion)) = ( ctx.sema.expand(&actual_macro_call), ctx.sema.expand_hypothetical( &actual_macro_call, - ¯o_call_with_fake_ident, + &hypothetical_args, fake_ident_token, ), ) { -- cgit v1.2.3