mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
check top level entry point invariants
This commit is contained in:
parent
fa049d94d1
commit
d846afdeef
5 changed files with 42 additions and 12 deletions
|
@ -105,21 +105,21 @@ macro_rules! m2 { ($x:ident) => {} }
|
|||
|
||||
#[test]
|
||||
fn expansion_does_not_parse_as_expression() {
|
||||
cov_mark::check!(expansion_does_not_parse_as_expression);
|
||||
check(
|
||||
r#"
|
||||
macro_rules! stmts {
|
||||
() => { let _ = 0; }
|
||||
}
|
||||
|
||||
fn f() { let _ = stmts!(); }
|
||||
fn f() { let _ = stmts!/*+errors*/(); }
|
||||
"#,
|
||||
expect![[r#"
|
||||
macro_rules! stmts {
|
||||
() => { let _ = 0; }
|
||||
}
|
||||
|
||||
fn f() { let _ = /* error: could not convert tokens */; }
|
||||
fn f() { let _ = /* parse error: expected expression */
|
||||
let _ = 0;; }
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1148,7 +1148,7 @@ fn foo() { let a = id!([0u32, bar($0)] ); }
|
|||
fn test_hover_through_literal_string_in_macro() {
|
||||
check(
|
||||
r#"
|
||||
macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } }
|
||||
macro_rules! arr { ($($tt:tt)*) => { [$($tt)*] } }
|
||||
fn foo() {
|
||||
let mastered_for_itunes = "";
|
||||
let _ = arr!("Tr$0acks", &mastered_for_itunes);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Conversions between [`SyntaxNode`] and [`tt::TokenTree`].
|
||||
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use stdx::non_empty_vec::NonEmptyVec;
|
||||
use stdx::{never, non_empty_vec::NonEmptyVec};
|
||||
use syntax::{
|
||||
ast::{self, make::tokens::doc_comment},
|
||||
AstToken, Parse, PreorderWithTokens, SmolStr, SyntaxElement, SyntaxKind,
|
||||
|
@ -66,8 +66,7 @@ pub fn token_tree_to_syntax_node(
|
|||
parser::Step::Error { msg } => tree_sink.error(msg.to_string()),
|
||||
}
|
||||
}
|
||||
if tree_sink.roots.len() != 1 {
|
||||
cov_mark::hit!(expansion_does_not_parse_as_expression);
|
||||
if never!(tree_sink.roots.len() != 1) {
|
||||
return Err(ExpandError::ConversionError);
|
||||
}
|
||||
//FIXME: would be cool to report errors
|
||||
|
|
|
@ -148,6 +148,19 @@ pub(crate) mod entry {
|
|||
}
|
||||
m.complete(p, ERROR);
|
||||
}
|
||||
|
||||
pub(crate) fn meta_item(p: &mut Parser) {
|
||||
let m = p.start();
|
||||
attributes::meta(p);
|
||||
if p.at(EOF) {
|
||||
m.abandon(p);
|
||||
return;
|
||||
}
|
||||
while !p.at(EOF) {
|
||||
p.bump_any();
|
||||
}
|
||||
m.complete(p, ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,9 +99,11 @@ impl PrefixEntryPoint {
|
|||
/// ```
|
||||
///
|
||||
/// the input to the macro will be parsed with [`PrefixEntryPoint::Item`], and
|
||||
/// the result will be [`TopEntryPoint::Items`].
|
||||
/// the result will be [`TopEntryPoint::MacroItems`].
|
||||
///
|
||||
/// This *should* (but currently doesn't) guarantee that all input is consumed.
|
||||
/// [`TopEntryPoint::parse`] makes a guarantee that
|
||||
/// * all input is consumed
|
||||
/// * the result is a valid tree (there's one root node)
|
||||
#[derive(Debug)]
|
||||
pub enum TopEntryPoint {
|
||||
SourceFile,
|
||||
|
@ -124,13 +126,29 @@ impl TopEntryPoint {
|
|||
TopEntryPoint::Pattern => grammar::entry::top::pattern,
|
||||
TopEntryPoint::Type => grammar::entry::top::type_,
|
||||
TopEntryPoint::Expr => grammar::entry::top::expr,
|
||||
// FIXME
|
||||
TopEntryPoint::MetaItem => grammar::entry::prefix::meta_item,
|
||||
TopEntryPoint::MetaItem => grammar::entry::top::meta_item,
|
||||
};
|
||||
let mut p = parser::Parser::new(input);
|
||||
entry_point(&mut p);
|
||||
let events = p.finish();
|
||||
event::process(events)
|
||||
let res = event::process(events);
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
let mut depth = 0;
|
||||
let mut first = true;
|
||||
for step in res.iter() {
|
||||
assert!(depth > 0 || first);
|
||||
first = false;
|
||||
match step {
|
||||
Step::Enter { .. } => depth += 1,
|
||||
Step::Exit => depth -= 1,
|
||||
Step::Token { .. } | Step::Error { .. } => (),
|
||||
}
|
||||
}
|
||||
assert!(!first, "no tree at all");
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue