mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Move out CompileError to core as generic form
This commit is contained in:
1 parent
9aacd144ca
commit
d876673546
6 files changed
+54
-56
No files matched your search
Generated
+1
@@ -1801,6 +1801,7 @@ dependencies = [
|
||||
"num-complex",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user