mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Make syntax bridge fully infallible
This commit is contained in:
parent
17afa2e778
commit
5088926ec3
5 changed files with 18 additions and 31 deletions
|
@ -735,7 +735,7 @@ impl Attr {
|
||||||
hygiene: &Hygiene,
|
hygiene: &Hygiene,
|
||||||
id: AttrId,
|
id: AttrId,
|
||||||
) -> Option<Attr> {
|
) -> Option<Attr> {
|
||||||
let (parse, _) = mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MetaItem).ok()?;
|
let (parse, _) = mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MetaItem);
|
||||||
let ast = ast::Meta::cast(parse.syntax_node())?;
|
let ast = ast::Meta::cast(parse.syntax_node())?;
|
||||||
|
|
||||||
Self::from_src(db, ast, hygiene, id)
|
Self::from_src(db, ast, hygiene, id)
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct BasicAdtInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, mbe::ExpandError> {
|
fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, mbe::ExpandError> {
|
||||||
let (parsed, token_map) = mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MacroItems)?; // FragmentKind::Items doesn't parse attrs?
|
let (parsed, token_map) = mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MacroItems); // FragmentKind::Items doesn't parse attrs?
|
||||||
let macro_items = ast::MacroItems::cast(parsed.syntax_node()).ok_or_else(|| {
|
let macro_items = ast::MacroItems::cast(parsed.syntax_node()).ok_or_else(|| {
|
||||||
debug!("derive node didn't parse");
|
debug!("derive node didn't parse");
|
||||||
mbe::ExpandError::UnexpectedToken
|
mbe::ExpandError::UnexpectedToken
|
||||||
|
|
|
@ -202,8 +202,7 @@ pub fn expand_speculative(
|
||||||
};
|
};
|
||||||
|
|
||||||
let expand_to = macro_expand_to(db, actual_macro_call);
|
let expand_to = macro_expand_to(db, actual_macro_call);
|
||||||
let (node, rev_tmap) =
|
let (node, rev_tmap) = token_tree_to_syntax_node(&speculative_expansion.value, expand_to);
|
||||||
token_tree_to_syntax_node(&speculative_expansion.value, expand_to).ok()?;
|
|
||||||
|
|
||||||
let range = rev_tmap.first_range_by_token(token_id, token_to_map.kind())?;
|
let range = rev_tmap.first_range_by_token(token_id, token_to_map.kind())?;
|
||||||
let token = node.syntax_node().covering_element(range).into_token()?;
|
let token = node.syntax_node().covering_element(range).into_token()?;
|
||||||
|
@ -264,17 +263,7 @@ fn parse_macro_expansion(
|
||||||
tracing::debug!("expanded = {}", tt.as_debug_string());
|
tracing::debug!("expanded = {}", tt.as_debug_string());
|
||||||
tracing::debug!("kind = {:?}", expand_to);
|
tracing::debug!("kind = {:?}", expand_to);
|
||||||
|
|
||||||
let (parse, rev_token_map) = match token_tree_to_syntax_node(&tt, expand_to) {
|
let (parse, rev_token_map) = token_tree_to_syntax_node(&tt, expand_to);
|
||||||
Ok(it) => it,
|
|
||||||
Err(err) => {
|
|
||||||
tracing::debug!(
|
|
||||||
"failed to parse expansion to {:?} = {}",
|
|
||||||
expand_to,
|
|
||||||
tt.as_debug_string()
|
|
||||||
);
|
|
||||||
return ExpandResult::only_err(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match result.err {
|
match result.err {
|
||||||
Some(err) => {
|
Some(err) => {
|
||||||
|
@ -502,7 +491,7 @@ fn macro_expand_to(db: &dyn AstDatabase, id: MacroCallId) -> ExpandTo {
|
||||||
fn token_tree_to_syntax_node(
|
fn token_tree_to_syntax_node(
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
expand_to: ExpandTo,
|
expand_to: ExpandTo,
|
||||||
) -> Result<(Parse<SyntaxNode>, mbe::TokenMap), ExpandError> {
|
) -> (Parse<SyntaxNode>, mbe::TokenMap) {
|
||||||
let entry_point = match expand_to {
|
let entry_point = match expand_to {
|
||||||
ExpandTo::Statements => mbe::TopEntryPoint::MacroStmts,
|
ExpandTo::Statements => mbe::TopEntryPoint::MacroStmts,
|
||||||
ExpandTo::Items => mbe::TopEntryPoint::MacroItems,
|
ExpandTo::Items => mbe::TopEntryPoint::MacroItems,
|
||||||
|
|
|
@ -104,12 +104,13 @@ pub fn expand_eager_macro(
|
||||||
macro_call: InFile<ast::MacroCall>,
|
macro_call: InFile<ast::MacroCall>,
|
||||||
def: MacroDefId,
|
def: MacroDefId,
|
||||||
resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
|
resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
|
||||||
mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
|
diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
|
||||||
) -> Result<MacroCallId, ErrorEmitted> {
|
) -> Result<MacroCallId, ErrorEmitted> {
|
||||||
let parsed_args = diagnostic_sink.option_with(
|
let parsed_args = macro_call
|
||||||
|| Some(mbe::syntax_node_to_token_tree(macro_call.value.token_tree()?.syntax()).0),
|
.value
|
||||||
|| err("malformed macro invocation"),
|
.token_tree()
|
||||||
)?;
|
.map(|tt| mbe::syntax_node_to_token_tree(tt.syntax()).0)
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
let ast_map = db.ast_id_map(macro_call.file_id);
|
let ast_map = db.ast_id_map(macro_call.file_id);
|
||||||
let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value));
|
let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value));
|
||||||
|
@ -130,9 +131,7 @@ pub fn expand_eager_macro(
|
||||||
});
|
});
|
||||||
let arg_file_id = arg_id;
|
let arg_file_id = arg_id;
|
||||||
|
|
||||||
let parsed_args = diagnostic_sink
|
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, mbe::TopEntryPoint::Expr).0;
|
||||||
.result(mbe::token_tree_to_syntax_node(&parsed_args, mbe::TopEntryPoint::Expr))?
|
|
||||||
.0;
|
|
||||||
let result = eager_macro_recur(
|
let result = eager_macro_recur(
|
||||||
db,
|
db,
|
||||||
InFile::new(arg_file_id.as_file(), parsed_args.syntax_node()),
|
InFile::new(arg_file_id.as_file(), parsed_args.syntax_node()),
|
||||||
|
@ -140,8 +139,7 @@ pub fn expand_eager_macro(
|
||||||
resolver,
|
resolver,
|
||||||
diagnostic_sink,
|
diagnostic_sink,
|
||||||
)?;
|
)?;
|
||||||
let subtree =
|
let subtree = to_subtree(&result);
|
||||||
diagnostic_sink.option(to_subtree(&result), || err("failed to parse macro result"))?;
|
|
||||||
|
|
||||||
if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
|
if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
|
||||||
let res = eager.expand(db, arg_id, &subtree);
|
let res = eager.expand(db, arg_id, &subtree);
|
||||||
|
@ -165,10 +163,10 @@ pub fn expand_eager_macro(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_subtree(node: &SyntaxNode) -> Option<tt::Subtree> {
|
fn to_subtree(node: &SyntaxNode) -> tt::Subtree {
|
||||||
let mut subtree = mbe::syntax_node_to_token_tree(node).0;
|
let mut subtree = mbe::syntax_node_to_token_tree(node).0;
|
||||||
subtree.delimiter = None;
|
subtree.delimiter = None;
|
||||||
Some(subtree)
|
subtree
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lazy_expand(
|
fn lazy_expand(
|
||||||
|
|
|
@ -10,7 +10,7 @@ use syntax::{
|
||||||
};
|
};
|
||||||
use tt::buffer::{Cursor, TokenBuffer};
|
use tt::buffer::{Cursor, TokenBuffer};
|
||||||
|
|
||||||
use crate::{to_parser_input::to_parser_input, tt_iter::TtIter, ExpandError, TokenMap};
|
use crate::{to_parser_input::to_parser_input, tt_iter::TtIter, TokenMap};
|
||||||
|
|
||||||
/// Convert the syntax node to a `TokenTree` (what macro
|
/// Convert the syntax node to a `TokenTree` (what macro
|
||||||
/// will consume).
|
/// will consume).
|
||||||
|
@ -46,7 +46,7 @@ pub fn syntax_node_to_token_tree_censored(
|
||||||
pub fn token_tree_to_syntax_node(
|
pub fn token_tree_to_syntax_node(
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
entry_point: parser::TopEntryPoint,
|
entry_point: parser::TopEntryPoint,
|
||||||
) -> Result<(Parse<SyntaxNode>, TokenMap), ExpandError> {
|
) -> (Parse<SyntaxNode>, TokenMap) {
|
||||||
let buffer = match tt {
|
let buffer = match tt {
|
||||||
tt::Subtree { delimiter: None, token_trees } => {
|
tt::Subtree { delimiter: None, token_trees } => {
|
||||||
TokenBuffer::from_tokens(token_trees.as_slice())
|
TokenBuffer::from_tokens(token_trees.as_slice())
|
||||||
|
@ -67,7 +67,7 @@ pub fn token_tree_to_syntax_node(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let (parse, range_map) = tree_sink.finish();
|
let (parse, range_map) = tree_sink.finish();
|
||||||
Ok((parse, range_map))
|
(parse, range_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a string to a `TokenTree`
|
/// Convert a string to a `TokenTree`
|
||||||
|
|
Loading…
Reference in a new issue