mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Make "expand macro" command work with attribute macros
This commit is contained in:
parent
8d87f9b298
commit
33e747d786
2 changed files with 43 additions and 7 deletions
|
@ -117,6 +117,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
|
pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
|
||||||
self.imp.expand(macro_call)
|
self.imp.expand(macro_call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If `item` has an attribute macro attached to it, expands it.
|
||||||
|
pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
|
||||||
|
self.imp.expand_attr_macro(item)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn speculative_expand(
|
pub fn speculative_expand(
|
||||||
&self,
|
&self,
|
||||||
actual_macro_call: &ast::MacroCall,
|
actual_macro_call: &ast::MacroCall,
|
||||||
|
@ -332,6 +338,16 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
Some(node)
|
Some(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
|
||||||
|
let sa = self.analyze(item.syntax());
|
||||||
|
let src = InFile::new(sa.file_id, item.clone());
|
||||||
|
let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src))?;
|
||||||
|
let file_id = macro_call_id.as_file();
|
||||||
|
let node = self.db.parse_or_expand(file_id)?;
|
||||||
|
self.cache(node.clone(), file_id);
|
||||||
|
Some(node)
|
||||||
|
}
|
||||||
|
|
||||||
fn speculative_expand(
|
fn speculative_expand(
|
||||||
&self,
|
&self,
|
||||||
actual_macro_call: &ast::MacroCall,
|
actual_macro_call: &ast::MacroCall,
|
||||||
|
|
|
@ -3,8 +3,7 @@ use std::iter;
|
||||||
use hir::Semantics;
|
use hir::Semantics;
|
||||||
use ide_db::RootDatabase;
|
use ide_db::RootDatabase;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::find_node_at_offset, ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*,
|
ast, match_ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, SyntaxNode, WalkEvent, T,
|
||||||
SyntaxNode, WalkEvent, T,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::FilePosition;
|
use crate::FilePosition;
|
||||||
|
@ -28,16 +27,37 @@ pub struct ExpandedMacro {
|
||||||
pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
|
pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
let file = sema.parse(position.file_id);
|
let file = sema.parse(position.file_id);
|
||||||
let mac = find_node_at_offset::<ast::MacroCall>(file.syntax(), position.offset)?;
|
|
||||||
let name = mac.path()?.segment()?.name_ref()?;
|
|
||||||
|
|
||||||
let expanded = expand_macro_recur(&sema, &mac)?;
|
let tok = file.syntax().token_at_offset(position.offset).left_biased()?;
|
||||||
|
let mut expanded = None;
|
||||||
|
let mut name = None;
|
||||||
|
for node in tok.ancestors() {
|
||||||
|
match_ast! {
|
||||||
|
match node {
|
||||||
|
ast::MacroCall(mac) => {
|
||||||
|
name = Some(mac.path()?.segment()?.name_ref()?.to_string());
|
||||||
|
expanded = expand_macro_recur(&sema, &mac);
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
ast::Item(item) => {
|
||||||
|
// FIXME: add the macro name
|
||||||
|
// FIXME: make this recursive too
|
||||||
|
name = Some("?".to_string());
|
||||||
|
expanded = sema.expand_attr_macro(&item);
|
||||||
|
if expanded.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// macro expansion may lose all white space information
|
// macro expansion may lose all white space information
|
||||||
// But we hope someday we can use ra_fmt for that
|
// But we hope someday we can use ra_fmt for that
|
||||||
let expansion = insert_whitespaces(expanded);
|
let expansion = insert_whitespaces(expanded?);
|
||||||
Some(ExpandedMacro { name: name.to_string(), expansion })
|
Some(ExpandedMacro { name: name?, expansion })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_macro_recur(
|
fn expand_macro_recur(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue