Remove MappedSubtree

This commit is contained in:
Lukas Wirth 2021-08-21 18:19:18 +02:00
parent 177c70128c
commit 5fb8c0ddfd
7 changed files with 21 additions and 41 deletions

View file

@ -14,7 +14,7 @@ use either::Either;
use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile};
use itertools::Itertools; use itertools::Itertools;
use la_arena::ArenaMap; use la_arena::ArenaMap;
use mbe::{syntax_node_to_token_tree, DelimiterKind, MappedSubTree}; use mbe::{syntax_node_to_token_tree, DelimiterKind};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use syntax::{ use syntax::{
ast::{self, AstNode, AttrsOwner}, ast::{self, AstNode, AttrsOwner},
@ -160,18 +160,18 @@ impl RawAttrs {
} }
let subtree = match attr.input.as_deref() { let subtree = match attr.input.as_deref() {
Some(AttrInput::TokenTree(it)) => it, Some(AttrInput::TokenTree(it, _)) => it,
_ => return smallvec![attr.clone()], _ => return smallvec![attr.clone()],
}; };
// Input subtree is: `(cfg, $(attr),+)` // Input subtree is: `(cfg, $(attr),+)`
// Split it up into a `cfg` subtree and the `attr` subtrees. // Split it up into a `cfg` subtree and the `attr` subtrees.
// FIXME: There should be a common API for this. // FIXME: There should be a common API for this.
let mut parts = subtree.tree.token_trees.split( let mut parts = subtree.token_trees.split(
|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','), |tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','),
); );
let cfg = parts.next().unwrap(); let cfg = parts.next().unwrap();
let cfg = Subtree { delimiter: subtree.tree.delimiter, token_trees: cfg.to_vec() }; let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() };
let cfg = CfgExpr::parse(&cfg); 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 = parts.filter(|a| !a.is_empty()).filter_map(|attr| {
@ -260,7 +260,7 @@ impl Attrs {
pub fn docs(&self) -> Option<Documentation> { pub fn docs(&self) -> Option<Documentation> {
let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? { let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? {
AttrInput::Literal(s) => Some(s), AttrInput::Literal(s) => Some(s),
AttrInput::TokenTree(_) => None, AttrInput::TokenTree(..) => None,
}); });
let indent = docs let indent = docs
.clone() .clone()
@ -465,7 +465,7 @@ impl AttrsWithOwner {
// FIXME: code duplication in `docs` above // FIXME: code duplication in `docs` above
let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? { let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? {
AttrInput::Literal(s) => Some((s, attr.id)), AttrInput::Literal(s) => Some((s, attr.id)),
AttrInput::TokenTree(_) => None, AttrInput::TokenTree(..) => None,
}); });
let indent = docs let indent = docs
.clone() .clone()
@ -654,14 +654,14 @@ pub enum AttrInput {
/// `#[attr = "string"]` /// `#[attr = "string"]`
Literal(SmolStr), Literal(SmolStr),
/// `#[attr(subtree)]` /// `#[attr(subtree)]`
TokenTree(mbe::MappedSubTree), TokenTree(tt::Subtree, mbe::TokenMap),
} }
impl fmt::Display for AttrInput { impl fmt::Display for AttrInput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
AttrInput::Literal(lit) => write!(f, " = \"{}\"", lit.escape_debug()), AttrInput::Literal(lit) => write!(f, " = \"{}\"", lit.escape_debug()),
AttrInput::TokenTree(subtree) => subtree.tree.fmt(f), AttrInput::TokenTree(subtree, _) => subtree.fmt(f),
} }
} }
} }
@ -682,7 +682,7 @@ impl Attr {
Some(Interned::new(AttrInput::Literal(value))) Some(Interned::new(AttrInput::Literal(value)))
} else if let Some(tt) = ast.token_tree() { } else if let Some(tt) = ast.token_tree() {
let (tree, map) = syntax_node_to_token_tree(tt.syntax()); let (tree, map) = syntax_node_to_token_tree(tt.syntax());
Some(Interned::new(AttrInput::TokenTree(MappedSubTree { tree, map }))) Some(Interned::new(AttrInput::TokenTree(tree, map)))
} else { } else {
None None
}; };
@ -712,10 +712,9 @@ impl Attr {
} }
match self.input.as_deref() { match self.input.as_deref() {
Some(AttrInput::TokenTree(args)) => { Some(AttrInput::TokenTree(args, _)) => {
let mut counter = 0; let mut counter = 0;
let paths = args let paths = args
.tree
.token_trees .token_trees
.iter() .iter()
.group_by(move |tt| { .group_by(move |tt| {
@ -760,7 +759,7 @@ pub struct AttrQuery<'a> {
impl<'a> AttrQuery<'a> { impl<'a> AttrQuery<'a> {
pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> { pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> {
self.attrs().filter_map(|attr| match attr.input.as_deref()? { self.attrs().filter_map(|attr| match attr.input.as_deref()? {
AttrInput::TokenTree(it) => Some(&it.tree), AttrInput::TokenTree(it, _) => Some(it),
_ => None, _ => None,
}) })
} }

View file

@ -787,12 +787,12 @@ fn attr_macro_as_call_id(
let mut arg = match &macro_attr.input { let mut arg = match &macro_attr.input {
Some(input) => match &**input { Some(input) => match &**input {
attr::AttrInput::Literal(_) => Default::default(), attr::AttrInput::Literal(_) => Default::default(),
attr::AttrInput::TokenTree(tt) => tt.clone(), attr::AttrInput::TokenTree(tt, map) => (tt.clone(), map.clone()),
}, },
None => Default::default(), None => Default::default(),
}; };
// The parentheses are always disposed here. // The parentheses are always disposed here.
arg.tree.delimiter = None; arg.0.delimiter = None;
let res = def.as_lazy_macro( let res = def.as_lazy_macro(
db.upcast(), db.upcast(),

View file

@ -289,7 +289,7 @@ impl DefCollector<'_> {
|| *attr_name == hir_expand::name![register_tool] || *attr_name == hir_expand::name![register_tool]
{ {
match attr.input.as_deref() { match attr.input.as_deref() {
Some(AttrInput::TokenTree(subtree)) => match &*subtree.tree.token_trees { Some(AttrInput::TokenTree(subtree, _)) => match &*subtree.token_trees {
[tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(), [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(),
_ => continue, _ => continue,
}, },

View file

@ -387,7 +387,7 @@ fn expand_proc_macro(db: &dyn AstDatabase, id: MacroCallId) -> ExpandResult<tt::
let attr_arg = match &loc.kind { let attr_arg = match &loc.kind {
MacroCallKind::Attr { attr_args, .. } => { MacroCallKind::Attr { attr_args, .. } => {
let mut attr_args = attr_args.tree.clone(); let mut attr_args = attr_args.0.clone();
mbe::Shift::new(&macro_arg.0).shift_all(&mut attr_args); mbe::Shift::new(&macro_arg.0).shift_all(&mut attr_args);
Some(attr_args) Some(attr_args)
} }

View file

@ -283,7 +283,7 @@ pub enum MacroCallKind {
Attr { Attr {
ast_id: AstId<ast::Item>, ast_id: AstId<ast::Item>,
attr_name: String, attr_name: String,
attr_args: mbe::MappedSubTree, attr_args: (tt::Subtree, mbe::TokenMap),
/// Syntactical index of the invoking `#[attribute]`. /// Syntactical index of the invoking `#[attribute]`.
/// ///
/// Outer attributes are counted first, then inner attributes. This does not support /// Outer attributes are counted first, then inner attributes. This does not support
@ -390,7 +390,7 @@ impl ExpansionInfo {
token_tree.left_delimiter_token()?.text_range().start(); token_tree.left_delimiter_token()?.text_range().start();
let range = token.value.text_range().checked_sub(attr_input_start)?; let range = token.value.text_range().checked_sub(attr_input_start)?;
let token_id = let token_id =
self.macro_arg_shift.shift(attr_args.map.token_by_range(range)?); self.macro_arg_shift.shift(attr_args.1.token_by_range(range)?);
Some(token_id) Some(token_id)
} }
_ => None, _ => None,
@ -437,7 +437,7 @@ impl ExpansionInfo {
MacroCallKind::Attr { attr_args, .. } => match self.macro_arg_shift.unshift(token_id) { MacroCallKind::Attr { attr_args, .. } => match self.macro_arg_shift.unshift(token_id) {
Some(unshifted) => { Some(unshifted) => {
token_id = unshifted; token_id = unshifted;
(&attr_args.map, self.attr_input_or_mac_def.clone()?.syntax().cloned()) (&attr_args.1, self.attr_input_or_mac_def.clone()?.syntax().cloned())
} }
None => (&self.macro_arg.1, self.arg.clone()), None => (&self.macro_arg.1, self.arg.clone()),
}, },

View file

@ -69,7 +69,7 @@ pub use crate::{
parse_exprs_with_sep, parse_to_token_tree, syntax_node_to_token_tree, parse_exprs_with_sep, parse_to_token_tree, syntax_node_to_token_tree,
token_tree_to_syntax_node, token_tree_to_syntax_node,
}, },
token_map::{MappedSubTree, TokenMap}, token_map::TokenMap,
}; };
/// This struct contains AST for a single `macro_rules` definition. What might /// This struct contains AST for a single `macro_rules` definition. What might

View file

@ -5,7 +5,7 @@ use std::hash::Hash;
use parser::{SyntaxKind, T}; use parser::{SyntaxKind, T};
use syntax::{TextRange, TextSize}; use syntax::{TextRange, TextSize};
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
enum TokenTextRange { enum TokenTextRange {
Token(TextRange), Token(TextRange),
Delimiter(TextRange), Delimiter(TextRange),
@ -26,27 +26,8 @@ impl TokenTextRange {
} }
} }
#[derive(Debug, Clone, Default)]
pub struct MappedSubTree {
pub tree: tt::Subtree,
pub map: TokenMap,
}
impl Eq for MappedSubTree {}
impl PartialEq for MappedSubTree {
fn eq(&self, other: &Self) -> bool {
self.tree == other.tree && self.map == other.map
}
}
impl Hash for MappedSubTree {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.tree.hash(state);
}
}
/// Maps `tt::TokenId` to the relative range of the original token. /// Maps `tt::TokenId` to the relative range of the original token.
#[derive(Debug, PartialEq, Eq, Clone, Default)] #[derive(Debug, PartialEq, Eq, Clone, Default, Hash)]
pub struct TokenMap { pub struct TokenMap {
/// Maps `tt::TokenId` to the *relative* source range. /// Maps `tt::TokenId` to the *relative* source range.
entries: Vec<(tt::TokenId, TokenTextRange)>, entries: Vec<(tt::TokenId, TokenTextRange)>,