1
0

Simplify errors; Make another pretty error type

This commit is contained in:
Jeff 2024-02-16 17:56:36 -05:00
parent ee4f37080e
commit bda217135e
34 changed files with 74 additions and 80 deletions

View File

@ -15,7 +15,7 @@ pub struct As {
impl AbstractTree for As {
fn from_syntax(node: Node, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "as", node)?;
SyntaxError::expect_syntax_node("as", node)?;
let expression_node = node.child(0).unwrap();
let expression = Expression::from_syntax(expression_node, source, context)?;

View File

@ -23,7 +23,7 @@ impl AbstractTree for Assignment {
source: &str,
context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "assignment", syntax_node)?;
SyntaxError::expect_syntax_node("assignment", syntax_node)?;
let child_count = syntax_node.child_count();

View File

@ -16,10 +16,10 @@ pub enum AssignmentOperator {
impl AbstractTree for AssignmentOperator {
fn from_syntax(
node: SyntaxNode,
source: &str,
_source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "assignment_operator", node)?;
SyntaxError::expect_syntax_node("assignment_operator", node)?;
let operator_node = node.child(0).unwrap();
let operator = match operator_node.kind() {
@ -30,8 +30,7 @@ impl AbstractTree for AssignmentOperator {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "=, += or -=".to_string(),
actual: operator_node.kind().to_string(),
location: operator_node.start_position(),
relevant_source: source[operator_node.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -34,7 +34,7 @@ impl Block {
impl AbstractTree for Block {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "block", node)?;
SyntaxError::expect_syntax_node("block", node)?;
let first_child = node.child(0).unwrap();
let is_async = first_child.kind() == "async";

View File

@ -21,7 +21,7 @@ impl AbstractTree for Command {
source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "command", node)?;
SyntaxError::expect_syntax_node("command", node)?;
let command_text_node = node.child(1).unwrap();
let command_text = source[command_text_node.byte_range()].to_string();

View File

@ -31,7 +31,7 @@ impl EnumDefinition {
impl AbstractTree for EnumDefinition {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "enum_definition", node)?;
SyntaxError::expect_syntax_node("enum_definition", node)?;
let identifier_node = node.child(1).unwrap();
let identifier = Identifier::from_syntax(identifier_node, source, context)?;

View File

@ -29,7 +29,7 @@ impl EnumPattern {
impl AbstractTree for EnumPattern {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "enum_pattern", node)?;
SyntaxError::expect_syntax_node("enum_pattern", node)?;
let enum_name_node = node.child(0).unwrap();
let name = Identifier::from_syntax(enum_name_node, source, context)?;

View File

@ -30,7 +30,7 @@ impl AbstractTree for Expression {
source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "expression", node)?;
SyntaxError::expect_syntax_node("expression", node)?;
let child = if node.child(0).unwrap().is_named() {
node.child(0).unwrap()
@ -56,8 +56,7 @@ impl AbstractTree for Expression {
expected: "value, identifier, index, math, logic, function call, as or command"
.to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -22,7 +22,7 @@ pub struct For {
impl AbstractTree for For {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "for", node)?;
SyntaxError::expect_syntax_node("for", node)?;
let for_node = node.child(0).unwrap();
let is_async = match for_node.kind() {
@ -32,8 +32,7 @@ impl AbstractTree for For {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "for or async for".to_string(),
actual: for_node.kind().to_string(),
location: for_node.start_position(),
relevant_source: source[for_node.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -32,7 +32,7 @@ impl FunctionCall {
impl AbstractTree for FunctionCall {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "function_call", node)?;
SyntaxError::expect_syntax_node("function_call", node)?;
let function_node = node.child(0).unwrap();
let function_expression = FunctionExpression::from_syntax(function_node, source, context)?;

View File

@ -16,7 +16,7 @@ pub enum FunctionExpression {
impl AbstractTree for FunctionExpression {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "function_expression", node)?;
SyntaxError::expect_syntax_node("function_expression", node)?;
let first_child = node.child(0).unwrap();
let child = if first_child.is_named() {
@ -39,8 +39,7 @@ impl AbstractTree for FunctionExpression {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "identifier, function call, value or index".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -53,7 +53,7 @@ impl FunctionNode {
impl AbstractTree for FunctionNode {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "function", node)?;
SyntaxError::expect_syntax_node("function", node)?;
let child_count = node.child_count();
let mut parameters = Vec::new();

View File

@ -50,7 +50,7 @@ impl AbstractTree for Identifier {
source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "identifier", node)?;
SyntaxError::expect_syntax_node("identifier", node)?;
let text = &source[node.byte_range()];

View File

@ -18,7 +18,7 @@ pub struct Index {
impl AbstractTree for Index {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "index", node)?;
SyntaxError::expect_syntax_node("index", node)?;
let collection_node = node.child(0).unwrap();
let collection = IndexExpression::from_syntax(collection_node, source, context)?;

View File

@ -15,7 +15,7 @@ pub struct IndexAssignment {
impl AbstractTree for IndexAssignment {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "index_assignment", node)?;
SyntaxError::expect_syntax_node("index_assignment", node)?;
let index_node = node.child(0).unwrap();
let index = Index::from_syntax(index_node, source, context)?;

View File

@ -16,7 +16,7 @@ pub enum IndexExpression {
impl AbstractTree for IndexExpression {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "index_expression", node)?;
SyntaxError::expect_syntax_node("index_expression", node)?;
let first_child = node.child(0).unwrap();
let child = if first_child.is_named() {
@ -40,8 +40,7 @@ impl AbstractTree for IndexExpression {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "value, identifier, index or function call".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -15,7 +15,7 @@ pub struct Logic {
impl AbstractTree for Logic {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "logic", node)?;
SyntaxError::expect_syntax_node("logic", node)?;
let first_node = node.child(0).unwrap();
let (left_node, operator_node, right_node) = {

View File

@ -20,10 +20,10 @@ pub enum LogicOperator {
impl AbstractTree for LogicOperator {
fn from_syntax(
node: SyntaxNode,
source: &str,
_source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "logic_operator", node)?;
SyntaxError::expect_syntax_node("logic_operator", node)?;
let operator_node = node.child(0).unwrap();
let operator = match operator_node.kind() {
@ -39,8 +39,7 @@ impl AbstractTree for LogicOperator {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "==, !=, &&, ||, >, <, >= or <=".to_string(),
actual: operator_node.kind().to_string(),
location: operator_node.start_position(),
relevant_source: source[operator_node.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -23,7 +23,7 @@ impl MapNode {
impl AbstractTree for MapNode {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "map", node)?;
SyntaxError::expect_syntax_node("map", node)?;
let mut properties = BTreeMap::new();
let mut current_identifier = None;

View File

@ -20,7 +20,7 @@ pub struct Match {
impl AbstractTree for Match {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "match", node)?;
SyntaxError::expect_syntax_node("match", node)?;
let matcher_node = node.child(1).unwrap();
let matcher = Expression::from_syntax(matcher_node, source, context)?;

View File

@ -15,7 +15,7 @@ pub enum MatchPattern {
impl AbstractTree for MatchPattern {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "match_pattern", node)?;
SyntaxError::expect_syntax_node("match_pattern", node)?;
let child = node.child(0).unwrap();
let pattern = match child.kind() {
@ -28,8 +28,7 @@ impl AbstractTree for MatchPattern {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "enum pattern or value".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -18,7 +18,7 @@ pub struct Math {
impl AbstractTree for Math {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "math", node)?;
SyntaxError::expect_syntax_node("math", node)?;
let left_node = node.child(0).unwrap();
let left = Expression::from_syntax(left_node, source, context)?;

View File

@ -17,7 +17,7 @@ pub enum MathOperator {
impl AbstractTree for MathOperator {
fn from_syntax(
node: SyntaxNode,
source: &str,
_source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
let operator_node = node.child(0).unwrap();
@ -31,8 +31,7 @@ impl AbstractTree for MathOperator {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "+, -, *, / or %".to_string(),
actual: operator_node.kind().to_string(),
location: operator_node.start_position(),
relevant_source: source[operator_node.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -85,7 +85,7 @@ pub struct Root {
// top-level statements in the tree.
impl AbstractTree for Root {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "root", node)?;
SyntaxError::expect_syntax_node("root", node)?;
let statement_count = node.child_count();
let mut statements = Vec::with_capacity(statement_count);

View File

@ -25,7 +25,7 @@ impl AbstractTree for Statement {
source: &str,
_context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "statement", node)?;
SyntaxError::expect_syntax_node("statement", node)?;
let first_child = node.child(0).unwrap();
let mut is_return = first_child.kind() == "return";
@ -83,7 +83,7 @@ enum StatementKind {
impl AbstractTree for StatementKind {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "statement_kind", node)?;
SyntaxError::expect_syntax_node("statement_kind", node)?;
let child = node.child(0).unwrap();
@ -119,8 +119,7 @@ impl AbstractTree for StatementKind {
expected:
"assignment, index assignment, expression, type_definition, block, return, if...else, while, for or match".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
}),
}
}

View File

@ -44,7 +44,7 @@ impl StructDefinition {
impl AbstractTree for StructDefinition {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "struct_definition", node)?;
SyntaxError::expect_syntax_node("struct_definition", node)?;
let name_node = node.child(1).unwrap();
let name = Identifier::from_syntax(name_node, source, context)?;

View File

@ -147,7 +147,7 @@ impl AbstractTree for Type {
_source: &str,
context: &Context,
) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(_source, "type", node)?;
SyntaxError::expect_syntax_node("type", node)?;
let type_node = node.child(0).unwrap();
@ -207,8 +207,7 @@ impl AbstractTree for Type {
return Err(SyntaxError::UnexpectedSyntaxNode {
expected: "any, bool, float, int, num, str, custom type, (, [ or {".to_string(),
actual: type_node.kind().to_string(),
location: type_node.start_position(),
relevant_source: _source[type_node.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -23,7 +23,7 @@ impl TypeDefinition {
impl AbstractTree for TypeDefinition {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "type_definition", node)?;
SyntaxError::expect_syntax_node("type_definition", node)?;
let child = node.child(0).unwrap();
@ -37,8 +37,7 @@ impl AbstractTree for TypeDefinition {
_ => Err(SyntaxError::UnexpectedSyntaxNode {
expected: "enum or struct definition".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
}),
}
}

View File

@ -26,7 +26,7 @@ impl TypeSpecification {
impl AbstractTree for TypeSpecification {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "type_specification", node)?;
SyntaxError::expect_syntax_node("type_specification", node)?;
let type_node = node.child(1).unwrap();
let r#type = Type::from_syntax(type_node, source, context)?;

View File

@ -32,7 +32,7 @@ pub enum ValueNode {
impl AbstractTree for ValueNode {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "value", node)?;
SyntaxError::expect_syntax_node("value", node)?;
let child = node.child(0).unwrap();
let value_node = match child.kind() {
@ -108,8 +108,7 @@ impl AbstractTree for ValueNode {
"string, integer, float, boolean, range, list, map, option, function, struct or enum"
.to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
position: node.range().into(),
})
}
};

View File

@ -16,7 +16,7 @@ pub struct While {
impl AbstractTree for While {
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
SyntaxError::expect_syntax_node(source, "while", node)?;
SyntaxError::expect_syntax_node("while", node)?;
let expression_node = node.child(1).unwrap();
let expression = Expression::from_syntax(expression_node, source, context)?;

View File

@ -7,6 +7,7 @@ pub(crate) mod rw_lock_error;
mod syntax_error;
mod validation_error;
use colored::Colorize;
use lyneate::Report;
pub use runtime_error::RuntimeError;
pub use syntax_error::SyntaxError;
@ -35,15 +36,33 @@ impl Error {
/// The `source` argument should be the full source code document that was
/// used to create this error.
pub fn create_report(&self, source: &str) -> String {
let markers = if let Error::Syntax(SyntaxError::InvalidSource { source, position }) = self {
let markers = if let Error::Syntax(SyntaxError::InvalidSource { position }) = self {
vec![(
position.start_byte..position.end_byte,
format!(
"Invalid syntax from ({}, {}) to ({}, {}).",
position.start_row,
position.start_column,
position.end_row,
position.end_column,
position.end_row
),
(255, 200, 100),
)]
} else if let Error::Syntax(SyntaxError::UnexpectedSyntaxNode {
expected,
actual,
position,
}) = self
{
vec![(
position.start_byte..position.end_byte,
format!(
"Unexpected syntax from ({}, {}) to ({}, {}). {}",
position.start_row,
position.start_column,
position.end_row,
position.end_column,
format!("Expected {} but got {}.", expected, actual).dimmed(),
),
(255, 100, 100),
)]

View File

@ -1,7 +1,7 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use tree_sitter::{Node as SyntaxNode, Point};
use tree_sitter::Node as SyntaxNode;
use crate::SourcePosition;
@ -11,7 +11,6 @@ use super::rw_lock_error::RwLockError;
pub enum SyntaxError {
/// Invalid user input.
InvalidSource {
source: String,
position: SourcePosition,
},
@ -20,35 +19,25 @@ pub enum SyntaxError {
UnexpectedSyntaxNode {
expected: String,
actual: String,
#[serde(skip)]
location: Point,
relevant_source: String,
position: SourcePosition,
},
}
impl SyntaxError {
pub fn expect_syntax_node(
source: &str,
expected: &str,
actual: SyntaxNode,
) -> Result<(), SyntaxError> {
pub fn expect_syntax_node(expected: &str, actual: SyntaxNode) -> Result<(), SyntaxError> {
log::info!("Converting {} to abstract node", actual.kind());
if expected == actual.kind() {
Ok(())
} else if actual.is_error() {
Err(SyntaxError::InvalidSource {
source: source[actual.byte_range()].to_string(),
position: SourcePosition::from(actual.range()),
})
} else {
Err(SyntaxError::UnexpectedSyntaxNode {
expected: expected.to_string(),
actual: actual.kind().to_string(),
location: actual.start_position(),
relevant_source: source[actual.byte_range()].to_string(),
position: SourcePosition::from(actual.range()),
})
}
}
@ -61,7 +50,7 @@ impl From<RwLockError> for SyntaxError {
}
impl Display for SyntaxError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
todo!()
}
}

View File

@ -35,11 +35,9 @@
//! Ok(Value::Integer(10))
//! );
//! ```
use tree_sitter::{Node as SyntaxNode, Parser, Tree as SyntaxTree, TreeCursor};
use tree_sitter::{Parser, Tree as SyntaxTree};
use crate::{
error::SyntaxError, language, AbstractTree, Context, Error, Format, Root, SourcePosition, Value,
};
use crate::{language, AbstractTree, Context, Error, Format, Root, Value};
/// Interpret the given source code. Returns the value of last statement or the
/// first error encountered.