ok/jj
1
0
Fork 0
forked from mirrors/jj

revsets: allow parenthesized expressions

We'll clearly want to allow parenthesized expressions once we have
infix operators (if not before). Let's prepare by allowing parentheses
already now.
This commit is contained in:
Martin von Zweigbergk 2021-04-17 21:22:46 -07:00
parent d71c083a7f
commit d9ae7cdd6d
3 changed files with 54 additions and 6 deletions

View file

@ -35,9 +35,14 @@ function_arguments = {
| ""
}
primary = {
symbol
| "(" ~ expression ~ ")"
}
expression = {
parents ~ expression
| ancestors ~ expression
| function_name ~ "(" ~ function_arguments ~ ")"
| symbol
| primary
}

View file

@ -111,7 +111,7 @@ pub enum RevsetExpression {
fn parse_expression_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, RevsetParseError> {
let first = pairs.next().unwrap();
match first.as_rule() {
Rule::symbol => Ok(RevsetExpression::Symbol(first.as_str().to_owned())),
Rule::primary => parse_primary_rule(first.into_inner()),
Rule::parents => {
let expression = pairs.next().unwrap();
Ok(RevsetExpression::Parents(Box::new(parse_expression_rule(
@ -135,6 +135,17 @@ fn parse_expression_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, Rev
}
}
fn parse_primary_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, RevsetParseError> {
let first = pairs.next().unwrap();
match first.as_rule() {
Rule::symbol => Ok(RevsetExpression::Symbol(first.as_str().to_owned())),
Rule::expression => parse_expression_rule(first.into_inner()),
_ => {
panic!("unxpected revset parse rule: {:?}", first.as_str());
}
}
}
fn parse_function_expression(
name: String,
mut argument_pairs: Pairs<Rule>,
@ -269,10 +280,12 @@ fn parse_function_argument_to_string(
.to_owned())
}
Rule::expression => {
let mut expression_pairs = first.into_inner();
let first = expression_pairs.next().unwrap();
if first.as_rule() == Rule::symbol {
return Ok(first.as_str().to_owned());
let first = first.into_inner().next().unwrap();
if first.as_rule() == Rule::primary {
let first = first.into_inner().next().unwrap();
if first.as_rule() == Rule::symbol {
return Ok(first.as_str().to_owned());
}
}
}
_ => {}

View file

@ -233,12 +233,22 @@ fn test_parse_revset() {
parse("foo"),
Ok(RevsetExpression::Symbol("foo".to_string()))
);
assert_eq!(
parse("(foo)"),
Ok(RevsetExpression::Symbol("foo".to_string()))
);
assert_eq!(
parse(":@"),
Ok(RevsetExpression::Parents(Box::new(
RevsetExpression::Symbol("@".to_string())
)))
);
assert_eq!(
parse(":(@)"),
Ok(RevsetExpression::Parents(Box::new(
RevsetExpression::Symbol("@".to_string())
)))
);
assert_eq!(
parse("*:@"),
Ok(RevsetExpression::Ancestors(Box::new(
@ -255,6 +265,12 @@ fn test_parse_revset_function() {
RevsetExpression::Symbol("@".to_string())
)))
);
assert_eq!(
parse("parents((@))"),
Ok(RevsetExpression::Parents(Box::new(
RevsetExpression::Symbol("@".to_string())
)))
);
assert_eq!(
parse("parents(\"@\")"),
Err(RevsetParseError::InvalidFunctionArguments {
@ -295,6 +311,20 @@ fn test_parse_revset_function() {
message: "Expected function argument of type string, found: foo()".to_string()
})
);
assert_eq!(
parse("description((foo),bar)"),
Err(RevsetParseError::InvalidFunctionArguments {
name: "description".to_string(),
message: "Expected function argument of type string, found: (foo)".to_string()
})
);
assert_eq!(
parse("description(\"(foo)\",bar)"),
Ok(RevsetExpression::Description {
needle: "(foo)".to_string(),
base_expression: Box::new(RevsetExpression::Symbol("bar".to_string()))
})
);
}
fn resolve_commit_ids(repo: RepoRef, revset_str: &str) -> Vec<CommitId> {