mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Add parser unit tests
This commit is contained in:
parent
725805dc79
commit
d149bb885b
3 changed files with 58 additions and 6 deletions
|
@ -26,7 +26,7 @@ pub use tt::{Delimiter, Punct};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
ParseError,
|
Expected(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -77,18 +77,70 @@ fn parse_repeat(p: &mut TtCursor) -> Result<crate::Repeat, ParseError> {
|
||||||
let subtree = p.eat_subtree().unwrap();
|
let subtree = p.eat_subtree().unwrap();
|
||||||
let mut subtree = parse_subtree(subtree)?;
|
let mut subtree = parse_subtree(subtree)?;
|
||||||
subtree.delimiter = crate::Delimiter::None;
|
subtree.delimiter = crate::Delimiter::None;
|
||||||
let sep = p.eat_punct().ok_or(ParseError::ParseError)?;
|
let sep = p.eat_punct().ok_or(ParseError::Expected(String::from("separator")))?;
|
||||||
let (separator, rep) = match sep.char {
|
let (separator, rep) = match sep.char {
|
||||||
'*' | '+' | '?' => (None, sep.char),
|
'*' | '+' | '?' => (None, sep.char),
|
||||||
char => (Some(char), p.eat_punct().ok_or(ParseError::ParseError)?.char),
|
char => {
|
||||||
|
(Some(char), p.eat_punct().ok_or(ParseError::Expected(String::from("separator")))?.char)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind = match rep {
|
let kind = match rep {
|
||||||
'*' => crate::RepeatKind::ZeroOrMore,
|
'*' => crate::RepeatKind::ZeroOrMore,
|
||||||
'+' => crate::RepeatKind::OneOrMore,
|
'+' => crate::RepeatKind::OneOrMore,
|
||||||
'?' => crate::RepeatKind::ZeroOrOne,
|
'?' => crate::RepeatKind::ZeroOrOne,
|
||||||
_ => return Err(ParseError::ParseError),
|
_ => return Err(ParseError::Expected(String::from("repeat"))),
|
||||||
};
|
};
|
||||||
p.bump();
|
p.bump();
|
||||||
Ok(crate::Repeat { subtree, kind, separator })
|
Ok(crate::Repeat { subtree, kind, separator })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use ra_syntax::{ast, AstNode};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::ast_to_token_tree;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_parse() {
|
||||||
|
expect_err("invalid", "subtree");
|
||||||
|
|
||||||
|
is_valid("($i:ident) => ()");
|
||||||
|
expect_err("$i:ident => ()", "subtree");
|
||||||
|
expect_err("($i:ident) ()", "`=`");
|
||||||
|
expect_err("($($i:ident)_) => ()", "separator");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_err(macro_body: &str, expected: &str) {
|
||||||
|
assert_eq!(
|
||||||
|
create_rules(&format_macro(macro_body)),
|
||||||
|
Err(ParseError::Expected(String::from(expected)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_valid(macro_body: &str) {
|
||||||
|
assert!(create_rules(&format_macro(macro_body)).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_macro(macro_body: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"
|
||||||
|
macro_rules! foo {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
",
|
||||||
|
macro_body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_rules(macro_definition: &str) -> Result<crate::MacroRules, ParseError> {
|
||||||
|
let source_file = ast::SourceFile::parse(macro_definition);
|
||||||
|
let macro_definition =
|
||||||
|
source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
|
||||||
|
|
||||||
|
let (definition_tt, _) = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
|
||||||
|
parse(&definition_tt)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl<'a> TtCursor<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(sub)
|
Ok(sub)
|
||||||
}
|
}
|
||||||
_ => Err(ParseError::ParseError),
|
_ => Err(ParseError::Expected(String::from("subtree"))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ impl<'a> TtCursor<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ParseError::ParseError)
|
Err(ParseError::Expected(format!("`{}`", char)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue