templater: unify variants of type error as general expression error

I'm going to add a lambda expression, and the current type-error message
wouldn't work for the lambda type. I also renamed "argument" to "expression"
as the expect_<type>() helper may be called against any expression node.
This commit is contained in:
Yuya Nishihara 2023-03-15 15:02:44 +09:00
parent f6b0b7788e
commit 0bbf146469
3 changed files with 20 additions and 21 deletions

View file

@ -17,7 +17,7 @@ use jujutsu_lib::backend::{Signature, Timestamp};
use crate::template_parser::{ use crate::template_parser::{
self, ExpressionKind, ExpressionNode, FunctionCallNode, MethodCallNode, TemplateParseError, self, ExpressionKind, ExpressionNode, FunctionCallNode, MethodCallNode, TemplateParseError,
TemplateParseErrorKind, TemplateParseResult, TemplateParseResult,
}; };
use crate::templater::{ use crate::templater::{
ConcatTemplate, ConditionalTemplate, FormattablePropertyListTemplate, IntoTemplate, ConcatTemplate, ConditionalTemplate, FormattablePropertyListTemplate, IntoTemplate,
@ -388,8 +388,7 @@ fn build_timestamp_method<'a, L: TemplateLanguage<'a>>(
let format = let format =
template_parser::expect_string_literal_with(format_node, |format, span| { template_parser::expect_string_literal_with(format_node, |format, span| {
time_util::FormattingItems::parse(format).ok_or_else(|| { time_util::FormattingItems::parse(format).ok_or_else(|| {
let kind = TemplateParseErrorKind::InvalidTimeFormat; TemplateParseError::unexpected_expression("Invalid time format", span)
TemplateParseError::with_span(kind, span)
}) })
})? })?
.into_owned(); .into_owned();
@ -570,7 +569,7 @@ pub fn expect_boolean_expression<'a, L: TemplateLanguage<'a>>(
) -> TemplateParseResult<Box<dyn TemplateProperty<L::Context, Output = bool> + 'a>> { ) -> TemplateParseResult<Box<dyn TemplateProperty<L::Context, Output = bool> + 'a>> {
build_expression(language, node)? build_expression(language, node)?
.try_into_boolean() .try_into_boolean()
.ok_or_else(|| TemplateParseError::invalid_argument_type("Boolean", node.span)) .ok_or_else(|| TemplateParseError::expected_type("Boolean", node.span))
} }
pub fn expect_integer_expression<'a, L: TemplateLanguage<'a>>( pub fn expect_integer_expression<'a, L: TemplateLanguage<'a>>(
@ -579,5 +578,5 @@ pub fn expect_integer_expression<'a, L: TemplateLanguage<'a>>(
) -> TemplateParseResult<Box<dyn TemplateProperty<L::Context, Output = i64> + 'a>> { ) -> TemplateParseResult<Box<dyn TemplateProperty<L::Context, Output = i64> + 'a>> {
build_expression(language, node)? build_expression(language, node)?
.try_into_integer() .try_into_integer()
.ok_or_else(|| TemplateParseError::invalid_argument_type("Integer", node.span)) .ok_or_else(|| TemplateParseError::expected_type("Integer", node.span))
} }

View file

@ -49,12 +49,10 @@ pub enum TemplateParseErrorKind {
NoSuchMethod { type_name: String, name: String }, NoSuchMethod { type_name: String, name: String },
#[error(r#"Function "{name}": {message}"#)] #[error(r#"Function "{name}": {message}"#)]
InvalidArguments { name: String, message: String }, InvalidArguments { name: String, message: String },
#[error(r#"Expected argument of type "{0}""#)]
InvalidArgumentType(String),
#[error("Invalid time format")]
InvalidTimeFormat,
#[error("Redefinition of function parameter")] #[error("Redefinition of function parameter")]
RedefinedFunctionParameter, RedefinedFunctionParameter,
#[error("{0}")]
UnexpectedExpression(String),
#[error(r#"Alias "{0}" cannot be expanded"#)] #[error(r#"Alias "{0}" cannot be expanded"#)]
BadAliasExpansion(String), BadAliasExpansion(String),
#[error(r#"Alias "{0}" expanded recursively"#)] #[error(r#"Alias "{0}" expanded recursively"#)]
@ -125,12 +123,14 @@ impl TemplateParseError {
) )
} }
pub fn invalid_argument_type( pub fn expected_type(type_name: &str, span: pest::Span<'_>) -> Self {
expected_type_name: impl Into<String>, let message = format!(r#"Expected expression of type "{type_name}""#);
span: pest::Span<'_>, TemplateParseError::unexpected_expression(message, span)
) -> Self { }
pub fn unexpected_expression(message: impl Into<String>, span: pest::Span<'_>) -> Self {
TemplateParseError::with_span( TemplateParseError::with_span(
TemplateParseErrorKind::InvalidArgumentType(expected_type_name.into()), TemplateParseErrorKind::UnexpectedExpression(message.into()),
span, span,
) )
} }
@ -636,8 +636,8 @@ pub fn expect_string_literal_with<'a, 'i, T>(
| ExpressionKind::Integer(_) | ExpressionKind::Integer(_)
| ExpressionKind::Concat(_) | ExpressionKind::Concat(_)
| ExpressionKind::FunctionCall(_) | ExpressionKind::FunctionCall(_)
| ExpressionKind::MethodCall(_) => Err(TemplateParseError::invalid_argument_type( | ExpressionKind::MethodCall(_) => Err(TemplateParseError::unexpected_expression(
"String literal", "Expected string literal",
node.span, node.span,
)), )),
ExpressionKind::AliasExpanded(id, subst) => expect_string_literal_with(subst, f) ExpressionKind::AliasExpanded(id, subst) => expect_string_literal_with(subst, f)

View file

@ -232,7 +232,7 @@ fn test_templater_parse_error() {
1 | if(label("foo", "bar"), "baz") 1 | if(label("foo", "bar"), "baz")
| ^-----------------^ | ^-----------------^
| |
= Expected argument of type "Boolean" = Expected expression of type "Boolean"
"###); "###);
} }
@ -368,7 +368,7 @@ fn test_templater_timestamp_method() {
1 | author.timestamp().format(0) 1 | author.timestamp().format(0)
| ^ | ^
| |
= Expected argument of type "String literal" = Expected string literal
"###); "###);
// Dynamic string isn't supported yet // Dynamic string isn't supported yet
@ -378,7 +378,7 @@ fn test_templater_timestamp_method() {
1 | author.timestamp().format("%Y" ++ "%m") 1 | author.timestamp().format("%Y" ++ "%m")
| ^----------^ | ^----------^
| |
= Expected argument of type "String literal" = Expected string literal
"###); "###);
// Literal alias expansion // Literal alias expansion
@ -657,7 +657,7 @@ fn test_templater_alias() {
1 | identity(identity(commit_id.short(""))) 1 | identity(identity(commit_id.short("")))
| ^^ | ^^
| |
= Expected argument of type "Integer" = Expected expression of type "Integer"
"###); "###);
insta::assert_snapshot!(render_err("commit_id ++ recurse"), @r###" insta::assert_snapshot!(render_err("commit_id ++ recurse"), @r###"
@ -716,7 +716,7 @@ fn test_templater_alias() {
1 | coalesce(label("x", "not boolean"), "") 1 | coalesce(label("x", "not boolean"), "")
| ^-----------------------^ | ^-----------------------^
| |
= Expected argument of type "Boolean" = Expected expression of type "Boolean"
"###); "###);
} }