mirror of
https://github.com/martinvonz/jj.git
synced 2024-10-24 07:32:54 +00:00
templater: fix handling of method chaining of parenthesized expression
This commit is contained in:
parent
16a744fe18
commit
9a5a88238b
2 changed files with 32 additions and 12 deletions
|
@ -582,18 +582,13 @@ fn parse_term<'a, C: 'a>(
|
|||
let expr = inner.next().unwrap();
|
||||
let maybe_method = inner.next().unwrap();
|
||||
assert!(inner.next().is_none());
|
||||
match expr.as_rule() {
|
||||
let primary = match expr.as_rule() {
|
||||
Rule::literal => {
|
||||
let text = parse_string_literal(expr);
|
||||
let term = PropertyAndLabels(Property::String(Box::new(Literal(text))), vec![]);
|
||||
let property = parse_method_chain(maybe_method, term, parse_keyword)?;
|
||||
Ok(Expression::Property(property))
|
||||
}
|
||||
Rule::identifier => {
|
||||
let term = parse_keyword(expr)?;
|
||||
let property = parse_method_chain(maybe_method, term, parse_keyword)?;
|
||||
Ok(Expression::Property(property))
|
||||
Expression::Property(term)
|
||||
}
|
||||
Rule::identifier => Expression::Property(parse_keyword(expr)?),
|
||||
Rule::function => {
|
||||
let (name, args_pair) = {
|
||||
let mut inner = expr.into_inner();
|
||||
|
@ -603,7 +598,7 @@ fn parse_term<'a, C: 'a>(
|
|||
assert_eq!(args_pair.as_rule(), Rule::function_arguments);
|
||||
(name, args_pair)
|
||||
};
|
||||
let expression = match name.as_str() {
|
||||
match name.as_str() {
|
||||
"label" => {
|
||||
let [label_pair, content_pair] = expect_exact_arguments(args_pair)?;
|
||||
let label_property =
|
||||
|
@ -649,11 +644,24 @@ fn parse_term<'a, C: 'a>(
|
|||
Expression::Template(template)
|
||||
}
|
||||
_ => return Err(TemplateParseError::no_such_function(&name)),
|
||||
};
|
||||
Ok(expression)
|
||||
}
|
||||
}
|
||||
Rule::template => parse_template_rule(expr, parse_keyword),
|
||||
Rule::template => parse_template_rule(expr, parse_keyword)?,
|
||||
other => panic!("unexpected term: {other:?}"),
|
||||
};
|
||||
match primary {
|
||||
Expression::Property(property) => {
|
||||
parse_method_chain(maybe_method, property, parse_keyword).map(Expression::Property)
|
||||
}
|
||||
Expression::Template(template) => {
|
||||
if let Some(chain) = maybe_method.into_inner().next() {
|
||||
assert_eq!(chain.as_rule(), Rule::function);
|
||||
let name = chain.into_inner().next().unwrap();
|
||||
Err(TemplateParseError::no_such_method("Template", &name))
|
||||
} else {
|
||||
Ok(Expression::Template(template))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,9 @@ fn test_templater_parsed_tree() {
|
|||
|
||||
// Parenthesized "if" condition
|
||||
insta::assert_snapshot!(render(r#"if((divergent), "t", "f")"#), @"f");
|
||||
|
||||
// Parenthesized method chaining
|
||||
insta::assert_snapshot!(render(r#"(commit_id).short()"#), @"000000000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -148,6 +151,15 @@ fn test_templater_parse_error() {
|
|||
= Method "foo" doesn't exist for type "String"
|
||||
"###);
|
||||
|
||||
insta::assert_snapshot!(render_err(r#"("foo" "bar").baz()"#), @r###"
|
||||
Error: Failed to parse template: --> 1:15
|
||||
|
|
||||
1 | ("foo" "bar").baz()
|
||||
| ^-^
|
||||
|
|
||||
= Method "baz" doesn't exist for type "Template"
|
||||
"###);
|
||||
|
||||
insta::assert_snapshot!(render_err(r#"description.contains()"#), @r###"
|
||||
Error: Failed to parse template: --> 1:22
|
||||
|
|
||||
|
|
Loading…
Reference in a new issue