mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-26 17:57:19 +00:00
fix: Fix expand macro recursively not working correctly for nested macro calls
This commit is contained in:
parent
14872a5332
commit
bd57ea0871
1 changed files with 49 additions and 46 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
use hir::db::ExpandDatabase;
|
use hir::db::ExpandDatabase;
|
||||||
use hir::{ExpandResult, InFile, InRealFile, Semantics};
|
use hir::{ExpandResult, InFile, Semantics};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
FileId, RootDatabase, base_db::Crate, helpers::pick_best_token,
|
FileId, RootDatabase, base_db::Crate, helpers::pick_best_token,
|
||||||
syntax_helpers::prettify_macro_expansion,
|
syntax_helpers::prettify_macro_expansion,
|
||||||
|
|
@ -87,52 +87,55 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
||||||
return derive;
|
return derive;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut anc = sema
|
let syntax_token = sema.descend_into_macros_exact(tok);
|
||||||
.descend_token_into_include_expansion(InRealFile::new(file_id, tok))
|
'tokens: for syntax_token in syntax_token {
|
||||||
.value
|
let mut anc = syntax_token.parent_ancestors();
|
||||||
.parent_ancestors();
|
let mut span_map = SpanMap::empty();
|
||||||
let mut span_map = SpanMap::empty();
|
let mut error = String::new();
|
||||||
let mut error = String::new();
|
let (name, expanded, kind) = loop {
|
||||||
let (name, expanded, kind) = loop {
|
let Some(node) = anc.next() else {
|
||||||
let node = anc.next()?;
|
continue 'tokens;
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(item) = ast::Item::cast(node.clone())
|
if let Some(item) = ast::Item::cast(node.clone())
|
||||||
&& let Some(def) = sema.resolve_attr_macro_call(&item)
|
&& let Some(def) = sema.resolve_attr_macro_call(&item)
|
||||||
{
|
{
|
||||||
break (
|
break (
|
||||||
def.name(db).display(db, file_id.edition(db)).to_string(),
|
def.name(db).display(db, file_id.edition(db)).to_string(),
|
||||||
expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
|
expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?,
|
||||||
SyntaxKind::MACRO_ITEMS,
|
SyntaxKind::MACRO_ITEMS,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
if let Some(mac) = ast::MacroCall::cast(node) {
|
||||||
|
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
|
||||||
|
name.push('!');
|
||||||
|
let syntax_kind =
|
||||||
|
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
|
||||||
|
break (
|
||||||
|
name,
|
||||||
|
expand_macro_recur(
|
||||||
|
&sema,
|
||||||
|
&ast::Item::MacroCall(mac),
|
||||||
|
&mut error,
|
||||||
|
&mut span_map,
|
||||||
|
TextSize::new(0),
|
||||||
|
)?,
|
||||||
|
syntax_kind,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
// macro expansion may lose all white space information
|
||||||
|
// But we hope someday we can use ra_fmt for that
|
||||||
|
let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
|
||||||
|
|
||||||
|
if !error.is_empty() {
|
||||||
|
expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
|
||||||
}
|
}
|
||||||
if let Some(mac) = ast::MacroCall::cast(node) {
|
return Some(ExpandedMacro { name, expansion });
|
||||||
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
|
|
||||||
name.push('!');
|
|
||||||
let syntax_kind =
|
|
||||||
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
|
|
||||||
break (
|
|
||||||
name,
|
|
||||||
expand_macro_recur(
|
|
||||||
&sema,
|
|
||||||
&ast::Item::MacroCall(mac),
|
|
||||||
&mut error,
|
|
||||||
&mut span_map,
|
|
||||||
TextSize::new(0),
|
|
||||||
)?,
|
|
||||||
syntax_kind,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME:
|
|
||||||
// macro expansion may lose all white space information
|
|
||||||
// But we hope someday we can use ra_fmt for that
|
|
||||||
let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
|
|
||||||
|
|
||||||
if !error.is_empty() {
|
|
||||||
expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n"));
|
|
||||||
}
|
}
|
||||||
Some(ExpandedMacro { name, expansion })
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_macro_recur(
|
fn expand_macro_recur(
|
||||||
|
|
@ -752,8 +755,8 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
my_concat!
|
concat!
|
||||||
"<>hi""#]],
|
"<>""#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue