mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 07:14:38 +00:00
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:
parent
f6b0b7788e
commit
0bbf146469
3 changed files with 20 additions and 21 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue