Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/254 strengthen import rules #620

Merged
merged 9 commits into from Feb 11, 2021
38 changes: 26 additions & 12 deletions asg/src/program/mod.rs
Expand Up @@ -25,7 +25,7 @@ mod function;
pub use function::*;

use crate::{AsgConvertError, ImportResolver, InnerScope, Input, Scope};
use leo_ast::{Identifier, Package, PackageAccess, Span};
use leo_ast::{Identifier, PackageAccess, PackageOrPackages, Span};

use indexmap::IndexMap;
use std::{cell::RefCell, sync::Arc};
Expand Down Expand Up @@ -74,24 +74,37 @@ enum ImportSymbol {
fn resolve_import_package(
output: &mut Vec<(Vec<String>, ImportSymbol, Span)>,
mut package_segments: Vec<String>,
package: &Package,
package_or_packages: &PackageOrPackages,
) {
package_segments.push(package.name.name.clone());

resolve_import_package_access(output, package_segments, &package.access);
match package_or_packages {
PackageOrPackages::Package(package) => {
package_segments.push(package.name.name.clone());
resolve_import_package_access(output, package_segments, &package.access);
}
PackageOrPackages::Packages(packages) => {
package_segments.push(packages.name.name.clone());
for access in packages.accesses.clone() {
resolve_import_package_access(output, package_segments.clone(), &access);
}
}
}
}

fn resolve_import_package_access(
output: &mut Vec<(Vec<String>, ImportSymbol, Span)>,
package_segments: Vec<String>,
mut package_segments: Vec<String>,
package: &PackageAccess,
) {
match package {
PackageAccess::Star(span) => {
output.push((package_segments, ImportSymbol::All, span.clone()));
}
PackageAccess::SubPackage(subpackage) => {
resolve_import_package(output, package_segments, &*subpackage);
resolve_import_package(
output,
package_segments,
&PackageOrPackages::Package(*(*subpackage).clone()),
);
}
PackageAccess::Symbol(symbol) => {
let span = symbol.symbol.span.clone();
Expand All @@ -102,8 +115,9 @@ fn resolve_import_package_access(
};
output.push((package_segments, symbol, span));
}
PackageAccess::Multiple(subaccesses) => {
for subaccess in subaccesses.iter() {
PackageAccess::Multiple(packages) => {
package_segments.push(packages.name.name.clone());
for subaccess in packages.accesses.iter() {
resolve_import_package_access(output, package_segments.clone(), &subaccess);
}
}
Expand All @@ -126,7 +140,7 @@ impl InternalProgram {
// Recursively extract imported symbols.
let mut imported_symbols: Vec<(Vec<String>, ImportSymbol, Span)> = vec![];
for import in program.imports.iter() {
resolve_import_package(&mut imported_symbols, vec![], &import.package);
resolve_import_package(&mut imported_symbols, vec![], &import.package_or_packages);
}

// Create package list.
Expand Down Expand Up @@ -383,11 +397,11 @@ pub fn reform_ast(program: &Program) -> leo_ast::Program {
imports: core_programs
.iter()
.map(|(module, _)| leo_ast::ImportStatement {
package: leo_ast::Package {
package_or_packages: leo_ast::PackageOrPackages::Package(leo_ast::Package {
name: Identifier::new(module.clone()),
access: leo_ast::PackageAccess::Star(Span::default()),
span: Default::default(),
},
}),
span: Span::default(),
})
.collect(),
Expand Down
4 changes: 4 additions & 0 deletions asg/tests/pass/import/imports/bar/src/baz.leo
@@ -1,3 +1,7 @@
circuit Baz {
z: u32
}

circuit Bazzar {
a: u32
}
3 changes: 2 additions & 1 deletion asg/tests/pass/import/many_import.leo
Expand Up @@ -5,7 +5,7 @@ import test-import.( // local import

import bar.( // imports directory import
Bar,
baz.Baz,
baz.(Baz, Bazzar),
bat.bat.Bat,
);

Expand All @@ -17,6 +17,7 @@ function main() {

const bar = Bar { r: 1u32 };
const baz = Baz { z: 1u32 };
const bazzar = Bazzar { a: 1u32 };
const bat = Bat { t: 1u32 };

const car = Car { c: 1u32 };
Expand Down
13 changes: 8 additions & 5 deletions ast/src/imports/import.rs
Expand Up @@ -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::{Package, Span};
use crate::{PackageOrPackages, Span};
use leo_grammar::imports::Import as GrammarImport;

use serde::{Deserialize, Serialize};
Expand All @@ -23,7 +23,7 @@ use std::fmt;
/// Represents an import statement in a Leo program.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ImportStatement {
pub package: Package,
pub package_or_packages: PackageOrPackages,
pub span: Span,
}

Expand All @@ -32,22 +32,25 @@ impl ImportStatement {
/// Returns the the package file name of the self import statement.
///
pub fn get_file_name(&self) -> &str {
&self.package.name.name
match self.package_or_packages {
PackageOrPackages::Package(ref package) => &package.name.name,
PackageOrPackages::Packages(ref packages) => &packages.name.name,
}
}
}

impl<'ast> From<GrammarImport<'ast>> for ImportStatement {
fn from(import: GrammarImport<'ast>) -> Self {
ImportStatement {
package: Package::from(import.package),
package_or_packages: PackageOrPackages::from(import.package_or_packages),
span: Span::from(import.span),
}
}
}

impl ImportStatement {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "import {};", self.package)
write!(f, "import {};", self.package_or_packages)
}
}

Expand Down
6 changes: 6 additions & 0 deletions ast/src/imports/mod.rs
Expand Up @@ -23,5 +23,11 @@ pub use import_symbol::*;
pub mod package;
pub use package::*;

pub mod packages;
pub use packages::*;

pub mod package_or_packages;
pub use package_or_packages::*;

pub mod package_access;
pub use package_access::*;
14 changes: 6 additions & 8 deletions ast/src/imports/package_access.rs
Expand Up @@ -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::{ImportSymbol, Package, Span};
use crate::{ImportSymbol, Package, Packages, Span};
use leo_grammar::imports::PackageAccess as GrammarPackageAccess;

use serde::{Deserialize, Serialize};
Expand All @@ -25,7 +25,7 @@ pub enum PackageAccess {
Star(Span),
SubPackage(Box<Package>),
Symbol(ImportSymbol),
Multiple(Vec<PackageAccess>),
Multiple(Packages),
}

impl<'ast> From<GrammarPackageAccess<'ast>> for PackageAccess {
Expand All @@ -34,9 +34,7 @@ impl<'ast> From<GrammarPackageAccess<'ast>> for PackageAccess {
GrammarPackageAccess::Star(star) => PackageAccess::Star(Span::from(star.span)),
GrammarPackageAccess::SubPackage(package) => PackageAccess::SubPackage(Box::new(Package::from(*package))),
GrammarPackageAccess::Symbol(symbol) => PackageAccess::Symbol(ImportSymbol::from(symbol)),
GrammarPackageAccess::Multiple(accesses) => {
PackageAccess::Multiple(accesses.into_iter().map(PackageAccess::from).collect())
}
GrammarPackageAccess::Multiple(packages) => PackageAccess::Multiple(Packages::from(packages)),
}
}
}
Expand All @@ -47,11 +45,11 @@ impl PackageAccess {
PackageAccess::Star(ref _span) => write!(f, "*"),
PackageAccess::SubPackage(ref package) => write!(f, "{}", package),
PackageAccess::Symbol(ref symbol) => write!(f, "{}", symbol),
PackageAccess::Multiple(ref accesses) => {
PackageAccess::Multiple(ref packages) => {
write!(f, "(")?;
for (i, access) in accesses.iter().enumerate() {
for (i, access) in packages.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < accesses.len() - 1 {
if i < packages.accesses.len() - 1 {
write!(f, ", ")?;
}
}
Expand Down
66 changes: 66 additions & 0 deletions ast/src/imports/package_or_packages.rs
@@ -0,0 +1,66 @@
// Copyright (C) 2019-2021 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::{Package, Packages};
use leo_grammar::imports::PackageOrPackages as GrammarPackageOrPackages;

use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum PackageOrPackages {
Package(Package),
Packages(Packages),
}

impl<'ast> From<GrammarPackageOrPackages<'ast>> for PackageOrPackages {
fn from(package_or_packages: GrammarPackageOrPackages<'ast>) -> Self {
match package_or_packages {
GrammarPackageOrPackages::Package(package) => PackageOrPackages::Package(Package::from(package)),
GrammarPackageOrPackages::Packages(packages) => PackageOrPackages::Packages(Packages::from(packages)),
}
}
}

impl PackageOrPackages {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PackageOrPackages::Package(ref package) => write!(f, "{}", package),
PackageOrPackages::Packages(ref packages) => {
write!(f, "(")?;
for (i, access) in packages.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < packages.accesses.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
}
}
}
}

impl fmt::Debug for PackageOrPackages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}

impl fmt::Display for PackageOrPackages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
63 changes: 63 additions & 0 deletions ast/src/imports/packages.rs
@@ -0,0 +1,63 @@
// Copyright (C) 2019-2021 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::{common::Identifier, PackageAccess, Span};
use leo_grammar::imports::Packages as GrammarPackages;

use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Packages {
pub name: Identifier,
pub accesses: Vec<PackageAccess>,
pub span: Span,
}

impl<'ast> From<GrammarPackages<'ast>> for Packages {
fn from(packages: GrammarPackages<'ast>) -> Self {
Packages {
name: Identifier::from(packages.name),
accesses: packages.accesses.into_iter().map(PackageAccess::from).collect(),
span: Span::from(packages.span),
}
}
}

impl Packages {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}.(", self.name)?;
for (i, access) in self.accesses.iter().enumerate() {
write!(f, "{}", access)?;
if i < self.accesses.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
}
}

impl fmt::Display for Packages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}

impl fmt::Debug for Packages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
4 changes: 4 additions & 0 deletions compiler/tests/import/imports/bar/src/baz.leo
@@ -1,3 +1,7 @@
circuit Baz {
z: u32
}

circuit Bazzar {
a: u32
}
3 changes: 2 additions & 1 deletion compiler/tests/import/many_import.leo
Expand Up @@ -5,7 +5,7 @@ import test-import.( // local import

import bar.( // imports directory import
Bar,
baz.Baz,
baz.(Baz, Bazzar),
bat.bat.Bat,
);

Expand All @@ -17,6 +17,7 @@ function main() {

const bar = Bar { r: 1u32 };
const baz = Baz { z: 1u32 };
const bazzar = Bazzar { a: 1u32 };
const bat = Bat { t: 1u32 };

const car = Car { c: 1u32 };
Expand Down
2 changes: 1 addition & 1 deletion examples/pedersen-hash/src/main.leo
Expand Up @@ -7,7 +7,7 @@ circuit PedersenHash {
}

function hash(self, bits: [bool; 256]) -> group {
let mut digest: group = 0;
let mut digest: group = 0group;
for i in 0..256 {
if bits[i] {
digest += self.parameters[i];
Expand Down