mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-28 01:01:53 +03:00
convert identifer to span with error
This commit is contained in:
parent
c54f1817ce
commit
6922d5dd73
@ -47,7 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Check global scope (function and circuit names)
|
||||
value.clone()
|
||||
} else {
|
||||
return Err(ExpressionError::UndefinedIdentifier(unresolved_identifier.to_string()));
|
||||
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
||||
};
|
||||
|
||||
result_value.resolve_type(expected_types)?;
|
||||
|
@ -1,14 +1,13 @@
|
||||
use crate::errors::{BooleanError, FieldError, FunctionError, GroupError, ValueError};
|
||||
use leo_types::IntegerError;
|
||||
use crate::errors::{BooleanError, Error, FieldError, FunctionError, GroupError, ValueError};
|
||||
use leo_types::{Identifier, IntegerError, Span};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use std::num::ParseIntError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ExpressionError {
|
||||
// Identifiers
|
||||
#[error("Identifier \"{}\" not found", _0)]
|
||||
UndefinedIdentifier(String),
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] Error),
|
||||
|
||||
// Types
|
||||
#[error("{}", _0)]
|
||||
@ -87,3 +86,15 @@ pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
||||
impl ExpressionError {
|
||||
fn new_from_span(message: String, span: Span) -> Self {
|
||||
ExpressionError::Error(Error::new_from_span(message, span))
|
||||
}
|
||||
|
||||
pub fn undefined_identifier(identifier: Identifier) -> Self {
|
||||
let message = format!("cannot find value `{}` in this scope", identifier.name);
|
||||
|
||||
Self::new_from_span(message, identifier.span)
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,12 @@ impl fmt::Display for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error() {
|
||||
let err = Error {
|
||||
@ -110,26 +116,3 @@ fn test_error() {
|
||||
.join("\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_span() {
|
||||
use pest::Span as AstSpan;
|
||||
|
||||
let text = "aaaa";
|
||||
let ast_span = AstSpan::new(text, 0, text.len()).unwrap();
|
||||
let span = Span::from(ast_span);
|
||||
let err = Error::new_from_span("test message".to_string(), span);
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", err),
|
||||
vec![
|
||||
" --> 1:0",
|
||||
" |",
|
||||
" 1 | aaaa",
|
||||
" | ^^^^",
|
||||
" |",
|
||||
" = test message",
|
||||
]
|
||||
.join("\n")
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{get_error, parse_program};
|
||||
use leo_ast::ParserError;
|
||||
use leo_compiler::errors::CompilerError;
|
||||
use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError};
|
||||
use leo_inputs::InputParserError;
|
||||
|
||||
#[test]
|
||||
@ -21,7 +21,25 @@ fn test_undefined() {
|
||||
|
||||
let error = get_error(program);
|
||||
|
||||
println!("{}", error);
|
||||
match error {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::Error(error),
|
||||
))) => {
|
||||
assert_eq!(
|
||||
format!("{}", error),
|
||||
vec![
|
||||
" --> 2:10",
|
||||
" |",
|
||||
" 2 | return a",
|
||||
" | ^",
|
||||
" |",
|
||||
" = cannot find value `a` in this scope",
|
||||
]
|
||||
.join("\n")
|
||||
);
|
||||
}
|
||||
_ => panic!("expected an undefined identifier error"),
|
||||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::Span;
|
||||
use leo_ast::common::Identifier as AstIdentifier;
|
||||
|
||||
use std::fmt;
|
||||
@ -6,6 +7,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
@ -16,7 +18,10 @@ impl Identifier {
|
||||
|
||||
impl<'ast> From<AstIdentifier<'ast>> for Identifier {
|
||||
fn from(identifier: AstIdentifier<'ast>) -> Self {
|
||||
Self { name: identifier.value }
|
||||
Self {
|
||||
name: identifier.value,
|
||||
span: Span::from(identifier.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use pest::Span as AstSpan;
|
||||
use pest::{Position, Span as AstSpan};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Span {
|
||||
@ -14,13 +14,50 @@ pub struct Span {
|
||||
|
||||
impl<'ast> From<AstSpan<'ast>> for Span {
|
||||
fn from(span: AstSpan<'ast>) -> Self {
|
||||
let line_col = span.start_pos().line_col();
|
||||
|
||||
let mut text = " ".to_string();
|
||||
text.push_str(span.start_pos().line_of().trim_end());
|
||||
Self {
|
||||
text: span.as_str().to_string(),
|
||||
line: line_col.0,
|
||||
start: span.start(),
|
||||
end: span.end(),
|
||||
text,
|
||||
line: span.start_pos().line_col().0,
|
||||
start: find_line_start(&span.start_pos()),
|
||||
end: find_line_end(&span.end_pos()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_line_start(pos: &Position) -> usize {
|
||||
let input = pos.line_of();
|
||||
if input.is_empty() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Position's pos is always a UTF-8 border.
|
||||
let start = input
|
||||
.char_indices()
|
||||
.rev()
|
||||
.skip_while(|&(i, _)| i >= pos.pos())
|
||||
.find(|&(_, c)| c == '\n');
|
||||
match start {
|
||||
Some((i, _)) => i,
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_line_end(pos: &Position) -> usize {
|
||||
let input = pos.line_of();
|
||||
if input.is_empty() {
|
||||
0
|
||||
} else if pos.pos() == input.len() - 1 {
|
||||
input.len()
|
||||
} else {
|
||||
// Position's pos is always a UTF-8 border.
|
||||
let end = input
|
||||
.char_indices()
|
||||
.skip_while(|&(i, _)| i < pos.pos())
|
||||
.find(|&(_, c)| c == '\n');
|
||||
match end {
|
||||
Some((i, _)) => i,
|
||||
None => input.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user