From 1717690a64c71a394fb091763ea4bb18375d7dc3 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Wed, 16 Nov 2022 16:47:00 +0900 Subject: [PATCH] revset: leverage SOI/EOI markers to detect incomplete parser input The error message is still a bit cryptic, but I don't think it's worse than the original "incomplete parse" error. https://pest.rs/book/grammars/syntax.html#start-and-end-of-input --- lib/src/revset.pest | 2 ++ lib/src/revset.rs | 14 +------------- tests/test_revset_output.rs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/src/revset.pest b/lib/src/revset.pest index f96f05c7a..02f1b5414 100644 --- a/lib/src/revset.pest +++ b/lib/src/revset.pest @@ -66,3 +66,5 @@ infix_expression = { expression = { whitespace* ~ infix_expression ~ whitespace* } + +program = _{ SOI ~ expression ~ EOI } diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 3ea998ba8..8f600c6e1 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -857,20 +857,8 @@ pub fn parse( revset_str: &str, workspace_ctx: Option<&RevsetWorkspaceContext>, ) -> Result, RevsetParseError> { - let mut pairs = RevsetParser::parse(Rule::expression, revset_str)?; + let mut pairs = RevsetParser::parse(Rule::program, revset_str)?; let first = pairs.next().unwrap(); - assert!(pairs.next().is_none()); - if first.as_span().end() != revset_str.len() { - let pos = pest::Position::new(revset_str, first.as_span().end()).unwrap(); - let err = pest::error::Error::new_from_pos( - pest::error::ErrorVariant::CustomError { - message: "Incomplete parse".to_string(), - }, - pos, - ); - return Err(RevsetParseError::from(err)); - } - parse_expression_rule(first.into_inner(), workspace_ctx) } diff --git a/tests/test_revset_output.rs b/tests/test_revset_output.rs index 1de2a351d..45bd883d7 100644 --- a/tests/test_revset_output.rs +++ b/tests/test_revset_output.rs @@ -16,6 +16,23 @@ use common::TestEnvironment; pub mod common; +#[test] +fn test_syntax_error() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + + let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", "x &"]); + insta::assert_snapshot!(stderr, @r###" + Error: Failed to parse revset: --> 1:4 + | + 1 | x & + | ^--- + | + = expected range_expression + "###); +} + #[test] fn test_bad_function_call() { let test_env = TestEnvironment::default();