mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-19 19:15:43 +00:00
Split the ast from the parser, remove compiler dep on parser
This commit is contained in:
parent
3f88b08aaa
commit
e9095a741d
5 changed files with 153 additions and 225 deletions
112
src/error.rs
112
src/error.rs
|
@ -1,34 +1,17 @@
|
|||
use rustpython_parser::error::{LexicalErrorType, ParseError, ParseErrorType};
|
||||
use rustpython_parser::location::Location;
|
||||
use rustpython_parser::token::Tok;
|
||||
use rustpython_ast::Location;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompileError {
|
||||
pub statement: Option<String>,
|
||||
pub error: CompileErrorType,
|
||||
pub location: Location,
|
||||
pub source_path: String,
|
||||
}
|
||||
|
||||
impl CompileError {
|
||||
pub fn from_parse_error(parse_error: ParseError, source_path: String) -> Self {
|
||||
Self {
|
||||
statement: None,
|
||||
error: CompileErrorType::Parse(parse_error.error),
|
||||
location: parse_error.location,
|
||||
source_path,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_statement_info(&mut self, statement: String) {
|
||||
self.statement = Some(statement);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum CompileErrorType {
|
||||
/// Invalid assignment, cannot store value in target.
|
||||
Assign(&'static str),
|
||||
|
@ -36,8 +19,6 @@ pub enum CompileErrorType {
|
|||
Delete(&'static str),
|
||||
/// Expected an expression got a statement
|
||||
ExpectExpr,
|
||||
/// Parser error
|
||||
Parse(ParseErrorType),
|
||||
SyntaxError(String),
|
||||
/// Multiple `*` detected
|
||||
MultipleStarArgs,
|
||||
|
@ -57,74 +38,43 @@ pub enum CompileErrorType {
|
|||
InvalidFutureFeature(String),
|
||||
}
|
||||
|
||||
impl CompileError {
|
||||
pub fn is_indentation_error(&self) -> bool {
|
||||
if let CompileErrorType::Parse(parse) = &self.error {
|
||||
match parse {
|
||||
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => true,
|
||||
ParseErrorType::UnrecognizedToken(token, expected) => {
|
||||
*token == Tok::Indent || expected.clone() == Some("Indent".to_owned())
|
||||
}
|
||||
_ => false,
|
||||
impl fmt::Display for CompileErrorType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CompileErrorType::Assign(target) => write!(f, "can't assign to {}", target),
|
||||
CompileErrorType::Delete(target) => write!(f, "can't delete {}", target),
|
||||
CompileErrorType::ExpectExpr => write!(f, "Expecting expression, got statement"),
|
||||
CompileErrorType::SyntaxError(err) => write!(f, "{}", err.as_str()),
|
||||
CompileErrorType::MultipleStarArgs => {
|
||||
write!(f, "two starred expressions in assignment")
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_tab_error(&self) -> bool {
|
||||
if let CompileErrorType::Parse(parse) = &self.error {
|
||||
if let ParseErrorType::Lexical(lex) = parse {
|
||||
if let LexicalErrorType::TabError = lex {
|
||||
return true;
|
||||
}
|
||||
CompileErrorType::InvalidStarExpr => write!(f, "can't use starred expression here"),
|
||||
CompileErrorType::InvalidBreak => write!(f, "'break' outside loop"),
|
||||
CompileErrorType::InvalidContinue => write!(f, "'continue' outside loop"),
|
||||
CompileErrorType::InvalidReturn => write!(f, "'return' outside function"),
|
||||
CompileErrorType::InvalidYield => write!(f, "'yield' outside function"),
|
||||
CompileErrorType::InvalidYieldFrom => write!(f, "'yield from' outside function"),
|
||||
CompileErrorType::InvalidAwait => write!(f, "'await' outside async function"),
|
||||
CompileErrorType::AsyncYieldFrom => write!(f, "'yield from' inside async function"),
|
||||
CompileErrorType::AsyncReturnValue => {
|
||||
write!(f, "'return' with value inside async generator")
|
||||
}
|
||||
CompileErrorType::InvalidFuturePlacement => write!(
|
||||
f,
|
||||
"from __future__ imports must occur at the beginning of the file"
|
||||
),
|
||||
CompileErrorType::InvalidFutureFeature(feat) => {
|
||||
write!(f, "future feature {} is not defined", feat)
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for CompileErrorType {}
|
||||
|
||||
impl fmt::Display for CompileError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let error_desc = match &self.error {
|
||||
CompileErrorType::Assign(target) => format!("can't assign to {}", target),
|
||||
CompileErrorType::Delete(target) => format!("can't delete {}", target),
|
||||
CompileErrorType::ExpectExpr => "Expecting expression, got statement".to_owned(),
|
||||
CompileErrorType::Parse(err) => err.to_string(),
|
||||
CompileErrorType::SyntaxError(err) => err.to_string(),
|
||||
CompileErrorType::MultipleStarArgs => {
|
||||
"two starred expressions in assignment".to_owned()
|
||||
}
|
||||
CompileErrorType::InvalidStarExpr => "can't use starred expression here".to_owned(),
|
||||
CompileErrorType::InvalidBreak => "'break' outside loop".to_owned(),
|
||||
CompileErrorType::InvalidContinue => "'continue' outside loop".to_owned(),
|
||||
CompileErrorType::InvalidReturn => "'return' outside function".to_owned(),
|
||||
CompileErrorType::InvalidYield => "'yield' outside function".to_owned(),
|
||||
CompileErrorType::InvalidYieldFrom => "'yield from' outside function".to_owned(),
|
||||
CompileErrorType::InvalidAwait => "'await' outside async function".to_owned(),
|
||||
CompileErrorType::AsyncYieldFrom => "'yield from' inside async function".to_owned(),
|
||||
CompileErrorType::AsyncReturnValue => {
|
||||
"'return' with value inside async generator".to_owned()
|
||||
}
|
||||
CompileErrorType::InvalidFuturePlacement => {
|
||||
"from __future__ imports must occur at the beginning of the file".to_owned()
|
||||
}
|
||||
CompileErrorType::InvalidFutureFeature(feat) => {
|
||||
format!("future feature {} is not defined", feat)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(statement) = &self.statement {
|
||||
if self.location.column() > 0 {
|
||||
if let Some(line) = statement.lines().nth(self.location.row() - 1) {
|
||||
// visualize the error, when location and statement are provided
|
||||
return write!(f, "{}", self.location.visualize(line, &error_desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print line number
|
||||
write!(f, "{} at {}", error_desc, self.location)
|
||||
write!(f, "{} at {}", self.error, self.location)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue