Remove Delimiter::DUMMY_INVISIBLE

This commit is contained in:
Lukas Wirth 2023-12-20 14:00:14 +01:00
parent 2c6ce480e3
commit 7b804552a5
20 changed files with 170 additions and 106 deletions

View file

@ -206,6 +206,7 @@ impl Attr {
id: AttrId,
) -> Option<Attr> {
let path = Interned::new(ModPath::from_src(db, ast.path()?, span_map)?);
let span = span_map.span_for_range(ast.syntax().text_range());
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
let value = match lit.kind() {
ast::LiteralKind::String(string) => string.value()?.into(),
@ -213,12 +214,12 @@ impl Attr {
};
Some(Interned::new(AttrInput::Literal(value)))
} else if let Some(tt) = ast.token_tree() {
let tree = syntax_node_to_token_tree(tt.syntax(), span_map);
let tree = syntax_node_to_token_tree(tt.syntax(), span_map, span);
Some(Interned::new(AttrInput::TokenTree(Box::new(tree))))
} else {
None
};
Some(Attr { id, path, input, span: span_map.span_for_range(ast.syntax().text_range()) })
Some(Attr { id, path, input, span })
}
fn from_tt(db: &dyn ExpandDatabase, tt: &tt::Subtree, id: AttrId) -> Option<Attr> {

View file

@ -101,7 +101,12 @@ fn derive_attr_expand(
MacroCallKind::Attr { attr_args: Some(attr_args), .. } if loc.def.is_attribute_derive() => {
attr_args
}
_ => return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan::DUMMY)),
_ => {
return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan {
open: loc.call_site,
close: loc.call_site,
}))
}
};
pseudo_derive_attr_expansion(tt, derives, loc.call_site)
}

View file

@ -246,7 +246,7 @@ fn parse_adt(
match this {
Some(it) => {
param_type_set.insert(it.as_name());
mbe::syntax_node_to_token_tree(it.syntax(), tm)
mbe::syntax_node_to_token_tree(it.syntax(), tm, call_site)
}
None => {
tt::Subtree::empty(::tt::DelimSpan { open: call_site, close: call_site })
@ -254,15 +254,15 @@ fn parse_adt(
}
};
let bounds = match &param {
ast::TypeOrConstParam::Type(it) => {
it.type_bound_list().map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm))
}
ast::TypeOrConstParam::Type(it) => it
.type_bound_list()
.map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm, call_site)),
ast::TypeOrConstParam::Const(_) => None,
};
let ty = if let ast::TypeOrConstParam::Const(param) = param {
let ty = param
.ty()
.map(|ty| mbe::syntax_node_to_token_tree(ty.syntax(), tm))
.map(|ty| mbe::syntax_node_to_token_tree(ty.syntax(), tm, call_site))
.unwrap_or_else(|| {
tt::Subtree::empty(::tt::DelimSpan { open: call_site, close: call_site })
});
@ -298,7 +298,7 @@ fn parse_adt(
let name = p.path()?.qualifier()?.as_single_name_ref()?.as_name();
param_type_set.contains(&name).then_some(p)
})
.map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm))
.map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm, call_site))
.collect();
let name_token = name_to_token(tm, name)?;
Ok(BasicAdtInfo { name: name_token, shape, param_types, associated_types })

View file

@ -201,7 +201,7 @@ fn assert_expand(
tt: &tt::Subtree,
span: Span,
) -> ExpandResult<tt::Subtree> {
let args = parse_exprs_with_sep(tt, ',');
let args = parse_exprs_with_sep(tt, ',', span);
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
let expanded = match &*args {
[cond, panic_args @ ..] => {

View file

@ -72,7 +72,7 @@ impl DeclarativeMacroExpander {
});
match self.mac.err() {
Some(e) => ExpandResult::new(
tt::Subtree::empty(tt::DelimSpan::DUMMY),
tt::Subtree::empty(tt::DelimSpan { open: loc.call_site, close: loc.call_site }),
ExpandError::other(format!("invalid macro definition: {e}")),
),
None => self
@ -108,7 +108,7 @@ impl DeclarativeMacroExpander {
});
match self.mac.err() {
Some(e) => ExpandResult::new(
tt::Subtree::empty(tt::DelimSpan::DUMMY),
tt::Subtree::empty(tt::DelimSpan { open: call_site, close: call_site }),
ExpandError::other(format!("invalid macro definition: {e}")),
),
None => self.mac.expand(&tt, |_| (), new_meta_vars, call_site).map_err(Into::into),
@ -244,12 +244,13 @@ pub fn expand_speculative(
// Build the subtree and token mapping for the speculative args
let (mut tt, undo_info) = match loc.kind {
MacroCallKind::FnLike { .. } => {
(mbe::syntax_node_to_token_tree(speculative_args, span_map), SyntaxFixupUndoInfo::NONE)
}
MacroCallKind::FnLike { .. } => (
mbe::syntax_node_to_token_tree(speculative_args, span_map, loc.call_site),
SyntaxFixupUndoInfo::NONE,
),
MacroCallKind::Derive { .. } | MacroCallKind::Attr { .. } => {
let censor = censor_for_macro_input(&loc, speculative_args);
let mut fixups = fixup::fixup_syntax(span_map, speculative_args);
let mut fixups = fixup::fixup_syntax(span_map, speculative_args, loc.call_site);
fixups.append.retain(|it, _| match it {
syntax::NodeOrToken::Node(it) => !censor.contains(it),
syntax::NodeOrToken::Token(_) => true,
@ -261,6 +262,7 @@ pub fn expand_speculative(
span_map,
fixups.append,
fixups.remove,
loc.call_site,
),
fixups.undo_info,
)
@ -282,8 +284,9 @@ pub fn expand_speculative(
}?;
match attr.token_tree() {
Some(token_tree) => {
let mut tree = syntax_node_to_token_tree(token_tree.syntax(), span_map);
tree.delimiter = tt::Delimiter::DUMMY_INVISIBLE;
let mut tree =
syntax_node_to_token_tree(token_tree.syntax(), span_map, loc.call_site);
tree.delimiter = tt::Delimiter::invisible_spanned(loc.call_site);
Some(tree)
}
@ -297,7 +300,7 @@ pub fn expand_speculative(
// Otherwise the expand query will fetch the non speculative attribute args and pass those instead.
let mut speculative_expansion = match loc.def.kind {
MacroDefKind::ProcMacro(expander, ..) => {
tt.delimiter = tt::Delimiter::DUMMY_INVISIBLE;
tt.delimiter = tt::Delimiter::invisible_spanned(loc.call_site);
let call_site = loc.span(db);
expander.expand(
db,
@ -473,12 +476,13 @@ fn macro_arg(
MacroCallKind::Attr { ast_id, .. } => ast_id.to_ptr(db).to_node(&root).syntax().clone(),
};
let (mut tt, undo_info) = match loc.kind {
MacroCallKind::FnLike { .. } => {
(mbe::syntax_node_to_token_tree(&syntax, map.as_ref()), SyntaxFixupUndoInfo::NONE)
}
MacroCallKind::FnLike { .. } => (
mbe::syntax_node_to_token_tree(&syntax, map.as_ref(), loc.call_site),
SyntaxFixupUndoInfo::NONE,
),
MacroCallKind::Derive { .. } | MacroCallKind::Attr { .. } => {
let censor = censor_for_macro_input(&loc, &syntax);
let mut fixups = fixup::fixup_syntax(map.as_ref(), &syntax);
let mut fixups = fixup::fixup_syntax(map.as_ref(), &syntax, loc.call_site);
fixups.append.retain(|it, _| match it {
syntax::NodeOrToken::Node(it) => !censor.contains(it),
syntax::NodeOrToken::Token(_) => true,
@ -490,6 +494,7 @@ fn macro_arg(
map.as_ref(),
fixups.append.clone(),
fixups.remove.clone(),
loc.call_site,
);
reverse_fixups(&mut tt, &fixups.undo_info);
}
@ -499,6 +504,7 @@ fn macro_arg(
map,
fixups.append,
fixups.remove,
loc.call_site,
),
fixups.undo_info,
)
@ -507,7 +513,7 @@ fn macro_arg(
if loc.def.is_proc_macro() {
// proc macros expect their inputs without parentheses, MBEs expect it with them included
tt.delimiter = tt::Delimiter::DUMMY_INVISIBLE;
tt.delimiter.kind = tt::DelimiterKind::Invisible;
}
if matches!(loc.def.kind, MacroDefKind::BuiltInEager(..)) {
@ -611,7 +617,11 @@ fn decl_macro_expander(
ast::Macro::MacroRules(macro_rules) => (
match macro_rules.token_tree() {
Some(arg) => {
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
let tt = mbe::syntax_node_to_token_tree(
arg.syntax(),
map.as_ref(),
map.span_for_range(macro_rules.macro_rules_token().unwrap().text_range()),
);
let mac = mbe::DeclarativeMacro::parse_macro_rules(&tt, is_2021, new_meta_vars);
mac
}
@ -625,7 +635,11 @@ fn decl_macro_expander(
ast::Macro::MacroDef(macro_def) => (
match macro_def.body() {
Some(arg) => {
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
let tt = mbe::syntax_node_to_token_tree(
arg.syntax(),
map.as_ref(),
map.span_for_range(macro_def.macro_token().unwrap().text_range()),
);
let mac = mbe::DeclarativeMacro::parse_macro2(&tt, is_2021, new_meta_vars);
mac
}
@ -677,7 +691,7 @@ fn macro_expand(
let Some((macro_arg, undo_info)) = value else {
return ExpandResult {
value: Arc::new(tt::Subtree {
delimiter: tt::Delimiter::DUMMY_INVISIBLE,
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
token_trees: Vec::new(),
}),
// FIXME: We should make sure to enforce an invariant that invalid macro
@ -736,7 +750,7 @@ fn macro_expand(
// Skip checking token tree limit for include! macro call
if !loc.def.is_include() {
// Set a hard limit for the expanded tt
if let Err(value) = check_tt_count(&tt) {
if let Err(value) = check_tt_count(&tt, loc.call_site) {
return value;
}
}
@ -749,7 +763,7 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
let Some((macro_arg, undo_info)) = db.macro_arg(id).value else {
return ExpandResult {
value: Arc::new(tt::Subtree {
delimiter: tt::Delimiter::DUMMY_INVISIBLE,
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
token_trees: Vec::new(),
}),
// FIXME: We should make sure to enforce an invariant that invalid macro
@ -783,7 +797,7 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
);
// Set a hard limit for the expanded tt
if let Err(value) = check_tt_count(&tt) {
if let Err(value) = check_tt_count(&tt, loc.call_site) {
return value;
}
@ -806,12 +820,12 @@ fn token_tree_to_syntax_node(
mbe::token_tree_to_syntax_node(tt, entry_point)
}
fn check_tt_count(tt: &tt::Subtree) -> Result<(), ExpandResult<Arc<tt::Subtree>>> {
fn check_tt_count(tt: &tt::Subtree, call_site: Span) -> Result<(), ExpandResult<Arc<tt::Subtree>>> {
let count = tt.count();
if TOKEN_LIMIT.check(count).is_err() {
Err(ExpandResult {
value: Arc::new(tt::Subtree {
delimiter: tt::Delimiter::DUMMY_INVISIBLE,
delimiter: tt::Delimiter::invisible_spanned(call_site),
token_trees: vec![],
}),
err: Some(ExpandError::other(format!(

View file

@ -82,9 +82,9 @@ pub fn expand_eager_macro_input(
return ExpandResult { value: None, err };
};
let mut subtree = mbe::syntax_node_to_token_tree(&expanded_eager_input, arg_map);
let mut subtree = mbe::syntax_node_to_token_tree(&expanded_eager_input, arg_map, call_site);
subtree.delimiter = crate::tt::Delimiter::DUMMY_INVISIBLE;
subtree.delimiter.kind = crate::tt::DelimiterKind::Invisible;
let loc = MacroCallLoc {
def,

View file

@ -4,7 +4,7 @@
use la_arena::RawIdx;
use rustc_hash::{FxHashMap, FxHashSet};
use smallvec::SmallVec;
use span::{ErasedFileAstId, FileId, SpanAnchor, SpanData};
use span::{ErasedFileAstId, FileId, Span, SpanAnchor, SpanData};
use stdx::never;
use syntax::{
ast::{self, AstNode, HasLoopBody},
@ -48,7 +48,11 @@ const FIXUP_DUMMY_AST_ID: ErasedFileAstId = ErasedFileAstId::from_raw(RawIdx::fr
const FIXUP_DUMMY_RANGE: TextRange = TextRange::empty(TextSize::new(0));
const FIXUP_DUMMY_RANGE_END: TextSize = TextSize::new(!0);
pub(crate) fn fixup_syntax(span_map: SpanMapRef<'_>, node: &SyntaxNode) -> SyntaxFixups {
pub(crate) fn fixup_syntax(
span_map: SpanMapRef<'_>,
node: &SyntaxNode,
call_site: Span,
) -> SyntaxFixups {
let mut append = FxHashMap::<SyntaxElement, _>::default();
let mut remove = FxHashSet::<SyntaxNode>::default();
let mut preorder = node.preorder();
@ -69,7 +73,7 @@ pub(crate) fn fixup_syntax(span_map: SpanMapRef<'_>, node: &SyntaxNode) -> Synta
if can_handle_error(&node) && has_error_to_handle(&node) {
remove.insert(node.clone().into());
// the node contains an error node, we have to completely replace it by something valid
let original_tree = mbe::syntax_node_to_token_tree(&node, span_map);
let original_tree = mbe::syntax_node_to_token_tree(&node, span_map, call_site);
let idx = original.len() as u32;
original.push(original_tree);
let replacement = Leaf::Ident(Ident {
@ -358,6 +362,7 @@ fn reverse_fixups_(tt: &mut Subtree, undo_info: &[Subtree]) {
mod tests {
use base_db::FileId;
use expect_test::{expect, Expect};
use syntax::TextRange;
use triomphe::Arc;
use crate::{
@ -395,12 +400,17 @@ mod tests {
fn check(ra_fixture: &str, mut expect: Expect) {
let parsed = syntax::SourceFile::parse(ra_fixture);
let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
let fixups = super::fixup_syntax(span_map.as_ref(), &parsed.syntax_node());
let fixups = super::fixup_syntax(
span_map.as_ref(),
&parsed.syntax_node(),
span_map.span_for_range(TextRange::empty(0.into())),
);
let mut tt = mbe::syntax_node_to_token_tree_modified(
&parsed.syntax_node(),
span_map.as_ref(),
fixups.append,
fixups.remove,
span_map.span_for_range(TextRange::empty(0.into())),
);
let actual = format!("{tt}\n");
@ -420,8 +430,11 @@ mod tests {
// the fixed-up + reversed version should be equivalent to the original input
// modulo token IDs and `Punct`s' spacing.
let original_as_tt =
mbe::syntax_node_to_token_tree(&parsed.syntax_node(), span_map.as_ref());
let original_as_tt = mbe::syntax_node_to_token_tree(
&parsed.syntax_node(),
span_map.as_ref(),
span_map.span_for_range(TextRange::empty(0.into())),
);
assert!(
check_subtree_eq(&tt, &original_as_tt),
"different token tree:\n{tt:?}\n\n{original_as_tt:?}"

View file

@ -719,7 +719,7 @@ impl ExpansionInfo {
let (macro_arg, _) = db.macro_arg(macro_file.macro_call_id).value.unwrap_or_else(|| {
(
Arc::new(tt::Subtree {
delimiter: tt::Delimiter::DUMMY_INVISIBLE,
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
token_trees: Vec::new(),
}),
SyntaxFixupUndoInfo::NONE,