From 24e98121d81b75bafcd9c6005548776c00de8401 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 7 Mar 2020 15:27:03 +0100 Subject: Try to complete within macros --- crates/ra_hir/Cargo.toml | 2 ++ crates/ra_hir/src/semantics.rs | 55 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 0555a0de7..266c4cff3 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -12,6 +12,8 @@ log = "0.4.8" rustc-hash = "1.1.0" either = "1.5.3" +itertools = "0.8.2" + ra_syntax = { path = "../ra_syntax" } ra_db = { path = "../ra_db" } ra_prof = { path = "../ra_prof" } diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 965d185a4..56bd763c7 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -6,13 +6,14 @@ use std::{cell::RefCell, fmt, iter::successors}; use hir_def::{ resolver::{self, HasResolver, Resolver}, - TraitId, + AsMacroCall, TraitId, }; use hir_expand::ExpansionInfo; use ra_db::{FileId, FileRange}; use ra_prof::profile; use ra_syntax::{ - algo::skip_trivia_token, ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, + algo::{self, skip_trivia_token}, + ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, }; use rustc_hash::{FxHashMap, FxHashSet}; @@ -70,6 +71,37 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { Some(node) } + pub fn expand_hypothetical( + &self, + actual_macro_call: &ast::MacroCall, + hypothetical_call: &ast::MacroCall, + token_to_map: SyntaxToken, + ) -> Option<(SyntaxNode, SyntaxToken)> { + let macro_call = + self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); + 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)) + } + pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { let parent = token.parent(); let parent = self.find_file(parent); @@ -104,6 +136,25 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { node.ancestors_with_macros(self.db).map(|it| it.value) } + pub fn ancestors_at_offset_with_macros( + &self, + node: &SyntaxNode, + offset: TextUnit, + ) -> impl Iterator + '_ { + use itertools::Itertools; + node.token_at_offset(offset) + .map(|token| self.ancestors_with_macros(token.parent())) + .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) + } + + pub fn find_node_at_offset_with_macros( + &self, + node: &SyntaxNode, + offset: TextUnit, + ) -> Option { + self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast) + } + pub fn type_of_expr(&self, expr: &ast::Expr) -> Option { self.analyze(expr.syntax()).type_of(self.db, &expr) } -- cgit v1.2.3 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 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'crates/ra_hir') 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 { -- cgit v1.2.3