Skip to content

Commit

Permalink
Make parse_declaration panics if given leftover tokens.
Browse files Browse the repository at this point in the history
Export consume_declaration.
Add unit test.
  • Loading branch information
PoignardAzur committed Dec 9, 2022
1 parent a9e1a15 commit f84a526
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ mod types;
mod types_edition;

pub use error::Error;
pub use parse::parse_declaration;
pub use parse::{consume_declaration, parse_declaration};
pub use punctuated::Punctuated;
pub use types::*;
34 changes: 26 additions & 8 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ use proc_macro2::token_stream::IntoIter;
use proc_macro2::{Delimiter, TokenStream, TokenTree};
use std::iter::Peekable;

// TODO - Return Result<...>, handle case where TokenStream is valid declaration,
// but not a type or function.

/// Parses the token stream of a type declaration.
///
/// For instance, if you're implementing a derive macro, you can pass the
Expand All @@ -29,6 +26,8 @@ use std::iter::Peekable;
/// macro, there should be no way for this to happen, as Rust will emit an
/// error instead of calling this macro.
///
/// Panics if there are leftover tokens.
///
/// ## Example
///
/// ```
Expand Down Expand Up @@ -57,15 +56,34 @@ use std::iter::Peekable;
/// E = (FOO + BAR), // Ok
/// }
/// ```

pub fn parse_declaration(tokens: TokenStream) -> Result<Declaration, Error> {
let mut tokens = tokens.into_iter().peekable();
parse_declaration_tokens(&mut tokens)
let declaration = consume_declaration(&mut tokens);

if tokens.peek().is_some() {
panic!(
"unexpected trailing tokens after declaration: {}",
tokens.collect::<TokenStream>()
);
}

declaration
}

pub(crate) fn parse_declaration_tokens(
tokens: &mut Peekable<IntoIter>,
) -> Result<Declaration, Error> {
/// Consume a type declaration from a token stream.
///
/// This is the same as [parse_declaration], except it doesn't panic if there are
/// leftover tokens.
///
/// ## Panics
///
/// Panics if given a token stream that doesn't parse as a valid Rust
/// type declaration.
///
/// ## Errors
///
/// Venial doesn't support enum discriminants with multiple non-grouped tokens.
pub fn consume_declaration(tokens: &mut Peekable<IntoIter>) -> Result<Declaration, Error> {
let attributes = consume_outer_attributes(tokens);
let vis_marker = consume_vis_marker(tokens);

Expand Down
4 changes: 2 additions & 2 deletions src/parse_mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::parse::parse_declaration_tokens;
use crate::parse::consume_declaration;
use crate::parse_type::consume_declaration_name;
use crate::parse_utils::{
consume_ident, consume_inner_attributes, consume_stuff_until, parse_ident, parse_punct,
Expand Down Expand Up @@ -43,7 +43,7 @@ pub(crate) fn parse_mod(
if tokens.peek().is_none() {
break;
}
let item = parse_declaration_tokens(&mut tokens)
let item = consume_declaration(&mut tokens)
.unwrap_or_else(|e| panic!("declaration in mod: {}", e));
mod_members.push(item);
}
Expand Down
11 changes: 11 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ fn parse_empty_enum() {
assert_debug_snapshot!(enum_type);
}

#[test]
#[should_panic = "unexpected trailing tokens after declaration"]
fn reject_trailing_tokens() {
let declaration = parse_declaration_checked(quote::quote! {
struct Good {}
trailing junk
});

println!("This should have panicked: {:#?}", declaration);
}

// ==========
// VISIBILITY
// ==========
Expand Down

0 comments on commit f84a526

Please sign in to comment.