mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 21:35:20 +00:00
Treat Derive Macro specially.
This commit is contained in:
parent
4bd2f948bb
commit
2c2bbe07fd
6 changed files with 87 additions and 40 deletions
|
@ -180,7 +180,7 @@ pub(crate) fn process_cfg_attrs(
|
|||
db: &dyn ExpandDatabase,
|
||||
) -> Option<FxHashSet<SyntaxElement>> {
|
||||
// FIXME: #[cfg_eval] is not implemented. But it is not stable yet
|
||||
if !matches!(loc.kind, MacroCallKind::Derive { .. }) {
|
||||
if !matches!(loc.kind, MacroCallKind::Derive { .. } | MacroCallKind::DeriveAttr { .. }) {
|
||||
return None;
|
||||
}
|
||||
let mut remove = FxHashSet::default();
|
||||
|
|
|
@ -7,7 +7,6 @@ use mbe::syntax_node_to_token_tree;
|
|||
use rustc_hash::FxHashSet;
|
||||
use span::{AstIdMap, Span, SyntaxContextData, SyntaxContextId};
|
||||
use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T};
|
||||
use tracing::debug;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
|
@ -158,7 +157,8 @@ pub fn expand_speculative(
|
|||
SyntaxFixupUndoInfo::NONE,
|
||||
),
|
||||
MacroCallKind::Derive { derive_attr_index: index, .. }
|
||||
| MacroCallKind::Attr { invoc_attr_index: index, .. } => {
|
||||
| MacroCallKind::Attr { invoc_attr_index: index, .. }
|
||||
| MacroCallKind::DeriveAttr { invoc_attr_index: index, .. } => {
|
||||
let censor = if let MacroCallKind::Derive { .. } = loc.kind {
|
||||
censor_derive_input(index, &ast::Adt::cast(speculative_args.clone())?)
|
||||
} else {
|
||||
|
@ -347,31 +347,18 @@ type MacroArgResult = (Arc<tt::Subtree>, SyntaxFixupUndoInfo, Span);
|
|||
/// Other wise return the [macro_arg] for the macro_call_id.
|
||||
///
|
||||
/// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is
|
||||
///
|
||||
/// FIXME: Pick a better name
|
||||
fn smart_macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
|
||||
let loc = db.lookup_intern_macro_call(id);
|
||||
fn macro_arg_considering_derives(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
|
||||
let macro_call_kind = db.lookup_intern_macro_call(id).kind;
|
||||
// FIXME: We called lookup_intern_macro_call twice.
|
||||
match loc.kind {
|
||||
match macro_call_kind {
|
||||
// Get the macro arg for the derive macro
|
||||
MacroCallKind::Derive { derive_macro_id, .. } => {
|
||||
debug!(
|
||||
?loc,
|
||||
"{id:?} is a derive macro. Using the derive macro, id: {derive_macro_id:?}, attribute as the macro arg."
|
||||
);
|
||||
db.macro_arg(derive_macro_id)
|
||||
}
|
||||
MacroCallKind::Derive { derive_macro_id, .. } => db.macro_arg(derive_macro_id),
|
||||
// Normal macro arg
|
||||
_ => db.macro_arg(id),
|
||||
}
|
||||
}
|
||||
|
||||
fn macro_arg(
|
||||
db: &dyn ExpandDatabase,
|
||||
id: MacroCallId,
|
||||
// FIXME: consider the following by putting fixup info into eager call info args
|
||||
// ) -> ValueResult<Arc<(tt::Subtree, SyntaxFixupUndoInfo)>, Arc<Box<[SyntaxError]>>> {
|
||||
) -> MacroArgResult {
|
||||
fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
|
||||
let loc = db.lookup_intern_macro_call(id);
|
||||
|
||||
if let MacroCallLoc {
|
||||
|
@ -441,7 +428,9 @@ fn macro_arg(
|
|||
}
|
||||
return (Arc::new(tt), SyntaxFixupUndoInfo::NONE, span);
|
||||
}
|
||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
||||
// MacroCallKind::Derive should not be here. As we are getting the argument for the derive macro
|
||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. }
|
||||
| MacroCallKind::DeriveAttr { ast_id, invoc_attr_index: derive_attr_index } => {
|
||||
let node = ast_id.to_ptr(db).to_node(&root);
|
||||
let censor_derive_input = censor_derive_input(derive_attr_index, &node);
|
||||
let item_node = node.into();
|
||||
|
@ -553,7 +542,7 @@ fn macro_expand(
|
|||
let (ExpandResult { value: tt, err }, span) = match loc.def.kind {
|
||||
MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id).map(CowArc::Arc),
|
||||
_ => {
|
||||
let (macro_arg, undo_info, span) = smart_macro_arg(db, macro_call_id);
|
||||
let (macro_arg, undo_info, span) = macro_arg_considering_derives(db, macro_call_id);
|
||||
|
||||
let arg = &*macro_arg;
|
||||
let res =
|
||||
|
@ -630,7 +619,7 @@ fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId<ast::Fn>) -> Span {
|
|||
|
||||
fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt::Subtree>> {
|
||||
let loc = db.lookup_intern_macro_call(id);
|
||||
let (macro_arg, undo_info, span) = smart_macro_arg(db, id);
|
||||
let (macro_arg, undo_info, span) = macro_arg_considering_derives(db, id);
|
||||
|
||||
let (expander, ast) = match loc.def.kind {
|
||||
MacroDefKind::ProcMacro(expander, _, ast) => (expander, ast),
|
||||
|
|
|
@ -228,6 +228,10 @@ pub enum MacroCallKind {
|
|||
/// We will resolve the same token tree for all derive macros in the same derive attribute.
|
||||
derive_macro_id: MacroCallId,
|
||||
},
|
||||
DeriveAttr {
|
||||
ast_id: AstId<ast::Adt>,
|
||||
invoc_attr_index: AttrId,
|
||||
},
|
||||
Attr {
|
||||
ast_id: AstId<ast::Item>,
|
||||
// FIXME: This shouldn't be here, we can derive this from `invoc_attr_index`
|
||||
|
@ -515,7 +519,8 @@ impl MacroCallLoc {
|
|||
MacroCallKind::FnLike { ast_id, .. } => {
|
||||
ast_id.with_value(ast_id.to_node(db).syntax().clone())
|
||||
}
|
||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. }
|
||||
| MacroCallKind::DeriveAttr { ast_id, invoc_attr_index: derive_attr_index } => {
|
||||
// FIXME: handle `cfg_attr`
|
||||
ast_id.with_value(ast_id.to_node(db)).map(|it| {
|
||||
collect_attrs(&it)
|
||||
|
@ -549,7 +554,7 @@ impl MacroCallLoc {
|
|||
fn expand_to(&self) -> ExpandTo {
|
||||
match self.kind {
|
||||
MacroCallKind::FnLike { expand_to, .. } => expand_to,
|
||||
MacroCallKind::Derive { .. } => ExpandTo::Items,
|
||||
MacroCallKind::Derive { .. } | MacroCallKind::DeriveAttr { .. } => ExpandTo::Items,
|
||||
MacroCallKind::Attr { .. } if self.def.is_attribute_derive() => ExpandTo::Items,
|
||||
MacroCallKind::Attr { .. } => {
|
||||
// FIXME(stmt_expr_attributes)
|
||||
|
@ -583,6 +588,7 @@ impl MacroCallKind {
|
|||
MacroCallKind::FnLike { .. } => "macro call",
|
||||
MacroCallKind::Derive { .. } => "derive macro",
|
||||
MacroCallKind::Attr { .. } => "attribute macro",
|
||||
MacroCallKind::DeriveAttr { .. } => "derive attribute",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,6 +597,7 @@ impl MacroCallKind {
|
|||
match *self {
|
||||
MacroCallKind::FnLike { ast_id: InFile { file_id, .. }, .. }
|
||||
| MacroCallKind::Derive { ast_id: InFile { file_id, .. }, .. }
|
||||
| MacroCallKind::DeriveAttr { ast_id: InFile { file_id, .. }, .. }
|
||||
| MacroCallKind::Attr { ast_id: InFile { file_id, .. }, .. } => file_id,
|
||||
}
|
||||
}
|
||||
|
@ -598,7 +605,8 @@ impl MacroCallKind {
|
|||
pub fn erased_ast_id(&self) -> ErasedFileAstId {
|
||||
match *self {
|
||||
MacroCallKind::FnLike { ast_id: InFile { value, .. }, .. } => value.erase(),
|
||||
MacroCallKind::Derive { ast_id: InFile { value, .. }, .. } => value.erase(),
|
||||
MacroCallKind::Derive { ast_id: InFile { value, .. }, .. }
|
||||
| MacroCallKind::DeriveAttr { ast_id: InFile { value, .. }, .. } => value.erase(),
|
||||
MacroCallKind::Attr { ast_id: InFile { value, .. }, .. } => value.erase(),
|
||||
}
|
||||
}
|
||||
|
@ -619,7 +627,9 @@ impl MacroCallKind {
|
|||
|
||||
let range = match kind {
|
||||
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_ptr(db).text_range(),
|
||||
MacroCallKind::Derive { ast_id, .. } => ast_id.to_ptr(db).text_range(),
|
||||
MacroCallKind::Derive { ast_id, .. } | MacroCallKind::DeriveAttr { ast_id, .. } => {
|
||||
ast_id.to_ptr(db).text_range()
|
||||
}
|
||||
MacroCallKind::Attr { ast_id, .. } => ast_id.to_ptr(db).text_range(),
|
||||
};
|
||||
|
||||
|
@ -665,6 +675,15 @@ impl MacroCallKind {
|
|||
.syntax()
|
||||
.text_range()
|
||||
}
|
||||
MacroCallKind::DeriveAttr { ast_id, invoc_attr_index } => {
|
||||
collect_attrs(&ast_id.to_node(db))
|
||||
.nth(invoc_attr_index.ast_index())
|
||||
.expect("missing attribute")
|
||||
.1
|
||||
.expect_left("attribute macro is a doc comment?")
|
||||
.syntax()
|
||||
.text_range()
|
||||
}
|
||||
};
|
||||
|
||||
FileRange { range, file_id }
|
||||
|
@ -675,7 +694,7 @@ impl MacroCallKind {
|
|||
MacroCallKind::FnLike { ast_id, .. } => {
|
||||
ast_id.to_in_file_node(db).map(|it| Some(it.token_tree()?.syntax().clone()))
|
||||
}
|
||||
MacroCallKind::Derive { ast_id, .. } => {
|
||||
MacroCallKind::Derive { ast_id, .. } | MacroCallKind::DeriveAttr { ast_id, .. } => {
|
||||
ast_id.to_in_file_node(db).syntax().cloned().map(Some)
|
||||
}
|
||||
MacroCallKind::Attr { ast_id, .. } => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue