revsets: accept quoted symbol names

Git refs with names containing e.g "-" are currently not accepted
symbol names, and I don't plan to change the grammar to accept
them. Instead, let's have the user quote symbol names containing
unusual characters. That way we can keep these symbols reserved for
revset operators.

With this patch the user can do e.g. `jj diff -r '"v2.9.0-rc2"'`.
This commit is contained in:
Martin von Zweigbergk 2021-04-22 22:15:19 -07:00
parent d78fd9e979
commit 5819687237
2 changed files with 32 additions and 2 deletions

View file

@ -12,7 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
symbol = @{ (ASCII_ALPHANUMERIC | "@" | "/" | ".")+ }
identifier = @{ (ASCII_ALPHANUMERIC | "@" | "/" | ".")+ }
symbol = {
identifier
| literal_string
}
literal_string = { "\"" ~ (!"\"" ~ ANY)+ ~ "\"" }
whitespace = _{ " " }

View file

@ -233,13 +233,34 @@ fn parse_primary_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, Revset
let argument_pairs = pairs.next().unwrap().into_inner();
parse_function_expression(name, argument_pairs)
}
Rule::symbol => Ok(RevsetExpression::Symbol(first.as_str().to_owned())),
Rule::symbol => parse_symbol_rule(first.into_inner()),
_ => {
panic!("unxpected revset parse rule: {:?}", first.as_str());
}
}
}
fn parse_symbol_rule(mut pairs: Pairs<Rule>) -> Result<RevsetExpression, RevsetParseError> {
let first = pairs.next().unwrap();
match first.as_rule() {
Rule::identifier => Ok(RevsetExpression::Symbol(first.as_str().to_owned())),
Rule::literal_string => {
return Ok(RevsetExpression::Symbol(
first
.as_str()
.strip_prefix('"')
.unwrap()
.strip_suffix('"')
.unwrap()
.to_owned(),
));
}
_ => {
panic!("unxpected symbol parse rule: {:?}", first.as_str());
}
}
}
fn parse_function_expression(
name: String,
mut argument_pairs: Pairs<Rule>,
@ -858,6 +879,11 @@ mod tests {
parse("(foo)"),
Ok(RevsetExpression::Symbol("foo".to_string()))
);
// Parse a quoted symbol
assert_eq!(
parse("\"foo\""),
Ok(RevsetExpression::Symbol("foo".to_string()))
);
// Parse the "parents" operator
assert_eq!(
parse(":@"),