1
0
Fork 0
mirror of synced 2025-09-23 20:28:36 +00:00

add resolver trait

This commit is contained in:
dark64 2020-02-25 21:30:30 +01:00
parent d8cde9e1c0
commit acd9b9ea86
11 changed files with 267 additions and 221 deletions

142
Cargo.lock generated
View file

@ -58,12 +58,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
[[package]]
name = "autocfg"
version = "1.0.0"
@ -233,7 +227,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
dependencies = [
"error-chain 0.12.1",
"error-chain 0.12.2",
"semver",
"serde",
"serde_derive",
@ -281,9 +275,9 @@ dependencies = [
[[package]]
name = "colored"
version = "1.9.2"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [
"atty",
"lazy_static",
@ -322,33 +316,36 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.4.0"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
dependencies = [
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg 0.1.7",
"autocfg",
"cfg-if",
"crossbeam-utils",
"lazy_static",
"maybe-uninit",
"memoffset",
"scopeguard",
]
@ -365,11 +362,11 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.7.0"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg 0.1.7",
"autocfg",
"cfg-if",
"lazy_static",
]
@ -455,12 +452,12 @@ dependencies = [
[[package]]
name = "error-chain"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
checksum = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd"
dependencies = [
"backtrace",
"version_check",
"version_check 0.9.1",
]
[[package]]
@ -479,9 +476,9 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
"synstructure",
]
@ -613,9 +610,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.7"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2c55f143919fbc0bc77e427fe2d74cf23786d7c1875666f2fde3ac3c659bb67"
checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
dependencies = [
"libc",
]
@ -678,9 +675,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.66"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "libgit2-sys"
@ -699,9 +696,9 @@ dependencies = [
[[package]]
name = "libssh2-sys"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36aa6e813339d3a063292b77091dfbbb6152ff9006a459895fa5bebed7d34f10"
checksum = "2b920f022ce0b459a5f27aa86c87c74510bad96f1d9169cfe1f7d2d2e7f1f10f"
dependencies = [
"cc",
"libc",
@ -745,10 +742,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "memchr"
version = "2.3.2"
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
name = "memoffset"
@ -772,7 +775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
dependencies = [
"memchr",
"version_check",
"version_check 0.1.5",
]
[[package]]
@ -802,7 +805,7 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
"autocfg 1.0.0",
"autocfg",
"num-integer",
"num-traits 0.2.11",
"serde",
@ -814,7 +817,7 @@ version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg 1.0.0",
"autocfg",
"num-traits 0.2.11",
]
@ -824,7 +827,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg 1.0.0",
"autocfg",
"num-integer",
"num-traits 0.2.11",
]
@ -844,7 +847,7 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg 1.0.0",
"autocfg",
]
[[package]]
@ -875,7 +878,7 @@ version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986"
dependencies = [
"autocfg 1.0.0",
"autocfg",
"cc",
"libc",
"pkg-config",
@ -901,9 +904,9 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
[[package]]
name = "pest"
version = "2.1.2"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
@ -933,22 +936,22 @@ dependencies = [
[[package]]
name = "pest_generator"
version = "2.1.1"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b9fcf299b5712d06ee128a556c94709aaa04512c4dffb8ead07c5c998447fc0"
checksum = "27e5277315f6b4f27e0e6744feb5d5ba1891e7164871033d3c8344c6783b349a"
dependencies = [
"pest",
"pest_meta",
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
]
[[package]]
name = "pest_meta"
version = "2.1.2"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
@ -978,9 +981,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.8"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid 0.2.0",
]
@ -1009,7 +1012,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
]
[[package]]
@ -1238,9 +1241,9 @@ version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
]
[[package]]
@ -1295,7 +1298,7 @@ checksum = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
dependencies = [
"bytecount",
"cargo_metadata",
"error-chain 0.12.1",
"error-chain 0.12.2",
"glob 0.2.11",
"pulldown-cmark",
"serde_json",
@ -1345,11 +1348,11 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.14"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"unicode-xid 0.2.0",
]
@ -1360,9 +1363,9 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
"unicode-xid 0.2.0",
]
@ -1518,6 +1521,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[[package]]
name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
[[package]]
name = "void"
version = "1.0.2"
@ -1560,9 +1569,9 @@ dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
"wasm-bindgen-shared",
]
@ -1594,9 +1603,9 @@ version = "0.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -1627,7 +1636,7 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97837a6e83ab24a4b3a38d44a257e13335b54f4b4548b2c9d71edd0bf570cb4f"
dependencies = [
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
]
@ -1640,9 +1649,9 @@ dependencies = [
"anyhow",
"heck",
"log",
"proc-macro2 1.0.8",
"proc-macro2 1.0.9",
"quote 1.0.2",
"syn 1.0.14",
"syn 1.0.16",
"wasm-bindgen-backend",
"weedle",
]
@ -1795,9 +1804,10 @@ dependencies = [
[[package]]
name = "zokrates_fs_resolver"
version = "0.5.0"
version = "0.1.0"
dependencies = [
"tempfile",
"zokrates_core",
]
[[package]]

View file

@ -16,7 +16,7 @@ regex = "0.2"
zokrates_field = { version = "0.3", path = "../zokrates_field" }
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
zokrates_core = { version = "0.4", path = "../zokrates_core" }
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
zokrates_fs_resolver = { version = "0.1", path = "../zokrates_fs_resolver"}
serde_json = "1.0"
[dev-dependencies]

View file

@ -19,7 +19,7 @@ use zokrates_core::proof_system::*;
use zokrates_core::typed_absy::abi::Abi;
use zokrates_core::typed_absy::{types::Signature, Type};
use zokrates_field::field::{Field, FieldPrime};
use zokrates_fs_resolver::resolve as fs_resolve;
use zokrates_fs_resolver::FileSystemResolver;
fn main() {
cli().unwrap_or_else(|e| {
@ -299,8 +299,9 @@ fn cli() -> Result<(), String> {
)
};
let resolver = FileSystemResolver::new();
let artifacts: CompilationArtifacts<FieldPrime> =
compile(source, path, Some(&fs_resolve)).map_err(|e| {
compile(source, path, Some(&resolver)).map_err(|e| {
format!(
"Compilation failed:\n\n{}",
e.0.iter()
@ -681,8 +682,9 @@ mod tests {
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let resolver = FileSystemResolver::new();
let _: CompilationArtifacts<FieldPrime> =
compile(source, path, Some(&fs_resolve)).unwrap();
compile(source, path, Some(&resolver)).unwrap();
}
}
@ -702,8 +704,9 @@ mod tests {
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let resolver = FileSystemResolver::new();
let artifacts: CompilationArtifacts<FieldPrime> =
compile(source, path, Some(&fs_resolve)).unwrap();
compile(source, path, Some(&resolver)).unwrap();
let _ = artifacts
.prog()
@ -729,8 +732,9 @@ mod tests {
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let resolver = FileSystemResolver::new();
let artifacts: CompilationArtifacts<FieldPrime> =
compile(source, path, Some(&fs_resolve)).unwrap();
compile(source, path, Some(&resolver)).unwrap();
let _ = artifacts
.prog()

View file

@ -129,20 +129,23 @@ impl fmt::Display for CompileErrorInner {
}
}
// See zokrates_fs_resolver for the spec
pub type Resolve<'a, E> = &'a dyn Fn(PathBuf, PathBuf) -> Result<(String, PathBuf), E>;
type FilePath = PathBuf;
pub trait Resolver<E: Into<imports::Error>> {
fn resolve(
&self,
current_location: PathBuf,
import_location: PathBuf,
) -> Result<(String, PathBuf), E>;
}
pub fn compile<T: Field, E: Into<imports::Error>>(
source: String,
location: FilePath,
resolve_option: Option<Resolve<E>>,
location: PathBuf,
resolver: Option<&dyn Resolver<E>>,
) -> Result<CompilationArtifacts<T>, CompileErrors> {
let arena = Arena::new();
let source = arena.alloc(source);
let compiled = compile_program(source, location.clone(), resolve_option, &arena)?;
let compiled = compile_program(source, location.clone(), resolver, &arena)?;
// check semantics
let typed_ast = Checker::check(compiled).map_err(|errors| {
@ -174,19 +177,13 @@ pub fn compile<T: Field, E: Into<imports::Error>>(
pub fn compile_program<'ast, T: Field, E: Into<imports::Error>>(
source: &'ast str,
location: FilePath,
resolve_option: Option<Resolve<E>>,
location: PathBuf,
resolver: Option<&dyn Resolver<E>>,
arena: &'ast Arena<String>,
) -> Result<Program<'ast, T>, CompileErrors> {
let mut modules = HashMap::new();
let main = compile_module(
&source,
location.clone(),
resolve_option,
&mut modules,
&arena,
)?;
let main = compile_module(&source, location.clone(), resolver, &mut modules, &arena)?;
modules.insert(location.clone(), main);
@ -198,8 +195,8 @@ pub fn compile_program<'ast, T: Field, E: Into<imports::Error>>(
pub fn compile_module<'ast, T: Field, E: Into<imports::Error>>(
source: &'ast str,
location: FilePath,
resolve_option: Option<Resolve<E>>,
location: PathBuf,
resolver: Option<&dyn Resolver<E>>,
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
arena: &'ast Arena<String>,
) -> Result<Module<'ast, T>, CompileErrors> {
@ -210,7 +207,7 @@ pub fn compile_module<'ast, T: Field, E: Into<imports::Error>>(
Importer::new().apply_imports(
module_without_imports,
location.clone(),
resolve_option,
resolver,
modules,
&arena,
)
@ -229,8 +226,11 @@ mod test {
return foo()
"#
.to_string();
let res: Result<CompilationArtifacts<FieldPrime>, CompileErrors> =
compile(source, "./path/to/file".into(), None::<Resolve<io::Error>>);
let res: Result<CompilationArtifacts<FieldPrime>, CompileErrors> = compile(
source,
"./path/to/file".into(),
None::<&dyn Resolver<io::Error>>,
);
assert!(res.unwrap_err().0[0]
.value()
.to_string()
@ -244,8 +244,11 @@ mod test {
return 1
"#
.to_string();
let res: Result<CompilationArtifacts<FieldPrime>, CompileErrors> =
compile(source, "./path/to/file".into(), None::<Resolve<io::Error>>);
let res: Result<CompilationArtifacts<FieldPrime>, CompileErrors> = compile(
source,
"./path/to/file".into(),
None::<&dyn Resolver<io::Error>>,
);
assert!(res.is_ok());
}
}

View file

@ -6,7 +6,7 @@
use crate::absy::*;
use crate::compile::compile_module;
use crate::compile::{CompileErrorInner, CompileErrors, Resolve};
use crate::compile::{CompileErrorInner, CompileErrors, Resolver};
use crate::embed::FlatEmbed;
use crate::parser::Position;
use std::collections::HashMap;
@ -135,7 +135,7 @@ impl Importer {
&self,
destination: Module<'ast, T>,
location: PathBuf,
resolve_option: Option<Resolve<E>>,
resolver: Option<&dyn Resolver<E>>,
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
arena: &'ast Arena<String>,
) -> Result<Module<'ast, T>, CompileErrors> {
@ -180,8 +180,8 @@ impl Importer {
}
} else {
// to resolve imports, we need a resolver
match resolve_option {
Some(resolve) => match resolve(location.clone(), import.source.to_path_buf()) {
match resolver {
Some(res) => match res.resolve(location.clone(), import.source.to_path_buf()) {
Ok((source, new_location)) => {
// generate an alias from the imported path if none was given explicitely
let alias = import.alias.unwrap_or(
@ -206,7 +206,7 @@ impl Importer {
let compiled = compile_module(
source,
new_location.clone(),
resolve_option,
resolver,
modules,
&arena,
)?;

View file

@ -1,15 +1,11 @@
[package]
name = "zokrates_fs_resolver"
version = "0.5.0"
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
repository = "https://github.com/JacobEberhardt/ZoKrates.git"
[features]
default = []
version = "0.1.0"
authors = ["dark64 <darem966@gmail.com>"]
edition = "2018"
[dependencies]
zokrates_core = { version = "0.4.2", path = "../zokrates_core" }
[dev-dependencies]
tempfile = "3"
[lib]
tempfile = "3"

View file

@ -3,75 +3,63 @@ use std::io;
use std::path::Path;
use std::path::{Component, PathBuf};
use zokrates_core::compile::Resolver;
const ZOKRATES_HOME: &str = &"ZOKRATES_HOME";
// path to the current file we're importing into
type CurrentLocation = PathBuf;
// path we're importing from
type ImportLocation<'a> = PathBuf;
type SourceCode = String;
pub struct FileSystemResolver {}
/// Returns the source code and the new location from a file path and import path
///
/// # Arguments
///
/// * `current_location` - Path to the file we're importing into
/// * `import_location` - Path to the file we're importing from
///
/// # Returns
/// * The content of the file we're importing from
/// * The path to the file we're importing from
///
/// # Remarks
///
/// * `current_location* must point to a file
/// * `import_location` and the returned path are both relative to the directory in which `current_location` is, unless it's an absolute
/// path, in which case they are relative to the root of the ZoKrates stdlib at `$ZOKRATES_HOME`
///
pub fn resolve<'a>(
current_location: CurrentLocation,
import_location: ImportLocation<'a>,
) -> Result<(SourceCode, CurrentLocation), io::Error> {
let source = Path::new(&import_location);
if !current_location.is_file() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("{} was expected to be a file", current_location.display()),
));
impl FileSystemResolver {
pub fn new() -> Self {
FileSystemResolver {}
}
}
// paths starting with `./` or `../` are interpreted relative to the current file
// other paths `abc/def` are interpreted relative to $ZOKRATES_HOME
let base = match source.components().next() {
Some(Component::CurDir) | Some(Component::ParentDir) => {
Ok(PathBuf::from(current_location).parent().unwrap().into())
impl Resolver<io::Error> for FileSystemResolver {
fn resolve(
&self,
current_location: PathBuf,
import_location: PathBuf,
) -> Result<(String, PathBuf), io::Error> {
let source = Path::new(&import_location);
if !current_location.is_file() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("{} was expected to be a file", current_location.display()),
));
}
_ => std::env::var(ZOKRATES_HOME)
.map_err(|_| {
io::Error::new(
io::ErrorKind::Other,
"$ZOKRATES_HOME is not set, please set it",
)
})
.map(PathBuf::from),
}?;
let path_owned = base
.join(PathBuf::from(import_location.clone()))
.with_extension("zok");
// paths starting with `./` or `../` are interpreted relative to the current file
// other paths `abc/def` are interpreted relative to $ZOKRATES_HOME
let base = match source.components().next() {
Some(Component::CurDir) | Some(Component::ParentDir) => {
Ok(PathBuf::from(current_location).parent().unwrap().into())
}
_ => std::env::var(ZOKRATES_HOME)
.map_err(|_| {
io::Error::new(
io::ErrorKind::Other,
"$ZOKRATES_HOME is not set, please set it",
)
})
.map(PathBuf::from),
}?;
if !path_owned.is_file() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("No file found at {}", import_location.display()),
));
let path_owned = base
.join(PathBuf::from(import_location.clone()))
.with_extension("zok");
if !path_owned.is_file() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("No file found at {}", import_location.display()),
));
}
let source = read_to_string(&path_owned)?;
Ok((source, path_owned))
}
let source = read_to_string(&path_owned)?;
Ok((source, path_owned))
}
#[cfg(test)]
@ -85,19 +73,25 @@ mod tests {
let folder = tempfile::tempdir().unwrap();
let file_path = folder.path().join("bar.zok");
File::create(file_path.clone()).unwrap();
let (_, next_location) = resolve(file_path.clone(), "./bar.zok".into()).unwrap();
let fs_resolver = FileSystemResolver::new();
let (_, next_location) = fs_resolver
.resolve(file_path.clone(), "./bar.zok".into())
.unwrap();
assert_eq!(next_location, file_path);
}
#[test]
fn non_existing_file() {
let res = resolve("./source.zok".into(), "./rubbish".into());
let fs_resolver = FileSystemResolver::new();
let res = fs_resolver.resolve("./source.zok".into(), "./rubbish".into());
assert!(res.is_err());
}
#[test]
fn invalid_location() {
let res = resolve(",8!-$2abc".into(), "./foo".into());
let fs_resolver = FileSystemResolver::new();
let res = fs_resolver.resolve(",8!-$2abc".into(), "./foo".into());
assert!(res.is_err());
}
@ -108,7 +102,8 @@ mod tests {
let dir_path = folder.path().join("dir");
std::fs::create_dir(dir_path.clone()).unwrap();
let res = resolve(".".into(), "./dir/".into());
let fs_resolver = FileSystemResolver::new();
let res = fs_resolver.resolve(".".into(), "./dir/".into());
assert!(res.is_err());
}
@ -118,7 +113,9 @@ mod tests {
let folder = tempfile::tempdir().unwrap();
let file_path = folder.path().join("foo.zok");
File::create(file_path.clone()).unwrap();
let res = resolve(file_path, ".".into());
let fs_resolver = FileSystemResolver::new();
let res = fs_resolver.resolve(file_path, ".".into());
assert!(res.is_err());
}
@ -141,7 +138,8 @@ mod tests {
// assign HOME folder to ZOKRATES_HOME
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
let result = resolve(file_path, "./bar.zok".into());
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve(file_path, "./bar.zok".into());
assert!(result.is_ok());
// the imported file should be the user's
assert_eq!(result.unwrap().0, String::from("<user code>\n"));
@ -166,7 +164,8 @@ mod tests {
// assign HOME folder to ZOKRATES_HOME
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
let result = resolve(file_path.clone(), "bar.zok".into());
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve(file_path.clone(), "bar.zok".into());
assert!(result.is_ok());
// the imported file should be the user's
assert_eq!(result.unwrap().0, String::from("<stdlib code>\n"));
@ -185,7 +184,8 @@ mod tests {
let origin_path = source_subfolder.path().join("foo.zok");
File::create(origin_path).unwrap();
let result = resolve(
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve(
source_subfolder.path().to_path_buf().join("foo.zok"),
"../bar.zok".into(),
);
@ -207,21 +207,24 @@ mod tests {
// assign HOME folder to ZOKRATES_HOME
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
let result = resolve("/path/to/source.zok".into(), "./bar.zok".into());
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve("/path/to/source.zok".into(), "./bar.zok".into());
assert!(result.is_err());
}
#[test]
fn fail_if_not_found_in_std() {
std::env::set_var(ZOKRATES_HOME, "");
let result = resolve("/path/to/source.zok".into(), "bar.zok".into());
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve("/path/to/source.zok".into(), "bar.zok".into());
assert!(result.is_err());
}
#[test]
fn panic_if_home_not_set() {
std::env::remove_var(ZOKRATES_HOME);
let result = resolve("/path/to/source.zok".into(), "bar.zok".into());
let fs_resolver = FileSystemResolver::new();
let result = fs_resolver.resolve("/path/to/source.zok".into(), "bar.zok".into());
assert!(result.is_err());
}
}

View file

@ -14,25 +14,25 @@ const initialize = async () => {
// load web assembly module
const zokrates = await import('./pkg/index.js');
const resolveModule = (location, path, callback) => {
if (isReserved(location) || isReserved(path)) {
return resolveFromStandardLibrary(location, path);
const resolveModule = (currentLocation, importLocation, callback) => {
if (isReserved(currentLocation) || isReserved(importLocation)) {
return resolveFromStandardLibrary(currentLocation, importLocation);
}
return callback(location, path);
return callback(currentLocation, importLocation);
}
const isReserved = (path) => RESERVED_PATHS.some(p => path.startsWith(p));
const resolveFromStandardLibrary = (location, path) => {
let key = appendExtension(getAbsolutePath(location, path), EXTENSION_ZOK);
const resolveFromStandardLibrary = (currentLocation, importLocation) => {
let key = appendExtension(getAbsolutePath(currentLocation, importLocation), EXTENSION_ZOK);
let source = stdlib[key];
return source ? { source, location: key } : null;
}
return {
compile: (source, location, callback) => {
let result = zokrates.compile(source, location, (location, path) =>
resolveModule(location, path, callback)
let result = zokrates.compile(source, location, (currentLocation, importLocation) =>
resolveModule(currentLocation, importLocation, callback)
);
return {
program: Array.from(result.program),

View file

@ -3,13 +3,15 @@ use serde::{Deserialize, Serialize};
use serde_json::to_string_pretty;
use std::path::PathBuf;
use wasm_bindgen::prelude::*;
use zokrates_abi::{parse_strict, Encode, Decode, Inputs};
use zokrates_core::compile::{compile as core_compile, CompilationArtifacts, CompileError};
use zokrates_abi::{parse_strict, Decode, Encode, Inputs};
use zokrates_core::compile::{
compile as core_compile, CompilationArtifacts, CompileError, Resolver,
};
use zokrates_core::imports::Error;
use zokrates_core::ir;
use zokrates_core::proof_system::{self, ProofSystem};
use zokrates_core::typed_absy::abi::Abi;
use zokrates_core::typed_absy::{types::Signature};
use zokrates_core::typed_absy::types::Signature;
use zokrates_field::field::FieldPrime;
#[derive(Serialize, Deserialize)]
@ -48,44 +50,71 @@ fn serialize_program(program: &ir::Prog<FieldPrime>) -> Result<Vec<u8>, JsValue>
.map_err(|err| JsValue::from_str(&format!("Could not serialize program: {}", err)))
}
pub struct JsResolver<'a> {
callback: &'a js_sys::Function,
}
impl<'a> JsResolver<'a> {
pub fn new(callback: &'a js_sys::Function) -> Self {
JsResolver { callback }
}
}
impl<'a> Resolver<Error> for JsResolver<'a> {
fn resolve(
&self,
current_location: PathBuf,
import_location: PathBuf,
) -> Result<(String, PathBuf), Error> {
let value = self
.callback
.call2(
&JsValue::UNDEFINED,
&current_location.to_str().unwrap().into(),
&import_location.to_str().unwrap().into(),
)
.map_err(|_| {
Error::new(format!(
"Error thrown in callback: could not resolve {}",
import_location.display()
))
})?;
if value.is_null() || value.is_undefined() {
Err(Error::new(format!(
"Could not resolve {}",
import_location.display()
)))
} else {
let result: ResolverResult = value.into_serde().unwrap();
Ok(result.into_tuple())
}
}
}
#[wasm_bindgen]
pub fn compile(
source: JsValue,
location: JsValue,
resolve: &js_sys::Function,
) -> Result<JsValue, JsValue> {
let closure = |l: PathBuf, p: PathBuf| {
let value = resolve
.call2(&JsValue::UNDEFINED, &l.display().to_string().into(), &p.clone().display().to_string().into())
.map_err(|_| {
Error::new(format!(
"Error thrown in callback: Could not resolve `{}`",
p.display()
))
})?;
if value.is_null() || value.is_undefined() {
Err(Error::new(format!("Could not resolve `{}`", p.display())))
} else {
let result: ResolverResult = value.into_serde().unwrap();
Ok(result.into_tuple())
}
};
let fmt_error = |e: &CompileError| {
format!(
"{}:{}",
e.file().display(),
e.value()
)
};
let fmt_error = |e: &CompileError| format!("{}:{}", e.file().display(), e.value());
let resolver = JsResolver::new(resolve);
let artifacts: CompilationArtifacts<FieldPrime> = core_compile(
source.as_string().unwrap(),
PathBuf::from(location.as_string().unwrap()),
Some(&closure),
Some(&resolver),
)
.map_err(|ce| JsValue::from_str(&format!("{}", ce.0.iter().map(|e| fmt_error(e)).collect::<Vec<_>>().join("\n"))))?;
.map_err(|ce| {
JsValue::from_str(&format!(
"{}",
ce.0.iter()
.map(|e| fmt_error(e))
.collect::<Vec<_>>()
.join("\n")
))
})?;
let result = CompilationResult {
program: serialize_program(artifacts.prog())?,
@ -119,7 +148,7 @@ pub fn compute_witness(artifacts: JsValue, args: JsValue) -> Result<JsValue, JsV
let result = ComputationResult {
witness: format!("{}", witness),
output: to_string_pretty(&return_values).unwrap()
output: to_string_pretty(&return_values).unwrap(),
};
Ok(JsValue::from_serde(&result).unwrap())

View file

@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
zokrates_field = { version = "0.3", path = "../zokrates_field" }
zokrates_core = { version = "0.4", path = "../zokrates_core" }
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver" }
zokrates_fs_resolver = { version = "0.1", path = "../zokrates_fs_resolver" }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"

View file

@ -69,7 +69,7 @@ fn compare(result: ir::ExecutionResult<FieldPrime>, expected: TestResult) -> Res
use std::io::{BufReader, Read};
use zokrates_core::compile::compile;
use zokrates_fs_resolver::resolve;
use zokrates_fs_resolver::FileSystemResolver;
pub fn test_inner(test_path: &str) {
let t: Tests =
@ -77,7 +77,8 @@ pub fn test_inner(test_path: &str) {
let code = std::fs::read_to_string(&t.entry_point).unwrap();
let artifacts = compile(code, t.entry_point.clone(), Some(&resolve)).unwrap();
let resolver = FileSystemResolver::new();
let artifacts = compile(code, t.entry_point.clone(), Some(&resolver)).unwrap();
let bin = artifacts.prog();