error and error message for deprecated test syntax, fmt, clean up

This commit is contained in:
gluaxspeed 2021-01-25 15:12:10 -05:00
parent 87bd041620
commit 29ff3c90b6
17 changed files with 161 additions and 21 deletions

1
Cargo.lock generated
View File

@ -1331,6 +1331,7 @@ dependencies = [
"pest",
"serde",
"serde_json",
"thiserror",
]
[[package]]

View File

@ -47,6 +47,9 @@ version = "1.0"
[dependencies.serde_json]
version = "1.0"
[dependencies.thiserror]
version = "1.0"
[dev-dependencies.criterion]
version = "0.3"

View File

@ -36,7 +36,6 @@ pub fn load_annotation(
match ast_definition {
Definition::Import(_) => unimplemented!("annotated imports are not supported yet"),
Definition::Circuit(_) => unimplemented!("annotated circuits are not supported yet"),
// TODO need someone to take functions annotated with @test to be moved from function to tests.
Definition::Function(function) => match ast_annotation.name {
AnnotationName::Test(_) => {
let ident = Identifier::from(function.identifier.clone());
@ -49,6 +48,7 @@ pub fn load_annotation(
load_annotated_test(test, ast_annotation, tests);
}
},
Definition::Deprecated(_) => {}
Definition::Annotated(_) => unimplemented!("nested annotations are not supported yet"),
}
}

View File

@ -0,0 +1,50 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_grammar::definitions::Deprecated;
use crate::{Error as FormattedError, Span};
use std::path::Path;
#[derive(Debug, Error)]
pub enum DeprecatedError {
#[error("{}", _0)]
Error(#[from] FormattedError),
}
impl DeprecatedError {
pub fn set_path(&mut self, path: &Path) {
match self {
DeprecatedError::Error(error) => error.set_path(path),
}
}
fn new_from_span(message: String, span: Span) -> Self {
DeprecatedError::Error(FormattedError::new_from_span(message, span))
}
}
impl<'ast> From<Deprecated<'ast>> for DeprecatedError {
fn from(deprecated: Deprecated<'ast>) -> Self {
match deprecated {
Deprecated::TestFunction(test_function) => DeprecatedError::new_from_span(
"\"test function...\" is deprecated. Did you mean @test decorator?".to_string(),
Span::from(test_function.span.clone()),
),
}
}
}

View File

@ -14,5 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
pub mod deprecated;
pub use deprecated::*;
pub mod error;
pub use error::*;

View File

@ -19,6 +19,8 @@
//! This module contains the [`Ast`] type, a wrapper around the [`Program`] type.
//! The [`Ast`] type is intended to be parsed and modified by different passes
//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`Ast`].
#[macro_use]
extern crate thiserror;
pub mod annotation;
pub use self::annotation::*;
@ -74,10 +76,10 @@ pub struct Ast {
impl Ast {
/// Creates a new ast from a given program name and grammar tree.
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Self {
Self {
ast: Program::from(program_name, ast.as_repr()),
}
pub fn new<'ast>(program_name: &str, ast: &Grammar<'ast>) -> Result<Self, DeprecatedError> {
Ok(Self {
ast: Program::from(program_name, ast.as_repr())?,
})
}
/// Returns a reference to the inner program ast representation.

View File

@ -17,7 +17,16 @@
//! A Leo program consists of import, circuit, and function definitions.
//! Each defined type consists of ast statements and expressions.
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
use crate::{
load_annotation,
Circuit,
DeprecatedError,
Function,
FunctionInput,
Identifier,
ImportStatement,
TestFunction,
};
use leo_grammar::{definitions::Definition, files::File};
use indexmap::IndexMap;
@ -37,7 +46,7 @@ const MAIN_FUNCTION_NAME: &str = "main";
impl<'ast> Program {
//! Logic to convert from an abstract syntax tree (ast) representation to a Leo program.
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Self {
pub fn from(program_name: &str, program_ast: &File<'ast>) -> Result<Self, DeprecatedError> {
let mut imports = vec![];
let mut circuits = IndexMap::new();
let mut functions = IndexMap::new();
@ -48,10 +57,14 @@ impl<'ast> Program {
.definitions
.to_owned()
.into_iter()
.for_each(|definition| match definition {
Definition::Import(import) => imports.push(ImportStatement::from(import)),
.find_map::<Result<(), _>, _>(|definition| match definition {
Definition::Import(import) => {
imports.push(ImportStatement::from(import));
None
}
Definition::Circuit(circuit) => {
circuits.insert(Identifier::from(circuit.identifier.clone()), Circuit::from(circuit));
None
}
Definition::Function(function_def) => {
let function = Function::from(function_def);
@ -59,6 +72,16 @@ impl<'ast> Program {
expected_input = function.input.clone();
}
functions.insert(function.identifier.clone(), function);
None
}
Definition::Deprecated(deprecated) => {
// 1. convert pest span to ast span.
// ast source common span
// new from span -> don't call direcrtly
// create separate file for error warnings
// "\"test function\" is deprecated. Did you mean @test?"
Some(Err(DeprecatedError::from(deprecated)))
}
Definition::Annotated(annotated_definition) => {
load_annotation(
@ -69,17 +92,20 @@ impl<'ast> Program {
&mut tests,
&mut expected_input,
);
}
});
Self {
None
}
})
.transpose()?;
Ok(Self {
name: program_name.to_string(),
expected_input,
imports,
circuits,
functions,
tests,
}
})
}
}

View File

@ -29,7 +29,7 @@ fn to_ast(program_filepath: &Path) -> Ast {
let ast = Grammar::new(&program_filepath, &program_string).unwrap();
// Parses the pest ast and constructs a Leo ast.
Ast::new("leo_tree", &ast)
Ast::new("leo_tree", &ast).unwrap()
}
#[test]

View File

@ -184,7 +184,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
})?;
// Construct the core ast from the pest ast.
let core_ast = Ast::new(&self.package_name, &pest_ast);
let core_ast = Ast::new(&self.package_name, &pest_ast)?;
// Store the main program file.
self.program = core_ast.into_repr();
@ -241,7 +241,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
let package_name = &self.package_name;
// Construct the core ast from the pest ast.
let core_ast = Ast::new(package_name, &ast);
let core_ast = Ast::new(package_name, &ast)?;
// Store the main program file.
self.program = core_ast.into_repr();

View File

@ -15,6 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError};
use leo_ast::DeprecatedError;
use leo_grammar::ParserError;
use leo_imports::ImportParserError;
use leo_input::InputParserError;
@ -27,6 +28,9 @@ use std::path::{Path, PathBuf};
#[derive(Debug, Error)]
pub enum CompilerError {
#[error("{}", _0)]
DeprecatedError(#[from] DeprecatedError),
#[error("{}", _0)]
ImportError(#[from] ImportError),

View File

@ -14,7 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, circuits::Circuit, definitions::AnnotatedDefinition, functions::Function, imports::Import};
use crate::{
ast::Rule,
circuits::Circuit,
definitions::{AnnotatedDefinition, Deprecated},
functions::Function,
imports::Import,
};
use pest_ast::FromPest;
use serde::Serialize;
@ -26,4 +32,5 @@ pub enum Definition<'ast> {
Import(Import<'ast>),
Circuit(Circuit<'ast>),
Function(Function<'ast>),
Deprecated(Deprecated<'ast>),
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, functions::TestFunction};
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::deprecated))]
pub enum Deprecated<'ast> {
TestFunction(TestFunction<'ast>),
}

View File

@ -19,3 +19,6 @@ pub use annotated_definition::*;
pub mod definition;
pub use definition::*;
pub mod deprecated;
pub use deprecated::*;

View File

@ -14,14 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{functions::Function, SpanDef};
use crate::{ast::Rule, functions::Function, SpanDef};
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, PartialEq, Serialize)]
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::test_function))]
pub struct TestFunction<'ast> {
pub function: Function<'ast>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}

View File

@ -12,6 +12,12 @@ definition = {
| import
| circuit
| function
| deprecated
}
// but then in the struct ffor this... I need to explicitly put all the types there.
deprecated = {
test_function
}
// Declared in definitions/annotated_definition.rs
@ -409,6 +415,9 @@ statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
// Declared in statements/expression_statement.rs
statement_expression = { expression ~ LINE_END }
// Decalred in functions/test_function.rs
test_function = { "test" ~ function }
// Declared in statements/for_statement.rs
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ block }

View File

@ -13,13 +13,16 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use leo_ast::{Error as FormattedError, Identifier, Span};
use leo_ast::{DeprecatedError, Error as FormattedError, Identifier, Span};
use leo_grammar::ParserError;
use std::{io, path::Path};
#[derive(Debug, Error)]
pub enum ImportParserError {
#[error("{}", _0)]
DeprecatedError(#[from] DeprecatedError),
#[error("{}", _0)]
Error(#[from] FormattedError),

View File

@ -55,7 +55,7 @@ fn parse_import_file(package: &DirEntry, span: &Span) -> Result<Program, ImportP
let ast = &Grammar::new(&file_path, &program_string)?;
// Build the package Leo syntax tree from the package abstract syntax tree.
Ok(Program::from(&file_name, ast.as_repr()))
Ok(Program::from(&file_name, ast.as_repr())?)
}
impl ImportParser {