Expand macro recursively expands both fp-like and attribute macros intertwined
This commit is contained in:
parent
fc71d49bc1
commit
5fa2b06819
@ -76,8 +76,6 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
|||||||
return derive;
|
return derive;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Intermix attribute and bang! expansions
|
|
||||||
// currently we only recursively expand one of the two types
|
|
||||||
let mut anc = tok.parent_ancestors();
|
let mut anc = tok.parent_ancestors();
|
||||||
let (name, expanded, kind) = loop {
|
let (name, expanded, kind) = loop {
|
||||||
let node = anc.next()?;
|
let node = anc.next()?;
|
||||||
@ -86,7 +84,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
|||||||
if let Some(def) = sema.resolve_attr_macro_call(&item) {
|
if let Some(def) = sema.resolve_attr_macro_call(&item) {
|
||||||
break (
|
break (
|
||||||
def.name(db).display(db).to_string(),
|
def.name(db).display(db).to_string(),
|
||||||
expand_attr_macro_recur(&sema, &item)?,
|
expand_macro_recur(&sema, &item)?,
|
||||||
SyntaxKind::MACRO_ITEMS,
|
SyntaxKind::MACRO_ITEMS,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -94,11 +92,9 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
|||||||
if let Some(mac) = ast::MacroCall::cast(node) {
|
if let Some(mac) = ast::MacroCall::cast(node) {
|
||||||
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
|
let mut name = mac.path()?.segment()?.name_ref()?.to_string();
|
||||||
name.push('!');
|
name.push('!');
|
||||||
break (
|
let syntax_kind =
|
||||||
name,
|
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
|
||||||
expand_macro_recur(&sema, &mac)?,
|
break (name, expand_macro_recur(&sema, &ast::Item::MacroCall(mac))?, syntax_kind);
|
||||||
mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,31 +108,23 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
|||||||
|
|
||||||
fn expand_macro_recur(
|
fn expand_macro_recur(
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
macro_call: &ast::MacroCall,
|
macro_call: &ast::Item,
|
||||||
) -> Option<SyntaxNode> {
|
) -> Option<SyntaxNode> {
|
||||||
let expanded = sema.expand(macro_call)?.clone_for_update();
|
let expanded = match macro_call {
|
||||||
expand(sema, expanded, ast::MacroCall::cast, expand_macro_recur)
|
item @ ast::Item::MacroCall(macro_call) => {
|
||||||
|
sema.expand_attr_macro(item).or_else(|| sema.expand(macro_call))?.clone_for_update()
|
||||||
|
}
|
||||||
|
item => sema.expand_attr_macro(item)?.clone_for_update(),
|
||||||
|
};
|
||||||
|
expand(sema, expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_attr_macro_recur(
|
fn expand(sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode) -> Option<SyntaxNode> {
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
let children = expanded.descendants().filter_map(ast::Item::cast);
|
||||||
item: &ast::Item,
|
|
||||||
) -> Option<SyntaxNode> {
|
|
||||||
let expanded = sema.expand_attr_macro(item)?.clone_for_update();
|
|
||||||
expand(sema, expanded, ast::Item::cast, expand_attr_macro_recur)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expand<T: AstNode>(
|
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
|
||||||
expanded: SyntaxNode,
|
|
||||||
f: impl FnMut(SyntaxNode) -> Option<T>,
|
|
||||||
exp: impl Fn(&Semantics<'_, RootDatabase>, &T) -> Option<SyntaxNode>,
|
|
||||||
) -> Option<SyntaxNode> {
|
|
||||||
let children = expanded.descendants().filter_map(f);
|
|
||||||
let mut replacements = Vec::new();
|
let mut replacements = Vec::new();
|
||||||
|
|
||||||
for child in children {
|
for child in children {
|
||||||
if let Some(new_node) = exp(sema, &child) {
|
if let Some(new_node) = expand_macro_recur(sema, &child) {
|
||||||
// check if the whole original syntax is replaced
|
// check if the whole original syntax is replaced
|
||||||
if expanded == *child.syntax() {
|
if expanded == *child.syntax() {
|
||||||
return Some(new_node);
|
return Some(new_node);
|
||||||
|
Loading…
Reference in New Issue
Block a user