From d876673546a232d81a41cfaa98d1e9c83cf4ec64 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 23 Aug 2022 01:30:00 +0900 Subject: [PATCH] Move out CompileError to core as generic form --- Cargo.lock | 1 + compiler/core/Cargo.toml | 1 + compiler/core/src/error.rs | 29 +++++++++++++++ compiler/core/src/lib.rs | 2 +- compiler/src/lib.rs | 75 +++++++++++--------------------------- src/shell.rs | 2 +- 6 files changed, 54 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34739f9b8..3fc549743 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1801,6 +1801,7 @@ dependencies = [ "num-complex", "serde", "static_assertions", + "thiserror", ] [[package]] diff --git a/compiler/core/Cargo.toml b/compiler/core/Cargo.toml index 5821ddc37..65be384f1 100644 --- a/compiler/core/Cargo.toml +++ b/compiler/core/Cargo.toml @@ -17,3 +17,4 @@ num-bigint = { version = "0.4.3", features = ["serde"] } num-complex = { version = "0.4.0", features = ["serde"] } serde = { version = "1.0.136", features = ["derive"] } static_assertions = "1.1.0" +thiserror = "1.0" diff --git a/compiler/core/src/error.rs b/compiler/core/src/error.rs index 40d97343a..f69b61f06 100644 --- a/compiler/core/src/error.rs +++ b/compiler/core/src/error.rs @@ -58,3 +58,32 @@ impl BaseError { BaseError::from(self) } } + +#[derive(Debug, thiserror::Error)] +pub struct CompileError { + pub body: BaseError, + pub statement: Option, +} + +impl std::ops::Deref for CompileError { + type Target = BaseError; + fn deref(&self) -> &Self::Target { + &self.body + } +} + +impl std::fmt::Display for CompileError +where + T: std::fmt::Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let loc = self.location; + if let Some(ref stmt) = self.statement { + // visualize the error when location and statement are provided + loc.fmt_with(f, &self.error)?; + write!(f, "\n{stmt}{arrow:>pad$}", pad = loc.column(), arrow = "^") + } else { + loc.fmt_with(f, &self.error) + } + } +} diff --git a/compiler/core/src/lib.rs b/compiler/core/src/lib.rs index 7360cf77f..e1f0a5b35 100644 --- a/compiler/core/src/lib.rs +++ b/compiler/core/src/lib.rs @@ -7,6 +7,6 @@ mod location; mod mode; pub use bytecode::*; -pub use error::BaseError; +pub use error::{BaseError, CompileError}; pub use location::Location; pub use mode::Mode; diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index afcb1adc7..a017c3ba7 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,14 +1,13 @@ use rustpython_codegen::{compile, symboltable}; -use rustpython_compiler_core::{BaseError, CodeObject}; +use rustpython_compiler_core::CodeObject; use rustpython_parser::{ ast::{fold::Fold, ConstantOptimizer, Location}, error::ParseErrorType, parser, }; -use std::fmt; pub use rustpython_codegen::compile::CompileOpts; -pub use rustpython_compiler_core::Mode; +pub use rustpython_compiler_core::{BaseError as CompileErrorBody, Mode}; #[derive(Debug, thiserror::Error)] pub enum CompileErrorType { @@ -18,56 +17,25 @@ pub enum CompileErrorType { Parse(#[from] rustpython_parser::error::ParseErrorType), } -pub type CompileErrorBody = BaseError; +pub type CompileError = rustpython_compiler_core::CompileError; -#[derive(Debug, thiserror::Error)] -pub struct CompileError { - pub body: CompileErrorBody, - pub statement: Option, -} - -impl std::ops::Deref for CompileError { - type Target = CompileErrorBody; - fn deref(&self) -> &Self::Target { - &self.body +fn error_from_codegen( + error: rustpython_codegen::error::CodegenError, + source: &str, +) -> CompileError { + let statement = get_statement(source, error.location); + CompileError { + body: error.into(), + statement, } } -impl fmt::Display for CompileError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let loc = self.location; - if let Some(ref stmt) = self.statement { - // visualize the error when location and statement are provided - loc.fmt_with(f, &self.error)?; - write!(f, "\n{stmt}{arrow:>pad$}", pad = loc.column(), arrow = "^") - } else { - loc.fmt_with(f, &self.error) - } - } -} - -impl CompileError { - fn from_codegen(error: rustpython_codegen::error::CodegenError, source: &str) -> Self { - let statement = get_statement(source, error.location); - Self { - body: error.into(), - statement, - } - } - fn from_parse(error: rustpython_parser::error::ParseError, source: &str) -> Self { - let error: rustpython_compiler_core::BaseError = error.into(); - let statement = get_statement(source, error.location); - Self { - body: error.into(), - statement, - } - } - fn from_symtable( - error: symboltable::SymbolTableError, - source: &str, - source_path: String, - ) -> Self { - Self::from_codegen(error.into_codegen_error(source_path), source) +fn error_from_parse(error: rustpython_parser::error::ParseError, source: &str) -> CompileError { + let error: CompileErrorBody = error.into(); + let statement = get_statement(source, error.location); + CompileError { + body: error.into(), + statement, } } @@ -85,15 +53,14 @@ pub fn compile( }; let mut ast = match parser::parse(source, parser_mode, &source_path) { Ok(x) => x, - Err(e) => return Err(CompileError::from_parse(e, source)), + Err(e) => return Err(error_from_parse(e, source)), }; if opts.optimize > 0 { ast = ConstantOptimizer::new() .fold_mod(ast) .unwrap_or_else(|e| match e {}); } - compile::compile_top(&ast, source_path, mode, opts) - .map_err(|e| CompileError::from_codegen(e, source)) + compile::compile_top(&ast, source_path, mode, opts).map_err(|e| error_from_codegen(e, source)) } pub fn compile_symtable( @@ -101,7 +68,7 @@ pub fn compile_symtable( mode: compile::Mode, source_path: &str, ) -> Result { - let parse_err = |e| CompileError::from_parse(e, source); + let parse_err = |e| error_from_parse(e, source); let res = match mode { compile::Mode::Exec | compile::Mode::Single | compile::Mode::BlockExpr => { let ast = parser::parse_program(source, source_path).map_err(parse_err)?; @@ -112,7 +79,7 @@ pub fn compile_symtable( symboltable::SymbolTable::scan_expr(&expr) } }; - res.map_err(|e| CompileError::from_symtable(e, source, source_path.to_owned())) + res.map_err(|e| error_from_codegen(e.into_codegen_error(source_path.to_owned()), source)) } fn get_statement(source: &str, loc: Location) -> Option { diff --git a/src/shell.rs b/src/shell.rs index 955dd33e9..f1010f5ee 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,10 +1,10 @@ mod helper; use rustpython_parser::error::{LexicalErrorType, ParseErrorType}; -use rustpython_vm::readline::{Readline, ReadlineResult}; use rustpython_vm::{ builtins::PyBaseExceptionRef, compile::{self, CompileError, CompileErrorBody, CompileErrorType}, + readline::{Readline, ReadlineResult}, scope::Scope, AsObject, PyResult, VirtualMachine, };