From 9d67b944cf7a7a2d581fda3120aa3b5c73142e39 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 22 Aug 2022 09:07:15 +0900 Subject: [PATCH] Integrate ParseError to compiler-core::Error --- core/src/error.rs | 22 ++++++++++++++ core/src/lib.rs | 2 ++ parser/Cargo.toml | 1 + parser/src/error.rs | 70 ++++++++++++++++++++++++------------------- parser/src/fstring.rs | 4 +-- src/lib.rs | 2 ++ 6 files changed, 69 insertions(+), 32 deletions(-) create mode 100644 core/src/error.rs diff --git a/core/src/error.rs b/core/src/error.rs new file mode 100644 index 0000000..4553b60 --- /dev/null +++ b/core/src/error.rs @@ -0,0 +1,22 @@ +use crate::Location; + +#[derive(Debug, PartialEq, Eq)] +pub struct Error { + pub error: T, + pub location: Location, + pub source_path: String, +} + +impl std::ops::Deref for Error { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.error + } +} + +impl Error { + pub fn error(self) -> T { + self.error + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index 0b2e23e..f38c6d0 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -2,9 +2,11 @@ #![doc(html_root_url = "https://docs.rs/rustpython-compiler-core/")] mod bytecode; +mod error; mod location; mod mode; pub use bytecode::*; +pub use error::Error; pub use location::Location; pub use mode::Mode; diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 2522e72..e6acbbd 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -16,6 +16,7 @@ tiny-keccak = { version = "2", features = ["sha3"] } [dependencies] rustpython-ast = { path = "../ast" } +rustpython-compiler-core = { path = "../core" } ahash = "0.7.6" itertools = "0.10.3" diff --git a/parser/src/error.rs b/parser/src/error.rs index 76f02dc..b64abcb 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -118,11 +118,7 @@ impl From for LalrpopError { /// Represents an error during parsing #[derive(Debug, PartialEq)] -pub struct ParseError { - pub error: ParseErrorType, - pub location: Location, - pub source_path: String, -} +pub struct ParseError(rustpython_compiler_core::Error); #[derive(Debug, PartialEq)] pub enum ParseErrorType { @@ -138,8 +134,28 @@ pub enum ParseErrorType { Lexical(LexicalErrorType), } +impl From for rustpython_compiler_core::Error { + fn from(err: ParseError) -> Self { + err.0 + } +} + +impl From for ParseErrorType { + fn from(err: ParseError) -> Self { + err.0.error + } +} + /// Convert `lalrpop_util::ParseError` to our internal type impl ParseError { + fn new(error: ParseErrorType, location: Location, source_path: String) -> Self { + Self(rustpython_compiler_core::Error { + error, + location, + source_path, + }) + } + pub(crate) fn from_lalrpop( err: LalrpopError, source_path: &str, @@ -147,36 +163,30 @@ impl ParseError { let source_path = source_path.to_owned(); match err { // TODO: Are there cases where this isn't an EOF? - LalrpopError::InvalidToken { location } => ParseError { - error: ParseErrorType::Eof, - location, + LalrpopError::InvalidToken { location } => { + ParseError::new(ParseErrorType::Eof, location, source_path) + } + LalrpopError::ExtraToken { token } => { + ParseError::new(ParseErrorType::ExtraToken(token.1), token.0, source_path) + } + LalrpopError::User { error } => ParseError::new( + ParseErrorType::Lexical(error.error), + error.location, source_path, - }, - LalrpopError::ExtraToken { token } => ParseError { - error: ParseErrorType::ExtraToken(token.1), - location: token.0, - source_path, - }, - LalrpopError::User { error } => ParseError { - error: ParseErrorType::Lexical(error.error), - location: error.location, - source_path, - }, + ), LalrpopError::UnrecognizedToken { token, expected } => { // Hacky, but it's how CPython does it. See PyParser_AddToken, // in particular "Only one possible expected token" comment. let expected = (expected.len() == 1).then(|| expected[0].clone()); - ParseError { - error: ParseErrorType::UnrecognizedToken(token.1, expected), - location: token.0, + ParseError::new( + ParseErrorType::UnrecognizedToken(token.1, expected), + token.0, source_path, - } + ) + } + LalrpopError::UnrecognizedEOF { location, .. } => { + ParseError::new(ParseErrorType::Eof, location, source_path) } - LalrpopError::UnrecognizedEOF { location, .. } => ParseError { - error: ParseErrorType::Eof, - location, - source_path, - }, } } } @@ -229,9 +239,9 @@ impl ParseErrorType { } impl std::ops::Deref for ParseError { - type Target = ParseErrorType; + type Target = rustpython_compiler_core::Error; fn deref(&self) -> &Self::Target { - &self.error + &self.0 } } diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index 11d75a0..dc17063 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -186,7 +186,7 @@ impl<'a> FStringParser<'a> { vec![self.expr(ExprKind::FormattedValue { value: Box::new( parse_fstring_expr(&expression) - .map_err(|e| InvalidExpression(Box::new(e.error)))?, + .map_err(|e| InvalidExpression(Box::new(e.into())))?, ), conversion: conversion as _, format_spec: spec, @@ -204,7 +204,7 @@ impl<'a> FStringParser<'a> { self.expr(ExprKind::FormattedValue { value: Box::new( parse_fstring_expr(&expression) - .map_err(|e| InvalidExpression(Box::new(e.error)))?, + .map_err(|e| InvalidExpression(Box::new(e.into())))?, ), conversion: (if conversion == ConversionFlag::None && spec.is_none() { diff --git a/src/lib.rs b/src/lib.rs index a96eefa..4e057a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use rustpython_codegen::{compile, symboltable}; use rustpython_compiler_core::CodeObject; use rustpython_parser::{ ast::{fold::Fold, ConstantOptimizer, Location}, + error::ParseErrorType, parser, }; use std::fmt; @@ -48,6 +49,7 @@ impl CompileError { } } fn from_parse(error: rustpython_parser::error::ParseError, source: &str) -> Self { + let error: rustpython_compiler_core::Error = error.into(); Self { error: error.error.into(), location: error.location,