mirror of
https://github.com/jj-vcs/jj.git
synced 2025-12-23 06:01:01 +00:00
revset: add parsing function that rejects expression other than symbol name
This commit is contained in:
parent
683ee9287e
commit
59ca16705e
3 changed files with 43 additions and 0 deletions
|
|
@ -122,6 +122,8 @@ program = _{
|
|||
SOI ~ whitespace* ~ (program_modifier ~ whitespace*)? ~ expression ~ whitespace* ~ EOI
|
||||
}
|
||||
|
||||
symbol_name = _{ SOI ~ symbol ~ EOI }
|
||||
|
||||
function_alias_declaration = {
|
||||
function_name ~ "(" ~ whitespace* ~ formal_parameters ~ whitespace* ~ ")"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ use crate::repo::RepoLoaderError;
|
|||
use crate::repo_path::RepoPathUiConverter;
|
||||
use crate::revset_parser;
|
||||
pub use crate::revset_parser::expect_literal;
|
||||
pub use crate::revset_parser::parse_symbol;
|
||||
pub use crate::revset_parser::BinaryOp;
|
||||
pub use crate::revset_parser::ExpressionKind;
|
||||
pub use crate::revset_parser::ExpressionNode;
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ impl Rule {
|
|||
Rule::expression => None,
|
||||
Rule::program_modifier => None,
|
||||
Rule::program => None,
|
||||
Rule::symbol_name => None,
|
||||
Rule::function_alias_declaration => None,
|
||||
Rule::alias_declaration => None,
|
||||
}
|
||||
|
|
@ -689,6 +690,22 @@ pub fn is_identifier(text: &str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses the text as a revset symbol, rejects empty string.
|
||||
pub fn parse_symbol(text: &str) -> Result<String, RevsetParseError> {
|
||||
let mut pairs = RevsetParser::parse(Rule::symbol_name, text)?;
|
||||
let first = pairs.next().unwrap();
|
||||
let span = first.as_span();
|
||||
let name = parse_as_string_literal(first);
|
||||
if name.is_empty() {
|
||||
Err(RevsetParseError::expression(
|
||||
"Expected non-empty string",
|
||||
span,
|
||||
))
|
||||
} else {
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub type RevsetAliasesMap = AliasesMap<RevsetAliasParser, String>;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
|
@ -1287,6 +1304,29 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_symbol_explicitly() {
|
||||
assert_matches!(parse_symbol("").as_deref(), Err(_));
|
||||
// empty string could be a valid ref name, but it would be super
|
||||
// confusing if identifier was empty.
|
||||
assert_matches!(parse_symbol("''").as_deref(), Err(_));
|
||||
|
||||
assert_matches!(parse_symbol("foo.bar").as_deref(), Ok("foo.bar"));
|
||||
assert_matches!(parse_symbol("foo@bar").as_deref(), Err(_));
|
||||
assert_matches!(parse_symbol("foo bar").as_deref(), Err(_));
|
||||
|
||||
assert_matches!(parse_symbol("'foo bar'").as_deref(), Ok("foo bar"));
|
||||
assert_matches!(parse_symbol(r#""foo\tbar""#).as_deref(), Ok("foo\tbar"));
|
||||
|
||||
// leading/trailing whitespace is NOT ignored.
|
||||
assert_matches!(parse_symbol(" foo").as_deref(), Err(_));
|
||||
assert_matches!(parse_symbol("foo ").as_deref(), Err(_));
|
||||
|
||||
// (foo) could be parsed as a symbol "foo", but is rejected because user
|
||||
// might expect a literal "(foo)".
|
||||
assert_matches!(parse_symbol("(foo)").as_deref(), Err(_));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_at_workspace_and_remote_symbol() {
|
||||
// Parse "@" (the current working copy)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue