diff --git a/lib/src/revset.pest b/lib/src/revset.pest index 1c77a79f8..05ee10bec 100644 --- a/lib/src/revset.pest +++ b/lib/src/revset.pest @@ -14,6 +14,7 @@ symbol = @{ (ASCII_ALPHANUMERIC | "@" | "/" | ".")+ } literal_string = { "\"" ~ (!"\"" ~ ANY)+ ~ "\"" } +whitespace = _{ " " } parents = { ":" } ancestors = { "*:" } @@ -35,8 +36,8 @@ function_argument = { | expression } function_arguments = { - (function_argument ~ ",")* ~ function_argument - | "" + (whitespace* ~ function_argument ~ whitespace* ~ ",")* ~ whitespace* ~ function_argument ~ whitespace* + | whitespace* } primary = { @@ -48,9 +49,9 @@ primary = { prefix_expression = { prefix_operator* ~ primary } infix_expression = { - prefix_expression ~ (infix_operator ~ prefix_expression)* + whitespace* ~ prefix_expression ~ whitespace* ~ (infix_operator ~ whitespace* ~ prefix_expression ~ whitespace*)* } expression = { - infix_expression + whitespace* ~ infix_expression ~ whitespace* } diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 3307ff318..64fd14ff8 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -343,6 +343,8 @@ fn parse_function_argument_to_string( } pub fn parse(revset_str: &str) -> Result { + // TODO: Return a better error message when parsing fails (such as when the user + // puts whitespace between a prefix operator and the operand) let mut pairs: Pairs = RevsetParser::parse(Rule::expression, revset_str).unwrap(); let first = pairs.next().unwrap(); assert!(pairs.next().is_none()); diff --git a/lib/tests/test_revset.rs b/lib/tests/test_revset.rs index c5b56a3be..96b70776e 100644 --- a/lib/tests/test_revset.rs +++ b/lib/tests/test_revset.rs @@ -255,6 +255,27 @@ fn test_parse_revset() { RevsetExpression::Symbol("@".to_string()) ))) ); + assert_eq!( + parse(" *:@ "), + Ok(RevsetExpression::Ancestors(Box::new( + RevsetExpression::Symbol("@".to_string()) + ))) + ); + assert_eq!( + parse(" description( arg1 , arg2 ) - parents( arg1 ) - all_heads( ) "), + Ok(RevsetExpression::Difference( + Box::new(RevsetExpression::Difference( + Box::new(RevsetExpression::Description { + needle: "arg1".to_string(), + base_expression: Box::new(RevsetExpression::Symbol("arg2".to_string())) + }), + Box::new(RevsetExpression::Parents(Box::new( + RevsetExpression::Symbol("arg1".to_string()) + ))) + )), + Box::new(RevsetExpression::AllHeads) + )) + ); } #[test] @@ -589,21 +610,21 @@ fn test_evaluate_expression_difference(use_git: bool) { assert_eq!( resolve_commit_ids( mut_repo.as_repo_ref(), - &format!("*:{}-*:{}", commit4.id().hex(), commit5.id().hex()) + &format!("*:{} - *:{}", commit4.id().hex(), commit5.id().hex()) ), vec![commit4.id().clone(), commit3.id().clone()] ); assert_eq!( resolve_commit_ids( mut_repo.as_repo_ref(), - &format!("*:{}-*:{}", commit5.id().hex(), commit4.id().hex()) + &format!("*:{} - *:{}", commit5.id().hex(), commit4.id().hex()) ), vec![commit5.id().clone()] ); assert_eq!( resolve_commit_ids( mut_repo.as_repo_ref(), - &format!("*:{}-*:{}", commit4.id().hex(), commit2.id().hex()) + &format!("*:{} - *:{}", commit4.id().hex(), commit2.id().hex()) ), vec![commit4.id().clone(), commit3.id().clone()] ); @@ -613,7 +634,7 @@ fn test_evaluate_expression_difference(use_git: bool) { resolve_commit_ids( mut_repo.as_repo_ref(), &format!( - "*:{}-{}-{}", + "*:{} - {} - {}", commit4.id().hex(), commit2.id().hex(), commit3.id().hex() @@ -631,7 +652,7 @@ fn test_evaluate_expression_difference(use_git: bool) { resolve_commit_ids( mut_repo.as_repo_ref(), &format!( - "(*:{}-*:{})-(*:{}-*:{})", + "(*:{} - *:{}) - (*:{} - *:{})", commit4.id().hex(), commit1.id().hex(), commit3.id().hex(),