Move out CompileError to core as generic form

This commit is contained in:
Jeong YunWon committed 2022-08-23 01:30:00 +09:00
1 parent 9aacd144ca
commit d876673546
6 files changed
+54 -56

No files matched your search

Generated
+1
View File
@@ -1801,6 +1801,7 @@ dependencies = [
"num-complex",
"serde",
"static_assertions",
"thiserror",
]
[[package]]
+1
View File
@@ -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"
+29
View File
@@ -58,3 +58,32 @@ impl<T> BaseError<T> {
BaseError::from(self)
}
}
#[derive(Debug, thiserror::Error)]
pub struct CompileError<T> {
pub body: BaseError<T>,
pub statement: Option<String>,
}
impl<T> std::ops::Deref for CompileError<T> {
type Target = BaseError<T>;
fn deref(&self) -> &Self::Target {
&self.body
}
}
impl<T> std::fmt::Display for CompileError<T>
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)
}
}
}
+1 -1
View File
@@ -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;
+21 -54
View File
@@ -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<CompileErrorType>;
pub type CompileError = rustpython_compiler_core::CompileError<CompileErrorType>;
#[derive(Debug, thiserror::Error)]
pub struct CompileError {
pub body: CompileErrorBody,
pub statement: Option<String>,
}
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<ParseErrorType> = 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<ParseErrorType> = 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<symboltable::SymbolTable, CompileError> {
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<String> {
+1 -1
View File
@@ -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,
};