use super::*;
impl<'source, 'ast, 'name, 'names> Parser<'source, 'ast, 'name, 'names>
where
'name: 'ast,
{
pub(in crate::parser) fn located<M: Into<ParseMessage>>(&self, message: M) -> ParseError {
self.error_at(self.current_location(), message)
}
pub(in crate::parser) fn error_at<M: Into<ParseMessage>>(
&self,
location: Location,
message: M,
) -> ParseError {
ParseError::new(location, message)
}
pub(in crate::parser) fn unexpected(&self, expected: &'static str) -> ParseError {
if let Some(found) = self.current.description() {
self.located(format!("Expected {expected}, got {found}"))
} else {
self.located(format!(
"expected {expected}, found {}",
self.current.name()
))
}
}
pub(in crate::parser) fn interpolated_double_brace_error(&self) -> ParseError {
self.located(
"Double braces are not permitted within interpolated strings; did you mean '\\{'?",
)
}
pub(in crate::parser) fn interpolated_missing_expression_error(&self) -> ParseError {
self.located("Malformed interpolated string, expected expression inside '{}'")
}
pub(in crate::parser) fn interpolated_malformed_escape_error(&self) -> ParseError {
self.located("Interpolated string literal contains malformed escape sequence")
}
pub(in crate::parser) fn interpolated_string_as_type_error(
&self,
location: Location,
) -> ParseError {
self.error_at(
location,
"Interpolated string literals cannot be used as types",
)
}
pub(in crate::parser) fn unmatched_group_error(&self, location: Location) -> ParseError {
let position = if self.current_position().line == location.begin.line {
format!("column {}", location.begin.column + 1)
} else {
format!("line {}", location.begin.line + 1)
};
let suggestion = if self.current.kind() == TokenKind::Equal {
"; did you mean to use '{' when defining a table?"
} else {
""
};
self.located(format!(
"Expected ')' (to close '(' at {position}), got {}{suggestion}",
self.current
))
}
pub(in crate::parser) fn method_call_arguments_error(
&self,
function_location: Location,
function_end_line: usize,
) -> ParseError {
if self.current_line() > function_end_line {
self.error_at(
function_location,
"Expected function call arguments after '('",
)
} else {
self.error_at(
Location::new(function_location.begin, self.current_position()),
format!(
"Expected '(', '{{' or <string> when parsing function call, got {}",
self.current
),
)
}
}
pub(in crate::parser) fn function_type_arrow_error(&self) -> ParseError {
let got = &self.current;
self.located(format!(
"Expected '->' when parsing function type, got {got}"
))
}
pub(in crate::parser) fn empty_function_type_arrow_error(
&self,
location: Location,
) -> ParseError {
self.error_at(
location,
"Expected '->' after '()' when parsing function type; did you mean 'nil'?",
)
}
pub(in crate::parser) fn function_type_colon_return_error(&self) -> ParseError {
self.located(
"Return types in function type annotations are written after '->' instead of ':'",
)
}
pub(in crate::parser) fn function_return_arrow_error(&self) -> ParseError {
self.located("Function return type annotations are written after ':' instead of '->'")
}
pub(in crate::parser) fn table_field_name_error(&self) -> ParseError {
self.located(format!(
"Expected identifier when parsing table field, got {}",
self.current
))
}
pub(in crate::parser) fn type_name_error(&self) -> ParseError {
self.located(format!(
"Expected identifier when parsing type name, got {}",
self.current
))
}
pub(in crate::parser) fn missing_type_parse_error(&self) -> ParseError {
let location = Location::new(
self.previous_token_end_position(),
self.current_token_location().end,
);
self.error_at(location, format!("Expected type, got {}", self.current))
}
pub(in crate::parser) fn generic_parameter_name_error(&self) -> ParseError {
self.located(format!("Expected identifier, got {}", self.current))
}
pub(in crate::parser) fn identifier_error(&self, context: Option<&'static str>) -> ParseError {
let got = self
.current
.description()
.map(|description| description.to_string())
.unwrap_or_else(|| self.current.to_string());
let message = if let Some(context) = context {
format!("Expected identifier when parsing {context}, got {got}")
} else {
format!("Expected identifier, got {got}")
};
self.located(message)
}
pub(in crate::parser) fn expected_eof_error(&self) -> ParseError {
self.located(format!("Expected <eof>, got {}", self.current))
}
pub(in crate::parser) fn variable_name_error(&self) -> ParseError {
let got = self
.current
.description()
.map(|description| description.to_string())
.unwrap_or_else(|| self.current.to_string());
self.located(format!(
"Expected identifier when parsing variable name, got {got}"
))
}
pub(in crate::parser) fn property_name_error(&self) -> ParseError {
self.located(format!(
"Expected identifier when parsing property name, got {}",
self.current
))
}
pub(in crate::parser) fn attribute_name_error(&self) -> ParseError {
self.located(format!(
"Expected identifier when parsing attribute name, got {}",
self.current
))
}
pub(in crate::parser) fn attribute_statement_error(&self) -> ParseError {
let expected = "'function', 'local function', 'const function', 'declare function' or a function type declaration";
self.located(format!(
"Expected {expected} after attribute, but got {} instead",
self.current
))
}
pub(in crate::parser) fn attribute_expression_error(&self, location: Location) -> ParseError {
self.error_at(
location,
format!(
"Expected 'function' declaration after attribute, but got {} instead",
self.current
),
)
}
pub(in crate::parser) fn matched_token_error(
&self,
expected: &'static str,
opener: &'static str,
location: Location,
) -> ParseError {
let position = if self.current_position().line == location.begin.line {
format!("column {}", location.begin.column + 1)
} else {
format!("line {}", location.begin.line + 1)
};
let got = &self.current;
self.located(format!(
"Expected '{expected}' (to close '{opener}' at {position}), got {got}"
))
}
pub(in crate::parser) fn matched_block_token_error(
&self,
expected: &'static str,
opener: &'static str,
location: Location,
) -> ParseError {
let position = if self.current_position().line == location.begin.line {
format!("column {}", location.begin.column + 1)
} else {
format!("line {}", location.begin.line + 1)
};
let got = &self.current;
let mut message =
format!("Expected '{expected}' (to close '{opener}' at {position}), got {got}");
if let Some(suspect) = self.contexts.end_mismatch_suspect
&& suspect.line > location.begin.line as usize + 1
{
message.push_str(&format!(
"; did you forget to close '{}' at line {}?",
suspect.opener, suspect.line
));
}
self.located(message)
}
pub(in crate::parser) fn loop_control_error(
&self,
location: Location,
keyword: &'static str,
) -> ParseError {
self.error_at(
location,
format!("{keyword} statement must be inside a loop"),
)
}
pub(in crate::parser) fn varargs_error(&self) -> ParseError {
self.located("Cannot use '...' outside of a vararg function")
}
pub(in crate::parser) fn malformed_string_error(&self) -> ParseError {
self.located("Malformed string; did you forget to finish it?")
}
}