Store invocation site for eager macros
This commit is contained in:
parent
b98ee075ee
commit
26f604b907
@ -563,6 +563,7 @@ fn expand_builtin_macro(ra_fixture: &str) -> String {
|
||||
|
||||
let args = macro_call.token_tree().unwrap();
|
||||
let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0;
|
||||
let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_call));
|
||||
|
||||
let arg_id = db.intern_eager_expansion({
|
||||
EagerCallLoc {
|
||||
@ -570,7 +571,7 @@ fn expand_builtin_macro(ra_fixture: &str) -> String {
|
||||
fragment: FragmentKind::Expr,
|
||||
subtree: Arc::new(parsed_args.clone()),
|
||||
krate,
|
||||
file_id: file_id.into(),
|
||||
call: call_id,
|
||||
}
|
||||
});
|
||||
|
||||
@ -580,7 +581,7 @@ fn expand_builtin_macro(ra_fixture: &str) -> String {
|
||||
fragment,
|
||||
subtree: Arc::new(subtree),
|
||||
krate,
|
||||
file_id: file_id.into(),
|
||||
call: call_id,
|
||||
};
|
||||
|
||||
let id: MacroCallId = db.intern_eager_expansion(eager).into();
|
||||
|
@ -5,7 +5,7 @@
|
||||
use base_db::{salsa, SourceDatabase};
|
||||
use mbe::{ExpandError, ExpandResult, MacroRules};
|
||||
use parser::FragmentKind;
|
||||
use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode};
|
||||
use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode};
|
||||
|
||||
use crate::{
|
||||
ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId,
|
||||
@ -129,11 +129,11 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
|
||||
fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
|
||||
match id.kind {
|
||||
MacroDefKind::Declarative => {
|
||||
let macro_call = match id.ast_id?.to_node(db) {
|
||||
let macro_rules = match id.ast_id?.to_node(db) {
|
||||
syntax::ast::Macro::MacroRules(mac) => mac,
|
||||
syntax::ast::Macro::MacroDef(_) => return None,
|
||||
};
|
||||
let arg = macro_call.token_tree()?;
|
||||
let arg = macro_rules.token_tree()?;
|
||||
let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| {
|
||||
log::warn!("fail on macro_def to token tree: {:#?}", arg);
|
||||
None
|
||||
@ -141,7 +141,8 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander,
|
||||
let rules = match MacroRules::parse(&tt) {
|
||||
Ok(it) => it,
|
||||
Err(err) => {
|
||||
log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt);
|
||||
let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default();
|
||||
log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
@ -110,6 +110,9 @@ pub fn expand_eager_macro(
|
||||
|| err("malformed macro invocation"),
|
||||
)?;
|
||||
|
||||
let ast_map = db.ast_id_map(macro_call.file_id);
|
||||
let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value));
|
||||
|
||||
// Note:
|
||||
// When `lazy_expand` is called, its *parent* file must be already exists.
|
||||
// Here we store an eager macro id for the argument expanded subtree here
|
||||
@ -120,7 +123,7 @@ pub fn expand_eager_macro(
|
||||
fragment: FragmentKind::Expr,
|
||||
subtree: Arc::new(parsed_args.clone()),
|
||||
krate,
|
||||
file_id: macro_call.file_id,
|
||||
call: call_id,
|
||||
}
|
||||
});
|
||||
let arg_file_id: MacroCallId = arg_id.into();
|
||||
@ -141,13 +144,8 @@ pub fn expand_eager_macro(
|
||||
let res = eager.expand(db, arg_id, &subtree);
|
||||
|
||||
let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?;
|
||||
let eager = EagerCallLoc {
|
||||
def,
|
||||
fragment,
|
||||
subtree: Arc::new(subtree),
|
||||
krate,
|
||||
file_id: macro_call.file_id,
|
||||
};
|
||||
let eager =
|
||||
EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id };
|
||||
|
||||
Ok(db.intern_eager_expansion(eager))
|
||||
} else {
|
||||
|
@ -83,7 +83,7 @@ pub fn original_file(self, db: &dyn db::AstDatabase) -> FileId {
|
||||
}
|
||||
MacroCallId::EagerMacro(id) => {
|
||||
let loc = db.lookup_intern_eager_expansion(id);
|
||||
loc.file_id
|
||||
loc.call.file_id
|
||||
}
|
||||
};
|
||||
file_id.original_file(db)
|
||||
@ -103,7 +103,7 @@ pub fn expansion_level(self, db: &dyn db::AstDatabase) -> u32 {
|
||||
}
|
||||
MacroCallId::EagerMacro(id) => {
|
||||
let loc = db.lookup_intern_eager_expansion(id);
|
||||
loc.file_id
|
||||
loc.call.file_id
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -114,17 +114,16 @@ pub fn expansion_level(self, db: &dyn db::AstDatabase) -> u32 {
|
||||
pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
|
||||
match self.0 {
|
||||
HirFileIdRepr::FileId(_) => None,
|
||||
HirFileIdRepr::MacroFile(macro_file) => {
|
||||
let lazy_id = match macro_file.macro_call_id {
|
||||
MacroCallId::LazyMacro(id) => id,
|
||||
MacroCallId::EagerMacro(_id) => {
|
||||
// FIXME: handle call node for eager macro
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let loc = db.lookup_intern_macro(lazy_id);
|
||||
Some(loc.kind.node(db))
|
||||
}
|
||||
HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
|
||||
MacroCallId::LazyMacro(lazy_id) => {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
|
||||
Some(loc.kind.node(db))
|
||||
}
|
||||
MacroCallId::EagerMacro(id) => {
|
||||
let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id);
|
||||
Some(loc.call.with_value(loc.call.to_node(db).syntax().clone()))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +303,7 @@ pub struct EagerCallLoc {
|
||||
pub(crate) fragment: FragmentKind,
|
||||
pub(crate) subtree: Arc<tt::Subtree>,
|
||||
pub(crate) krate: CrateId,
|
||||
pub(crate) file_id: HirFileId,
|
||||
pub(crate) call: AstId<ast::MacroCall>,
|
||||
}
|
||||
|
||||
/// ExpansionInfo mainly describes how to map text range between src and expanded macro
|
||||
|
@ -749,6 +749,31 @@ fn test() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_through_included_file() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! include {}
|
||||
|
||||
include!("foo.rs");
|
||||
//^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
fn f() {
|
||||
foo<|>();
|
||||
}
|
||||
|
||||
mod confuse_index {
|
||||
pub fn foo() {}
|
||||
}
|
||||
|
||||
//- /foo.rs
|
||||
fn foo() {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_for_type_param() {
|
||||
check(
|
||||
|
Loading…
Reference in New Issue
Block a user