mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 23:23:20 +00:00
fileset, templater: insert intermediate InvalidArguments error type
This will help extract common FunctionCallNode<'i, T> type. We don't need freedom of arbitrary error type choices, but implementing From<_> is the easiest option I can think of. Another option is to constrain error type by the expression type T through "T::ParseError: ArgumentsParseError" or something, but it seemed a bit weird that we have to use trait just for that.
This commit is contained in:
parent
82b0e88a21
commit
0c05c541a1
3 changed files with 52 additions and 30 deletions
|
@ -18,7 +18,7 @@ use std::{error, mem};
|
|||
use itertools::Itertools as _;
|
||||
use jj_lib::dsl_util::{
|
||||
collect_similar, AliasDeclaration, AliasDeclarationParser, AliasId, AliasesMap,
|
||||
StringLiteralParser,
|
||||
InvalidArguments, StringLiteralParser,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
|
@ -149,16 +149,6 @@ impl TemplateParseError {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn invalid_arguments(name: &str, message: String, span: pest::Span<'_>) -> Self {
|
||||
TemplateParseError::with_span(
|
||||
TemplateParseErrorKind::InvalidArguments {
|
||||
name: name.to_owned(),
|
||||
message,
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn expected_type(expected: &str, actual: &str, span: pest::Span<'_>) -> Self {
|
||||
let message =
|
||||
format!(r#"Expected expression of type "{expected}", but actual type is "{actual}""#);
|
||||
|
@ -238,6 +228,16 @@ impl From<pest::error::Error<Rule>> for TemplateParseError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<InvalidArguments<'_>> for TemplateParseError {
|
||||
fn from(err: InvalidArguments<'_>) -> Self {
|
||||
let kind = TemplateParseErrorKind::InvalidArguments {
|
||||
name: err.name.to_owned(),
|
||||
message: err.message,
|
||||
};
|
||||
Self::with_span(kind, err.span)
|
||||
}
|
||||
}
|
||||
|
||||
fn rename_rules_in_pest_error(err: pest::error::Error<Rule>) -> pest::error::Error<Rule> {
|
||||
err.renamed_rules(|rule| {
|
||||
rule.to_symbol()
|
||||
|
@ -623,11 +623,12 @@ pub fn expand_aliases<'i>(
|
|||
ExpressionKind::FunctionCall(function) => {
|
||||
if let Some((id, params, defn)) = state.aliases_map.get_function(function.name) {
|
||||
if function.args.len() != params.len() {
|
||||
return Err(TemplateParseError::invalid_arguments(
|
||||
function.name,
|
||||
format!("Expected {} arguments", params.len()),
|
||||
function.args_span,
|
||||
));
|
||||
return Err(InvalidArguments {
|
||||
name: function.name,
|
||||
message: format!("Expected {} arguments", params.len()),
|
||||
span: function.args_span,
|
||||
}
|
||||
.into());
|
||||
}
|
||||
// Resolve arguments in the current scope, and pass them in to the alias
|
||||
// expansion scope.
|
||||
|
@ -727,7 +728,11 @@ impl<'i> FunctionCallNode<'i> {
|
|||
}
|
||||
|
||||
fn invalid_arguments(&self, message: String) -> TemplateParseError {
|
||||
TemplateParseError::invalid_arguments(self.name, message, self.args_span)
|
||||
InvalidArguments {
|
||||
name: self.name,
|
||||
message,
|
||||
span: self.args_span,
|
||||
}.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,20 @@ use itertools::Itertools as _;
|
|||
use pest::iterators::Pairs;
|
||||
use pest::RuleType;
|
||||
|
||||
/// Unexpected number of arguments, or invalid combination of arguments.
|
||||
///
|
||||
/// This error is supposed to be converted to language-specific parse error
|
||||
/// type, where lifetime `'i` will be eliminated.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InvalidArguments<'i> {
|
||||
/// Function name.
|
||||
pub name: &'i str,
|
||||
/// Error message.
|
||||
pub message: String,
|
||||
/// Span of the bad arguments.
|
||||
pub span: pest::Span<'i>,
|
||||
}
|
||||
|
||||
/// Helper to parse string literal.
|
||||
#[derive(Debug)]
|
||||
pub struct StringLiteralParser<R> {
|
||||
|
|
|
@ -24,7 +24,7 @@ use pest::Parser;
|
|||
use pest_derive::Parser;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::dsl_util::StringLiteralParser;
|
||||
use crate::dsl_util::{InvalidArguments, StringLiteralParser};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "fileset.pest"]
|
||||
|
@ -121,17 +121,6 @@ impl FilesetParseError {
|
|||
self
|
||||
}
|
||||
|
||||
/// Unexpected number of arguments, or invalid combination of arguments.
|
||||
pub(super) fn invalid_arguments(name: &str, message: String, span: pest::Span<'_>) -> Self {
|
||||
FilesetParseError::new(
|
||||
FilesetParseErrorKind::InvalidArguments {
|
||||
name: name.to_owned(),
|
||||
message,
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
/// Some other expression error.
|
||||
pub(super) fn expression(message: impl Into<String>, span: pest::Span<'_>) -> Self {
|
||||
FilesetParseError::new(FilesetParseErrorKind::Expression(message.into()), span)
|
||||
|
@ -153,6 +142,15 @@ impl From<pest::error::Error<Rule>> for FilesetParseError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<InvalidArguments<'_>> for FilesetParseError {
|
||||
fn from(err: InvalidArguments<'_>) -> Self {
|
||||
let kind = FilesetParseErrorKind::InvalidArguments {
|
||||
name: err.name.to_owned(),
|
||||
message: err.message,
|
||||
};
|
||||
Self::new(kind, err.span)
|
||||
}
|
||||
}
|
||||
fn rename_rules_in_pest_error(err: pest::error::Error<Rule>) -> pest::error::Error<Rule> {
|
||||
err.renamed_rules(|rule| {
|
||||
rule.to_symbol()
|
||||
|
@ -349,7 +347,12 @@ impl<'i> FunctionCallNode<'i> {
|
|||
}
|
||||
|
||||
fn invalid_arguments(&self, message: String) -> FilesetParseError {
|
||||
FilesetParseError::invalid_arguments(self.name, message, self.args_span)
|
||||
InvalidArguments {
|
||||
name: self.name,
|
||||
message,
|
||||
span: self.args_span,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue