mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Encode one level of cfg_attr in attr_id
This commit is contained in:
parent
68723043db
commit
621e96bd6a
11 changed files with 99 additions and 52 deletions
|
@ -546,7 +546,7 @@ impl AttrSourceMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
|
fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
|
||||||
let ast_idx = id.ast_index as usize;
|
let ast_idx = id.ast_index();
|
||||||
let file_id = match self.mod_def_site_file_id {
|
let file_id = match self.mod_def_site_file_id {
|
||||||
Some((file_id, def_site_cut)) if def_site_cut <= ast_idx => file_id,
|
Some((file_id, def_site_cut)) if def_site_cut <= ast_idx => file_id,
|
||||||
_ => self.file_id,
|
_ => self.file_id,
|
||||||
|
|
|
@ -117,7 +117,7 @@ impl ChildBySource for ItemScope {
|
||||||
let adt = ast_id.to_node(db.upcast());
|
let adt = ast_id.to_node(db.upcast());
|
||||||
calls.for_each(|(attr_id, call_id, calls)| {
|
calls.for_each(|(attr_id, call_id, calls)| {
|
||||||
if let Some(Either::Left(attr)) =
|
if let Some(Either::Left(attr)) =
|
||||||
adt.doc_comments_and_attrs().nth(attr_id.ast_index as usize)
|
adt.doc_comments_and_attrs().nth(attr_id.ast_index())
|
||||||
{
|
{
|
||||||
res[keys::DERIVE_MACRO_CALL].insert(attr, (attr_id, call_id, calls.into()));
|
res[keys::DERIVE_MACRO_CALL].insert(attr, (attr_id, call_id, calls.into()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -941,7 +941,7 @@ pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
fn derive_macro_as_call_id(
|
fn derive_macro_as_call_id(
|
||||||
db: &dyn db::DefDatabase,
|
db: &dyn db::DefDatabase,
|
||||||
item_attr: &AstIdWithPath<ast::Adt>,
|
item_attr: &AstIdWithPath<ast::Adt>,
|
||||||
derive_attr: AttrId,
|
derive_attr_index: AttrId,
|
||||||
derive_pos: u32,
|
derive_pos: u32,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
|
resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
|
||||||
|
@ -954,7 +954,7 @@ fn derive_macro_as_call_id(
|
||||||
MacroCallKind::Derive {
|
MacroCallKind::Derive {
|
||||||
ast_id: item_attr.ast_id,
|
ast_id: item_attr.ast_id,
|
||||||
derive_index: derive_pos,
|
derive_index: derive_pos,
|
||||||
derive_attr_index: derive_attr.ast_index,
|
derive_attr_index,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Ok((macro_id, def_id, call_id))
|
Ok((macro_id, def_id, call_id))
|
||||||
|
@ -982,7 +982,7 @@ fn attr_macro_as_call_id(
|
||||||
MacroCallKind::Attr {
|
MacroCallKind::Attr {
|
||||||
ast_id: item_attr.ast_id,
|
ast_id: item_attr.ast_id,
|
||||||
attr_args: Arc::new(arg),
|
attr_args: Arc::new(arg),
|
||||||
invoc_attr_index: macro_attr.id.ast_index,
|
invoc_attr_index: macro_attr.id,
|
||||||
is_derive,
|
is_derive,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -452,7 +452,7 @@ impl DefCollector<'_> {
|
||||||
MacroCallKind::Attr {
|
MacroCallKind::Attr {
|
||||||
ast_id: ast_id.ast_id,
|
ast_id: ast_id.ast_id,
|
||||||
attr_args: Default::default(),
|
attr_args: Default::default(),
|
||||||
invoc_attr_index: attr.id.ast_index,
|
invoc_attr_index: attr.id,
|
||||||
is_derive: false,
|
is_derive: false,
|
||||||
},
|
},
|
||||||
attr.path().clone(),
|
attr.path().clone(),
|
||||||
|
@ -1407,7 +1407,7 @@ impl DefCollector<'_> {
|
||||||
directive.module_id,
|
directive.module_id,
|
||||||
MacroCallKind::Derive {
|
MacroCallKind::Derive {
|
||||||
ast_id: ast_id.ast_id,
|
ast_id: ast_id.ast_id,
|
||||||
derive_attr_index: derive_attr.ast_index,
|
derive_attr_index: *derive_attr,
|
||||||
derive_index: *derive_pos as u32,
|
derive_index: *derive_pos as u32,
|
||||||
},
|
},
|
||||||
ast_id.path.clone(),
|
ast_id.path.clone(),
|
||||||
|
|
|
@ -31,9 +31,9 @@ pub enum DefDiagnosticKind {
|
||||||
|
|
||||||
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
|
||||||
|
|
||||||
InvalidDeriveTarget { ast: AstId<ast::Item>, id: u32 },
|
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
|
||||||
|
|
||||||
MalformedDerive { ast: AstId<ast::Adt>, id: u32 },
|
MalformedDerive { ast: AstId<ast::Adt>, id: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
@ -119,7 +119,7 @@ impl DefDiagnostic {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
in_module: container,
|
in_module: container,
|
||||||
kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id: id.ast_index },
|
kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id: id.ast_index() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ impl DefDiagnostic {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
in_module: container,
|
in_module: container,
|
||||||
kind: DefDiagnosticKind::MalformedDerive { ast, id: id.ast_index },
|
kind: DefDiagnosticKind::MalformedDerive { ast, id: id.ast_index() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
||||||
use std::{fmt, ops, sync::Arc};
|
use std::{fmt, ops, sync::Arc};
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
|
@ -65,14 +66,16 @@ impl RawAttrs {
|
||||||
(None, entries @ Some(_)) => Self { entries },
|
(None, entries @ Some(_)) => Self { entries },
|
||||||
(Some(entries), None) => Self { entries: Some(entries.clone()) },
|
(Some(entries), None) => Self { entries: Some(entries.clone()) },
|
||||||
(Some(a), Some(b)) => {
|
(Some(a), Some(b)) => {
|
||||||
let last_ast_index = a.last().map_or(0, |it| it.id.ast_index + 1);
|
let last_ast_index = a.last().map_or(0, |it| it.id.ast_index() + 1) as u32;
|
||||||
Self {
|
Self {
|
||||||
entries: Some(
|
entries: Some(
|
||||||
a.iter()
|
a.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(b.iter().map(|it| {
|
.chain(b.iter().map(|it| {
|
||||||
let mut it = it.clone();
|
let mut it = it.clone();
|
||||||
it.id.ast_index += last_ast_index;
|
it.id.id = it.id.ast_index() as u32 + last_ast_index
|
||||||
|
| (it.id.cfg_attr_index().unwrap_or(0) as u32)
|
||||||
|
<< AttrId::AST_INDEX_BITS;
|
||||||
it
|
it
|
||||||
}))
|
}))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -83,6 +86,7 @@ impl RawAttrs {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
|
/// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
|
||||||
|
// FIXME: This should return a different type
|
||||||
pub fn filter(self, db: &dyn AstDatabase, krate: CrateId) -> RawAttrs {
|
pub fn filter(self, db: &dyn AstDatabase, krate: CrateId) -> RawAttrs {
|
||||||
let has_cfg_attrs = self
|
let has_cfg_attrs = self
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -106,27 +110,22 @@ impl RawAttrs {
|
||||||
_ => return smallvec![attr.clone()],
|
_ => return smallvec![attr.clone()],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Input subtree is: `(cfg, $(attr),+)`
|
let (cfg, parts) = match parse_cfg_attr_input(subtree) {
|
||||||
// Split it up into a `cfg` subtree and the `attr` subtrees.
|
|
||||||
// FIXME: There should be a common API for this.
|
|
||||||
let mut parts = subtree.token_trees.split(|tt| {
|
|
||||||
matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })))
|
|
||||||
});
|
|
||||||
let cfg = match parts.next() {
|
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return smallvec![],
|
None => return smallvec![attr.clone()],
|
||||||
};
|
};
|
||||||
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() };
|
|
||||||
let cfg = CfgExpr::parse(&cfg);
|
|
||||||
let index = attr.id;
|
let index = attr.id;
|
||||||
let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| {
|
let attrs =
|
||||||
let tree = Subtree { delimiter: None, token_trees: attr.to_vec() };
|
parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(|(idx, attr)| {
|
||||||
// FIXME hygiene
|
let tree = Subtree { delimiter: None, token_trees: attr.to_vec() };
|
||||||
let hygiene = Hygiene::new_unhygienic();
|
// FIXME hygiene
|
||||||
Attr::from_tt(db, &tree, &hygiene, index)
|
let hygiene = Hygiene::new_unhygienic();
|
||||||
});
|
Attr::from_tt(db, &tree, &hygiene, index.with_cfg_attr(idx))
|
||||||
|
});
|
||||||
|
|
||||||
let cfg_options = &crate_graph[krate].cfg_options;
|
let cfg_options = &crate_graph[krate].cfg_options;
|
||||||
|
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() };
|
||||||
|
let cfg = CfgExpr::parse(&cfg);
|
||||||
if cfg_options.check(&cfg) == Some(false) {
|
if cfg_options.check(&cfg) == Some(false) {
|
||||||
smallvec![]
|
smallvec![]
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,7 +142,32 @@ impl RawAttrs {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct AttrId {
|
pub struct AttrId {
|
||||||
pub ast_index: u32,
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This only handles a single level of cfg_attr nesting
|
||||||
|
// that is `#[cfg_attr(all(), cfg_attr(all(), cfg(any())))]` breaks again
|
||||||
|
impl AttrId {
|
||||||
|
const CFG_ATTR_BITS: usize = 7;
|
||||||
|
const AST_INDEX_MASK: usize = 0x00FF_FFFF;
|
||||||
|
const AST_INDEX_BITS: usize = Self::AST_INDEX_MASK.count_ones() as usize;
|
||||||
|
const CFG_ATTR_SET_BITS: u32 = 1 << 31;
|
||||||
|
|
||||||
|
pub fn ast_index(&self) -> usize {
|
||||||
|
self.id as usize & Self::AST_INDEX_MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cfg_attr_index(&self) -> Option<usize> {
|
||||||
|
if self.id & Self::CFG_ATTR_SET_BITS == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.id as usize >> Self::AST_INDEX_BITS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_cfg_attr(self, idx: usize) -> AttrId {
|
||||||
|
AttrId { id: self.id | (idx as u32) << Self::AST_INDEX_BITS | Self::CFG_ATTR_SET_BITS }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -272,10 +296,7 @@ pub fn collect_attrs(
|
||||||
Either::Left(attr) => attr.kind().is_outer(),
|
Either::Left(attr) => attr.kind().is_outer(),
|
||||||
Either::Right(comment) => comment.is_outer(),
|
Either::Right(comment) => comment.is_outer(),
|
||||||
});
|
});
|
||||||
outer_attrs
|
outer_attrs.chain(inner_attrs).enumerate().map(|(id, attr)| (AttrId { id: id as u32 }, attr))
|
||||||
.chain(inner_attrs)
|
|
||||||
.enumerate()
|
|
||||||
.map(|(id, attr)| (AttrId { ast_index: id as u32 }, attr))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner_attributes(
|
fn inner_attributes(
|
||||||
|
@ -311,3 +332,15 @@ fn inner_attributes(
|
||||||
});
|
});
|
||||||
Some(attrs)
|
Some(attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input subtree is: `(cfg, $(attr),+)`
|
||||||
|
// Split it up into a `cfg` subtree and the `attr` subtrees.
|
||||||
|
pub fn parse_cfg_attr_input(
|
||||||
|
subtree: &Subtree,
|
||||||
|
) -> Option<(&[tt::TokenTree], impl Iterator<Item = &[tt::TokenTree]>)> {
|
||||||
|
let mut parts = subtree
|
||||||
|
.token_trees
|
||||||
|
.split(|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. }))));
|
||||||
|
let cfg = parts.next()?;
|
||||||
|
Some((cfg, parts.filter(|it| !it.is_empty())))
|
||||||
|
}
|
||||||
|
|
|
@ -168,7 +168,9 @@ pub fn expand_speculative(
|
||||||
// Attributes may have an input token tree, build the subtree and map for this as well
|
// Attributes may have an input token tree, build the subtree and map for this as well
|
||||||
// then try finding a token id for our token if it is inside this input subtree.
|
// then try finding a token id for our token if it is inside this input subtree.
|
||||||
let item = ast::Item::cast(speculative_args.clone())?;
|
let item = ast::Item::cast(speculative_args.clone())?;
|
||||||
item.doc_comments_and_attrs().nth(invoc_attr_index as usize).and_then(Either::left)
|
item.doc_comments_and_attrs()
|
||||||
|
.nth(invoc_attr_index.ast_index())
|
||||||
|
.and_then(Either::left)
|
||||||
}?;
|
}?;
|
||||||
match attr.token_tree() {
|
match attr.token_tree() {
|
||||||
Some(token_tree) => {
|
Some(token_tree) => {
|
||||||
|
@ -321,6 +323,7 @@ fn macro_arg(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<SyntaxNode> {
|
fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<SyntaxNode> {
|
||||||
|
// FIXME: handle `cfg_attr`
|
||||||
(|| {
|
(|| {
|
||||||
let censor = match loc.kind {
|
let censor = match loc.kind {
|
||||||
MacroCallKind::FnLike { .. } => return None,
|
MacroCallKind::FnLike { .. } => return None,
|
||||||
|
@ -328,7 +331,7 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<Sy
|
||||||
cov_mark::hit!(derive_censoring);
|
cov_mark::hit!(derive_censoring);
|
||||||
ast::Item::cast(node.clone())?
|
ast::Item::cast(node.clone())?
|
||||||
.attrs()
|
.attrs()
|
||||||
.take(derive_attr_index as usize + 1)
|
.take(derive_attr_index.ast_index() + 1)
|
||||||
// FIXME, this resolution should not be done syntactically
|
// FIXME, this resolution should not be done syntactically
|
||||||
// derive is a proper macro now, no longer builtin
|
// derive is a proper macro now, no longer builtin
|
||||||
// But we do not have resolution at this stage, this means
|
// But we do not have resolution at this stage, this means
|
||||||
|
@ -343,7 +346,7 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<Sy
|
||||||
cov_mark::hit!(attribute_macro_attr_censoring);
|
cov_mark::hit!(attribute_macro_attr_censoring);
|
||||||
ast::Item::cast(node.clone())?
|
ast::Item::cast(node.clone())?
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(Either::left)
|
.and_then(Either::left)
|
||||||
.map(|attr| attr.syntax().clone())
|
.map(|attr| attr.syntax().clone())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -191,7 +191,7 @@ fn make_hygiene_info(
|
||||||
let tt = ast_id
|
let tt = ast_id
|
||||||
.to_node(db)
|
.to_node(db)
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(Either::left)?
|
.and_then(Either::left)?
|
||||||
.token_tree()?;
|
.token_tree()?;
|
||||||
Some(InFile::new(ast_id.file_id, tt))
|
Some(InFile::new(ast_id.file_id, tt))
|
||||||
|
|
|
@ -38,6 +38,7 @@ use syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast_id_map::FileAstId,
|
ast_id_map::FileAstId,
|
||||||
|
attrs::AttrId,
|
||||||
builtin_attr_macro::BuiltinAttrExpander,
|
builtin_attr_macro::BuiltinAttrExpander,
|
||||||
builtin_derive_macro::BuiltinDeriveExpander,
|
builtin_derive_macro::BuiltinDeriveExpander,
|
||||||
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
||||||
|
@ -146,7 +147,7 @@ pub enum MacroCallKind {
|
||||||
///
|
///
|
||||||
/// Outer attributes are counted first, then inner attributes. This does not support
|
/// Outer attributes are counted first, then inner attributes. This does not support
|
||||||
/// out-of-line modules, which may have attributes spread across 2 files!
|
/// out-of-line modules, which may have attributes spread across 2 files!
|
||||||
derive_attr_index: u32,
|
derive_attr_index: AttrId,
|
||||||
/// Index of the derive macro in the derive attribute
|
/// Index of the derive macro in the derive attribute
|
||||||
derive_index: u32,
|
derive_index: u32,
|
||||||
},
|
},
|
||||||
|
@ -157,7 +158,7 @@ pub enum MacroCallKind {
|
||||||
///
|
///
|
||||||
/// Outer attributes are counted first, then inner attributes. This does not support
|
/// Outer attributes are counted first, then inner attributes. This does not support
|
||||||
/// out-of-line modules, which may have attributes spread across 2 files!
|
/// out-of-line modules, which may have attributes spread across 2 files!
|
||||||
invoc_attr_index: u32,
|
invoc_attr_index: AttrId,
|
||||||
/// Whether this attribute is the `#[derive]` attribute.
|
/// Whether this attribute is the `#[derive]` attribute.
|
||||||
is_derive: bool,
|
is_derive: bool,
|
||||||
},
|
},
|
||||||
|
@ -262,10 +263,11 @@ impl HirFileId {
|
||||||
});
|
});
|
||||||
let attr_input_or_mac_def = def.or_else(|| match loc.kind {
|
let attr_input_or_mac_def = def.or_else(|| match loc.kind {
|
||||||
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
|
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
|
||||||
|
// FIXME: handle `cfg_attr`
|
||||||
let tt = ast_id
|
let tt = ast_id
|
||||||
.to_node(db)
|
.to_node(db)
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(Either::left)?
|
.and_then(Either::left)?
|
||||||
.token_tree()?;
|
.token_tree()?;
|
||||||
Some(InFile::new(ast_id.file_id, tt))
|
Some(InFile::new(ast_id.file_id, tt))
|
||||||
|
@ -398,8 +400,7 @@ impl MacroDefId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: attribute indices do not account for `cfg_attr`, which means that we'll strip the whole
|
// FIXME: attribute indices do not account for nested `cfg_attr`
|
||||||
// `cfg_attr` instead of just one of the attributes it expands to
|
|
||||||
|
|
||||||
impl MacroCallKind {
|
impl MacroCallKind {
|
||||||
/// Returns the file containing the macro invocation.
|
/// Returns the file containing the macro invocation.
|
||||||
|
@ -420,7 +421,7 @@ impl MacroCallKind {
|
||||||
// FIXME: handle `cfg_attr`
|
// FIXME: handle `cfg_attr`
|
||||||
ast_id.with_value(ast_id.to_node(db)).map(|it| {
|
ast_id.with_value(ast_id.to_node(db)).map(|it| {
|
||||||
it.doc_comments_and_attrs()
|
it.doc_comments_and_attrs()
|
||||||
.nth(*derive_attr_index as usize)
|
.nth(derive_attr_index.ast_index())
|
||||||
.and_then(|it| match it {
|
.and_then(|it| match it {
|
||||||
Either::Left(attr) => Some(attr.syntax().clone()),
|
Either::Left(attr) => Some(attr.syntax().clone()),
|
||||||
Either::Right(_) => None,
|
Either::Right(_) => None,
|
||||||
|
@ -432,7 +433,7 @@ impl MacroCallKind {
|
||||||
// FIXME: handle `cfg_attr`
|
// FIXME: handle `cfg_attr`
|
||||||
ast_id.with_value(ast_id.to_node(db)).map(|it| {
|
ast_id.with_value(ast_id.to_node(db)).map(|it| {
|
||||||
it.doc_comments_and_attrs()
|
it.doc_comments_and_attrs()
|
||||||
.nth(*invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(|it| match it {
|
.and_then(|it| match it {
|
||||||
Either::Left(attr) => Some(attr.syntax().clone()),
|
Either::Left(attr) => Some(attr.syntax().clone()),
|
||||||
Either::Right(_) => None,
|
Either::Right(_) => None,
|
||||||
|
@ -489,19 +490,21 @@ impl MacroCallKind {
|
||||||
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
|
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
|
||||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
||||||
// FIXME: should be the range of the macro name, not the whole derive
|
// FIXME: should be the range of the macro name, not the whole derive
|
||||||
|
// FIXME: handle `cfg_attr`
|
||||||
ast_id
|
ast_id
|
||||||
.to_node(db)
|
.to_node(db)
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(derive_attr_index as usize)
|
.nth(derive_attr_index.ast_index())
|
||||||
.expect("missing derive")
|
.expect("missing derive")
|
||||||
.expect_left("derive is a doc comment?")
|
.expect_left("derive is a doc comment?")
|
||||||
.syntax()
|
.syntax()
|
||||||
.text_range()
|
.text_range()
|
||||||
}
|
}
|
||||||
|
// FIXME: handle `cfg_attr`
|
||||||
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => ast_id
|
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => ast_id
|
||||||
.to_node(db)
|
.to_node(db)
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.expect("missing attribute")
|
.expect("missing attribute")
|
||||||
.expect_left("attribute macro is a doc comment?")
|
.expect_left("attribute macro is a doc comment?")
|
||||||
.syntax()
|
.syntax()
|
||||||
|
@ -593,9 +596,10 @@ impl ExpansionInfo {
|
||||||
let token_range = token.value.text_range();
|
let token_range = token.value.text_range();
|
||||||
match &loc.kind {
|
match &loc.kind {
|
||||||
MacroCallKind::Attr { attr_args, invoc_attr_index, is_derive, .. } => {
|
MacroCallKind::Attr { attr_args, invoc_attr_index, is_derive, .. } => {
|
||||||
|
// FIXME: handle `cfg_attr`
|
||||||
let attr = item
|
let attr = item
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(*invoc_attr_index as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(Either::left)?;
|
.and_then(Either::left)?;
|
||||||
match attr.token_tree() {
|
match attr.token_tree() {
|
||||||
Some(token_tree)
|
Some(token_tree)
|
||||||
|
|
|
@ -785,7 +785,7 @@ fn precise_macro_call_location(
|
||||||
let token = (|| {
|
let token = (|| {
|
||||||
let derive_attr = node
|
let derive_attr = node
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth(*derive_attr_index as usize)
|
.nth(derive_attr_index.ast_index())
|
||||||
.and_then(Either::left)?;
|
.and_then(Either::left)?;
|
||||||
let token_tree = derive_attr.meta()?.token_tree()?;
|
let token_tree = derive_attr.meta()?.token_tree()?;
|
||||||
let group_by = token_tree
|
let group_by = token_tree
|
||||||
|
@ -813,9 +813,11 @@ fn precise_macro_call_location(
|
||||||
let node = ast_id.to_node(db.upcast());
|
let node = ast_id.to_node(db.upcast());
|
||||||
let attr = node
|
let attr = node
|
||||||
.doc_comments_and_attrs()
|
.doc_comments_and_attrs()
|
||||||
.nth((*invoc_attr_index) as usize)
|
.nth(invoc_attr_index.ast_index())
|
||||||
.and_then(Either::left)
|
.and_then(Either::left)
|
||||||
.unwrap_or_else(|| panic!("cannot find attribute #{invoc_attr_index}"));
|
.unwrap_or_else(|| {
|
||||||
|
panic!("cannot find attribute #{}", invoc_attr_index.ast_index())
|
||||||
|
});
|
||||||
|
|
||||||
(
|
(
|
||||||
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
|
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "intern"
|
name = "intern"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
description = "TBD"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
rust-version = "1.65"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
doctest = false
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# We need to freeze the version of the crate, as the raw-api feature is considered unstable
|
# We need to freeze the version of the crate, as the raw-api feature is considered unstable
|
||||||
|
|
Loading…
Reference in a new issue