mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 02:24:15 +03:00
use import parser errors in compiler
This commit is contained in:
parent
22422c1b55
commit
d54749145b
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -1236,6 +1236,7 @@ dependencies = [
|
||||
"leo-ast",
|
||||
"leo-core",
|
||||
"leo-gadgets",
|
||||
"leo-imports",
|
||||
"leo-input",
|
||||
"leo-package",
|
||||
"leo-state",
|
||||
@ -1291,8 +1292,10 @@ dependencies = [
|
||||
name = "leo-imports"
|
||||
version = "1.0.3"
|
||||
dependencies = [
|
||||
"leo-ast",
|
||||
"leo-typed",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -29,6 +29,10 @@ version = "1.0.3"
|
||||
path = "../gadgets"
|
||||
version = "1.0.3"
|
||||
|
||||
[dependencies.leo-imports]
|
||||
path = "../imports"
|
||||
version = "1.0.3"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.0.3"
|
||||
|
@ -20,11 +20,11 @@ use crate::{
|
||||
constraints::{generate_constraints, generate_test_constraints},
|
||||
errors::CompilerError,
|
||||
GroupType,
|
||||
ImportParser,
|
||||
OutputBytes,
|
||||
OutputFile,
|
||||
};
|
||||
use leo_ast::LeoAst;
|
||||
use leo_imports::ImportParser;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_state::verify_local_data_commitment;
|
||||
|
@ -22,14 +22,14 @@ use crate::{
|
||||
ConstrainedProgram,
|
||||
ConstrainedValue,
|
||||
GroupType,
|
||||
ImportParser,
|
||||
OutputBytes,
|
||||
OutputFile,
|
||||
};
|
||||
use leo_typed::{Input, Program};
|
||||
|
||||
use leo_imports::ImportParser;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_typed::{Input, Program};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSystem, TestConstraintSystem},
|
||||
|
@ -21,8 +21,8 @@ use crate::{
|
||||
program::{new_scope, ConstrainedProgram},
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
ImportParser,
|
||||
};
|
||||
use leo_imports::ImportParser;
|
||||
use leo_typed::Program;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use crate::errors::{FunctionError, ImportError, OutputBytesError, OutputFileError};
|
||||
use leo_ast::ParserError;
|
||||
use leo_imports::ImportParserError;
|
||||
use leo_input::InputParserError;
|
||||
use leo_state::LocalDataVerificationError;
|
||||
|
||||
@ -27,6 +28,9 @@ pub enum CompilerError {
|
||||
#[error("{}", _0)]
|
||||
ImportError(#[from] ImportError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportParserError(#[from] ImportParserError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
InputParserError(#[from] InputParserError),
|
||||
|
||||
|
@ -14,7 +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/>.
|
||||
|
||||
use crate::{errors::ImportError, imported_symbols::ImportedSymbols, ConstrainedProgram, GroupType, ImportParser};
|
||||
use crate::{errors::ImportError, imported_symbols::ImportedSymbols, ConstrainedProgram, GroupType};
|
||||
use leo_imports::ImportParser;
|
||||
use leo_typed::Import;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
|
@ -17,9 +17,16 @@ include = ["Cargo.toml", "src", "README.md", "LICENSE.md" ]
|
||||
license = "GPL-3.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "../ast"
|
||||
version = "1.0.3"
|
||||
|
||||
[dependencies.leo-typed]
|
||||
path = "../typed"
|
||||
version = "1.0.3"
|
||||
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.tracing]
|
||||
version = "0.1"
|
92
imports/src/errors/import_parser.rs
Normal file
92
imports/src/errors/import_parser.rs
Normal file
@ -0,0 +1,92 @@
|
||||
// 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_ast::ParserError;
|
||||
use leo_typed::{Error as FormattedError, Identifier, Span};
|
||||
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ImportParserError {
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ParserError(#[from] ParserError),
|
||||
}
|
||||
|
||||
impl ImportParserError {
|
||||
fn new_from_span(message: String, span: Span) -> Self {
|
||||
ImportParserError::Error(FormattedError::new_from_span(message, span))
|
||||
}
|
||||
|
||||
fn new_from_span_with_path(message: String, span: Span, path: PathBuf) -> Self {
|
||||
ImportParserError::Error(FormattedError::new_from_span_with_path(message, span, path))
|
||||
}
|
||||
|
||||
pub fn conflicting_imports(identifier: Identifier) -> Self {
|
||||
let message = format!("conflicting imports found for `{}`", identifier.name);
|
||||
|
||||
Self::new_from_span(message, identifier.span)
|
||||
}
|
||||
|
||||
pub fn convert_os_string(span: Span) -> Self {
|
||||
let message = format!("failed to convert file string name, maybe an illegal character?");
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn current_directory_error(error: io::Error) -> Self {
|
||||
let span = Span {
|
||||
text: "".to_string(),
|
||||
line: 0,
|
||||
start: 0,
|
||||
end: 0,
|
||||
};
|
||||
let message = format!("compilation failed trying to find current directory - {:?}", error);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn directory_error(error: io::Error, span: Span, path: PathBuf) -> Self {
|
||||
let message = format!("compilation failed due to directory error - {:?}", error);
|
||||
|
||||
Self::new_from_span_with_path(message, span, path)
|
||||
}
|
||||
|
||||
pub fn star(path: PathBuf, span: Span) -> Self {
|
||||
let message = format!("cannot import `*` from path `{:?}`", path);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn expected_lib_file(entry: String, span: Span) -> Self {
|
||||
let message = format!(
|
||||
"expected library file`{}` when looking for symbol `{}`",
|
||||
entry, span.text
|
||||
);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn unknown_package(identifier: Identifier) -> Self {
|
||||
let message = format!(
|
||||
"cannot find imported package `{}` in source files or import directory",
|
||||
identifier.name
|
||||
);
|
||||
|
||||
Self::new_from_span(message, identifier.span)
|
||||
}
|
||||
}
|
18
imports/src/errors/mod.rs
Normal file
18
imports/src/errors/mod.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// 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/>.
|
||||
|
||||
pub mod import_parser;
|
||||
pub use self::import_parser::*;
|
@ -15,14 +15,11 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/// The import parser creates a hashmap of import program names -> import program structs
|
||||
pub mod core_package;
|
||||
pub use self::core_package::*;
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
pub mod parse_symbol;
|
||||
pub use self::parse_symbol::*;
|
||||
pub mod errors;
|
||||
pub use self::errors::*;
|
||||
|
||||
pub mod import_parser;
|
||||
pub use self::import_parser::*;
|
||||
|
||||
pub mod parse_package;
|
||||
pub use self::parse_package::*;
|
||||
pub mod parser;
|
||||
pub use self::parser::*;
|
||||
|
@ -14,14 +14,14 @@
|
||||
// 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::{errors::ImportError, ImportParser};
|
||||
use crate::{errors::ImportParserError, ImportParser};
|
||||
use leo_typed::Package;
|
||||
|
||||
pub static CORE_PACKAGE_NAME: &str = "core";
|
||||
|
||||
impl ImportParser {
|
||||
// import a core package into scope
|
||||
pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportError> {
|
||||
pub fn parse_core_package(&mut self, package: &Package) -> Result<(), ImportParserError> {
|
||||
self.insert_core_package(package);
|
||||
Ok(())
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// 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::errors::ImportError;
|
||||
use crate::errors::ImportParserError;
|
||||
use leo_typed::{Package, Program};
|
||||
|
||||
use std::{collections::HashMap, env::current_dir};
|
||||
@ -52,18 +52,18 @@ impl ImportParser {
|
||||
&self.core_packages
|
||||
}
|
||||
|
||||
pub fn parse(program: &Program) -> Result<Self, ImportError> {
|
||||
pub fn parse(program: &Program) -> Result<Self, ImportParserError> {
|
||||
let mut imports = Self::new();
|
||||
|
||||
// Find all imports relative to current directory
|
||||
let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?;
|
||||
let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?;
|
||||
|
||||
// Parse each imported file
|
||||
program
|
||||
.imports
|
||||
.iter()
|
||||
.map(|import| imports.parse_package(path.clone(), &import.package))
|
||||
.collect::<Result<Vec<()>, ImportError>>()?;
|
||||
.collect::<Result<Vec<()>, ImportParserError>>()?;
|
||||
|
||||
Ok(imports)
|
||||
}
|
28
imports/src/parser/mod.rs
Normal file
28
imports/src/parser/mod.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// 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/>.
|
||||
|
||||
/// The import parser creates a hashmap of import program names -> import program structs
|
||||
pub mod core_package;
|
||||
pub use self::core_package::*;
|
||||
|
||||
pub mod parse_symbol;
|
||||
pub use self::parse_symbol::*;
|
||||
|
||||
pub mod import_parser;
|
||||
pub use self::import_parser::*;
|
||||
|
||||
pub mod parse_package;
|
||||
pub use self::parse_package::*;
|
@ -14,7 +14,7 @@
|
||||
// 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::{errors::ImportError, ImportParser, CORE_PACKAGE_NAME};
|
||||
use crate::{errors::ImportParserError, ImportParser, CORE_PACKAGE_NAME};
|
||||
use leo_typed::{Package, PackageAccess};
|
||||
|
||||
use std::{fs, fs::DirEntry, path::PathBuf};
|
||||
@ -26,7 +26,7 @@ static IMPORTS_DIRECTORY_NAME: &str = "imports/";
|
||||
impl ImportParser {
|
||||
// bring one or more import symbols into scope for the current constrained program
|
||||
// we will recursively traverse sub packages here until we find the desired symbol
|
||||
pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportError> {
|
||||
pub fn parse_package_access(&mut self, entry: &DirEntry, access: &PackageAccess) -> Result<(), ImportParserError> {
|
||||
tracing::debug!("import {:?}", entry.path());
|
||||
|
||||
match access {
|
||||
@ -43,7 +43,7 @@ impl ImportParser {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportError> {
|
||||
pub fn parse_package(&mut self, mut path: PathBuf, package: &Package) -> Result<(), ImportParserError> {
|
||||
let error_path = path.clone();
|
||||
let package_name = package.name.clone();
|
||||
|
||||
@ -69,10 +69,12 @@ impl ImportParser {
|
||||
}
|
||||
|
||||
let entries = fs::read_dir(path)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||
.map_err(|error| ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||
.map_err(|error| {
|
||||
ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone())
|
||||
})?;
|
||||
|
||||
let matched_source_entry = entries.into_iter().find(|entry| {
|
||||
entry
|
||||
@ -89,26 +91,30 @@ impl ImportParser {
|
||||
self.parse_core_package(&package)
|
||||
} else if imports_directory.exists() {
|
||||
let entries = fs::read_dir(imports_directory)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||
.map_err(|error| {
|
||||
ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone())
|
||||
})?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||
.map_err(|error| {
|
||||
ImportParserError::directory_error(error, package_name.span.clone(), error_path.clone())
|
||||
})?;
|
||||
|
||||
let matched_import_entry = entries
|
||||
.into_iter()
|
||||
.find(|entry| entry.file_name().into_string().unwrap().eq(&package_name.name));
|
||||
|
||||
match (matched_source_entry, matched_import_entry) {
|
||||
(Some(_), Some(_)) => Err(ImportError::conflicting_imports(package_name)),
|
||||
(Some(_), Some(_)) => Err(ImportParserError::conflicting_imports(package_name)),
|
||||
(Some(source_entry), None) => self.parse_package_access(&source_entry, &package.access),
|
||||
(None, Some(import_entry)) => self.parse_package_access(&import_entry, &package.access),
|
||||
(None, None) => Err(ImportError::unknown_package(package_name)),
|
||||
(None, None) => Err(ImportParserError::unknown_package(package_name)),
|
||||
}
|
||||
} else {
|
||||
// Enforce local package access with no found imports directory
|
||||
match matched_source_entry {
|
||||
Some(source_entry) => self.parse_package_access(&source_entry, &package.access),
|
||||
None => Err(ImportError::unknown_package(package_name)),
|
||||
None => Err(ImportParserError::unknown_package(package_name)),
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// 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::{errors::ImportError, ImportParser};
|
||||
use crate::{errors::ImportParserError, ImportParser};
|
||||
use leo_ast::LeoAst;
|
||||
use leo_typed::{ImportSymbol, Program, Span};
|
||||
|
||||
@ -23,23 +23,23 @@ use std::{ffi::OsString, fs::DirEntry, path::PathBuf};
|
||||
static LIBRARY_FILE: &str = "src/lib.leo";
|
||||
static FILE_EXTENSION: &str = "leo";
|
||||
|
||||
fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportError> {
|
||||
fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportParserError> {
|
||||
// make sure the given entry is file
|
||||
let file_type = entry
|
||||
.file_type()
|
||||
.map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?;
|
||||
.map_err(|error| ImportParserError::directory_error(error, span.clone(), entry.path()))?;
|
||||
let file_name = entry
|
||||
.file_name()
|
||||
.to_os_string()
|
||||
.into_string()
|
||||
.map_err(|_| ImportError::convert_os_string(span.clone()))?;
|
||||
.map_err(|_| ImportParserError::convert_os_string(span.clone()))?;
|
||||
|
||||
let mut file_path = entry.path().to_path_buf();
|
||||
if file_type.is_dir() {
|
||||
file_path.push(LIBRARY_FILE);
|
||||
|
||||
if !file_path.exists() {
|
||||
return Err(ImportError::expected_lib_file(
|
||||
return Err(ImportParserError::expected_lib_file(
|
||||
format!("{:?}", file_path.as_path()),
|
||||
span.clone(),
|
||||
));
|
||||
@ -55,7 +55,7 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportErr
|
||||
}
|
||||
|
||||
impl ImportParser {
|
||||
pub fn parse_import_star(&mut self, entry: &DirEntry, span: &Span) -> Result<(), ImportError> {
|
||||
pub fn parse_import_star(&mut self, entry: &DirEntry, span: &Span) -> Result<(), ImportParserError> {
|
||||
let path = entry.path();
|
||||
let is_dir = path.is_dir();
|
||||
let is_leo_file = path
|
||||
@ -77,7 +77,7 @@ impl ImportParser {
|
||||
.imports
|
||||
.iter()
|
||||
.map(|import| self.parse_package(entry.path(), &import.package))
|
||||
.collect::<Result<Vec<()>, ImportError>>()?;
|
||||
.collect::<Result<Vec<()>, ImportParserError>>()?;
|
||||
|
||||
// Store program in imports hashmap
|
||||
let file_name_path = PathBuf::from(entry.file_name());
|
||||
@ -93,11 +93,11 @@ impl ImportParser {
|
||||
Ok(())
|
||||
} else {
|
||||
// importing * from a directory or non-leo file in `package/src/` is illegal
|
||||
Err(ImportError::star(entry.path().to_path_buf(), span.clone()))
|
||||
Err(ImportParserError::star(entry.path().to_path_buf(), span.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportError> {
|
||||
pub fn parse_import_symbol(&mut self, entry: &DirEntry, symbol: &ImportSymbol) -> Result<(), ImportParserError> {
|
||||
// Generate aleo program from file
|
||||
let program = parse_import_file(entry, &symbol.span)?;
|
||||
|
||||
@ -106,7 +106,7 @@ impl ImportParser {
|
||||
.imports
|
||||
.iter()
|
||||
.map(|import| self.parse_package(entry.path(), &import.package))
|
||||
.collect::<Result<Vec<()>, ImportError>>()?;
|
||||
.collect::<Result<Vec<()>, ImportParserError>>()?;
|
||||
|
||||
// Store program in imports hashmap
|
||||
let file_name_path = PathBuf::from(entry.file_name());
|
Loading…
Reference in New Issue
Block a user