diff options
Diffstat (limited to 'third_party/rust/jsparagus-generated-parser/src/error.rs')
-rw-r--r-- | third_party/rust/jsparagus-generated-parser/src/error.rs | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/third_party/rust/jsparagus-generated-parser/src/error.rs b/third_party/rust/jsparagus-generated-parser/src/error.rs new file mode 100644 index 0000000000..38e3ed77f6 --- /dev/null +++ b/third_party/rust/jsparagus-generated-parser/src/error.rs @@ -0,0 +1,177 @@ +use crate::stack_value_generated::AstError; +use crate::DeclarationKind; +use crate::Token; +use static_assertions::assert_eq_size; +use std::{convert::Infallible, error::Error, fmt}; + +#[derive(Debug)] +pub enum ParseError<'alloc> { + // Lexical errors + IllegalCharacter(char), + InvalidEscapeSequence, + UnterminatedString, + UnterminatedRegExp, + UnterminatedMultiLineComment, + LexerError, + NoLineTerminatorHereExpectedToken, + ParserCannotUnpackToken, + + // Generic syntax errors + NotImplemented(&'static str), + SyntaxError(Token), + UnexpectedEnd, + InvalidAssignmentTarget, + InvalidParameter, + InvalidIdentifier(&'alloc str, usize), + AstError(String), + + // Destructuring errors + ArrayPatternWithNonFinalRest, + ArrayBindingPatternWithInvalidRest, + ObjectPatternWithMethod, + ObjectPatternWithNonFinalRest, + ObjectBindingPatternWithInvalidRest, + + // 14.8 Async arrow function definitions + ArrowHeadInvalid, + ArrowParametersWithNonFinalRest, + + DuplicateBinding(&'alloc str, DeclarationKind, usize, DeclarationKind, usize), + DuplicateExport(&'alloc str, usize, usize), + MissingExport(&'alloc str, usize), + + // Labelled Statement Errors + DuplicateLabel, + BadContinue, + ToughBreak, + LabelNotFound, + + // Annex B. FunctionDeclarations in IfStatement Statement Clauses + // https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses + FunctionDeclInSingleStatement, + LabelledFunctionDeclInSingleStatement, +} + +impl<'alloc> ParseError<'alloc> { + pub fn message(&self) -> String { + match self { + ParseError::IllegalCharacter(c) => format!("illegal character: {:?}", c), + ParseError::InvalidEscapeSequence => format!("invalid escape sequence"), + ParseError::UnterminatedString => format!("unterminated string literal"), + ParseError::UnterminatedRegExp => format!("unterminated regexp literal"), + ParseError::UnterminatedMultiLineComment => format!("unterminated multiline comment"), + ParseError::LexerError => format!("lexical error"), + ParseError::NoLineTerminatorHereExpectedToken => format!( + "no-line-terminator-here expects a token" + ), + ParseError::ParserCannotUnpackToken => format!("cannot unpack token"), + ParseError::NotImplemented(message) => format!("not implemented: {}", message), + ParseError::SyntaxError(token) => format!("syntax error on: {:?}", token), + ParseError::UnexpectedEnd => format!("unexpected end of input"), + ParseError::InvalidAssignmentTarget => format!("invalid left-hand side of assignment"), + ParseError::InvalidParameter => format!("invalid parameter"), + ParseError::InvalidIdentifier(name, _) => { + format!("invalid identifier {}", name) + } + ParseError::AstError(ast_error) => format!("{}", ast_error), + ParseError::ArrayPatternWithNonFinalRest => { + format!("array patterns can have a rest element (`...x`) only at the end") + } + ParseError::ArrayBindingPatternWithInvalidRest => format!( + "the expression after `...` in this array pattern must be a single identifier" + ), + ParseError::ObjectPatternWithMethod => format!("object patterns can't have methods"), + ParseError::ObjectPatternWithNonFinalRest => { + format!("object patterns can have a rest element (`...x`) only at the end") + } + ParseError::ObjectBindingPatternWithInvalidRest => format!( + "the expression after `...` in this object pattern must be a single identifier" + ), + ParseError::ArrowHeadInvalid => format!( + "unexpected `=>` after function call (parentheses around the arrow function may help)" + ), + ParseError::ArrowParametersWithNonFinalRest => format!( + "arrow function parameters can have a rest element (`...x`) only at the end" + ), + ParseError::DuplicateBinding(name, kind1, _, kind2, _) => format!( + "redeclaration of {} '{}' with {}", + kind1.to_str(), + name, + kind2.to_str(), + ), + ParseError::DuplicateExport(name, _, _) => format!( + "duplicate export name '{}'", + name, + ), + ParseError::MissingExport(name, _) => format!( + "local binding for export '{}' not found", + name, + ), + ParseError::FunctionDeclInSingleStatement => format!( + "function declarations can't appear in single-statement context" + ), + ParseError::LabelledFunctionDeclInSingleStatement => format!( + "functions can only be labelled inside blocks" + ), + ParseError::DuplicateLabel => format!( + "duplicate label" + ), + ParseError::BadContinue => format!( + "continue must be inside loop" + ), + ParseError::ToughBreak => format!( + "unlabeled break must be inside loop or switch" + ), + ParseError::LabelNotFound => format!( + "label not found" + ), + } + } +} + +impl<'alloc> PartialEq for ParseError<'alloc> { + fn eq(&self, other: &ParseError) -> bool { + format!("{:?}", self) == format!("{:?}", other) + } +} + +impl<'alloc> fmt::Display for ParseError<'alloc> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.message()) + } +} + +impl<'alloc> From<Infallible> for ParseError<'alloc> { + fn from(err: Infallible) -> ParseError<'alloc> { + match err {} + } +} + +impl<'alloc> From<AstError> for ParseError<'alloc> { + fn from(err: AstError) -> ParseError<'alloc> { + ParseError::AstError(err) + } +} + +impl<'alloc> From<Infallible> for std::boxed::Box<ParseError<'alloc>> { + fn from(err: Infallible) -> std::boxed::Box<ParseError<'alloc>> { + match err {} + } +} + +impl<'alloc> From<AstError> for std::boxed::Box<ParseError<'alloc>> { + fn from(err: AstError) -> std::boxed::Box<ParseError<'alloc>> { + ParseError::AstError(err).into() + } +} + +impl<'a, 'alloc: 'a> Error for &'a ParseError<'alloc> {} + +// NOTE: This is not the Bump allocator, as error are allocated infrequently and +// this avoid propagating the bump allocator to all places, while keeping these +// implementation possible. +pub type BoxedParseError<'alloc> = std::boxed::Box<ParseError<'alloc>>; +pub type Result<'alloc, T> = std::result::Result<T, BoxedParseError<'alloc>>; + +assert_eq_size!(BoxedParseError<'static>, usize); +assert_eq_size!(Result<'static, ()>, usize); |