mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-01 08:19:32 +03:00
imports: refactor AST repr
This commit is contained in:
parent
5d3d93efbc
commit
567def9e2f
@ -1,58 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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::PackageOrPackages;
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Represents an import statement in a Leo program.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportStatement {
|
||||
/// The package or packages to import.
|
||||
pub package_or_packages: PackageOrPackages,
|
||||
/// The span, excluding the `;`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ImportStatement {
|
||||
/// Returns the the package file name of the self import statement.
|
||||
pub fn get_file_name(&self) -> Symbol {
|
||||
match self.package_or_packages {
|
||||
PackageOrPackages::Package(ref package) => package.name.name,
|
||||
PackageOrPackages::Packages(ref packages) => packages.name.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportStatement {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "import {};", self.package_or_packages)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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::Identifier;
|
||||
|
||||
use leo_span::{sym, Span};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// An import of `symbol` possibly renamed to `alias`,
|
||||
/// e.g., `symbol` or `symbol as alias`.
|
||||
///
|
||||
/// This is the leaf of an import tree.
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportSymbol {
|
||||
pub symbol: Identifier,
|
||||
/// The name, if any, to import `symbol` as.
|
||||
/// If not specified, `symbol` is the name it is imported under.
|
||||
pub alias: Option<Identifier>,
|
||||
/// The span including `symbol` and possibly `as alias`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportSymbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.alias.is_some() {
|
||||
write!(f, "{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||
} else {
|
||||
write!(f, "{}", self.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (collin): remove this
|
||||
impl fmt::Debug for ImportSymbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.alias.is_some() {
|
||||
write!(f, "{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||
} else {
|
||||
write!(f, "{}", self.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportSymbol {
|
||||
/// Creates a glob `*` import.
|
||||
pub fn star(span: &Span) -> Self {
|
||||
Self {
|
||||
symbol: Identifier {
|
||||
name: sym::Star,
|
||||
span: span.clone(),
|
||||
},
|
||||
alias: None,
|
||||
span: span.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this a glob import?
|
||||
pub fn is_star(&self) -> bool {
|
||||
self.symbol.name == sym::Star
|
||||
}
|
||||
}
|
@ -14,20 +14,106 @@
|
||||
// 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;
|
||||
pub use import::*;
|
||||
use crate::Identifier;
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
pub mod import_symbol;
|
||||
pub use import_symbol::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
pub mod package;
|
||||
pub use package::*;
|
||||
/// Represents an import statement in a Leo program.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportStatement {
|
||||
/// The tree specifying what items or packages to import.
|
||||
pub tree: ImportTree,
|
||||
/// The span, excluding the `;`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
pub mod packages;
|
||||
pub use packages::*;
|
||||
impl ImportStatement {
|
||||
/// Returns the the package file name of the self import statement.
|
||||
pub fn get_file_name(&self) -> Symbol {
|
||||
self.tree.base.first().unwrap().name
|
||||
}
|
||||
}
|
||||
|
||||
pub mod package_or_packages;
|
||||
pub use package_or_packages::*;
|
||||
impl fmt::Display for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "import {};", self.tree)
|
||||
}
|
||||
}
|
||||
|
||||
pub mod package_access;
|
||||
pub use package_access::*;
|
||||
impl fmt::Debug for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// An import tree specifies item(s) to import.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportTree {
|
||||
/// A path to the base item or package to import or import from.
|
||||
/// The list is always non-empty.
|
||||
pub base: Vec<Identifier>,
|
||||
/// Specifies the kind of import and the meaning of `base`.
|
||||
/// This includes plain imports, renames, globs (`*`), and nested imports.
|
||||
pub kind: ImportTreeKind,
|
||||
/// The span for the import excluding `import` and `;`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportTree {
|
||||
/// Formats `self` to `f`.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Format the path.
|
||||
for (i, part) in self.base.iter().enumerate() {
|
||||
write!(f, "{}", part)?;
|
||||
if i < self.base.len() - 1 {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
|
||||
// Format the kind.
|
||||
match self.kind {
|
||||
ImportTreeKind::Glob { .. } => write!(f, ".*"),
|
||||
ImportTreeKind::Leaf { alias: None } => Ok(()),
|
||||
ImportTreeKind::Leaf { alias: Some(alias) } => write!(f, "as {}", alias),
|
||||
ImportTreeKind::Nested { tree } => {
|
||||
write!(f, ".(")?;
|
||||
for (i, node) in tree.iter().enumerate() {
|
||||
write!(f, "{}", node)?;
|
||||
if i < tree.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ImportTree {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the import kind and the meaning of `base`.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ImportTreeKind {
|
||||
/// A glob import `*`.
|
||||
Glob {
|
||||
/// The span for the `*`.
|
||||
span: Span,
|
||||
},
|
||||
/// A leaf package to import.
|
||||
Leaf {
|
||||
/// When specified, the package is imported under a different name.
|
||||
/// Otherwise, the `base` name is used as in the `ImportTree`.
|
||||
alias: Option<Identifier>,
|
||||
},
|
||||
/// A nested import of items or sub-packages.
|
||||
Nested {
|
||||
/// The sub-tree specifying what to import from the `base`.
|
||||
tree: Vec<ImportTree>,
|
||||
},
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A package import specification.
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Package {
|
||||
/// The base package to import `access` from.
|
||||
pub name: Identifier,
|
||||
/// A specification of what to import from `name`.
|
||||
pub access: PackageAccess,
|
||||
/// The span including the `name` and the `access`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
/// Formats `self` to `f`.
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.{}", self.name, self.access)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Package {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Package {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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::{ImportSymbol, Node, Package, Packages};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum PackageAccess {
|
||||
/// A glob import `*`.
|
||||
Star {
|
||||
/// The span for the `*`.
|
||||
span: Span,
|
||||
},
|
||||
/// A subpackage to import.
|
||||
SubPackage(Box<Package>),
|
||||
/// A leaf package to import.
|
||||
Symbol(ImportSymbol),
|
||||
/// Several subpackages to import.
|
||||
// FIXME(Centril): This structure seems convoluted and unclear.
|
||||
// Refactor and simplify the types to:
|
||||
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.UseTree.html.
|
||||
Multiple(Packages),
|
||||
}
|
||||
|
||||
impl Node for PackageAccess {
|
||||
fn span(&self) -> &Span {
|
||||
match self {
|
||||
PackageAccess::Star { span } => span,
|
||||
PackageAccess::SubPackage(package) => &package.span,
|
||||
PackageAccess::Symbol(package) => &package.span,
|
||||
PackageAccess::Multiple(package) => &package.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
match self {
|
||||
PackageAccess::Star { span } => *span = span.clone(),
|
||||
PackageAccess::SubPackage(package) => package.span = span,
|
||||
PackageAccess::Symbol(package) => package.span = span,
|
||||
PackageAccess::Multiple(package) => package.span = span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PackageAccess {
|
||||
/// Formats `self` to `f`.
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
PackageAccess::Star { .. } => write!(f, "*"),
|
||||
PackageAccess::SubPackage(ref package) => write!(f, "{}", package),
|
||||
PackageAccess::Symbol(ref symbol) => write!(f, "{}", symbol),
|
||||
PackageAccess::Multiple(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 PackageAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PackageAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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::{Node, Package, Packages};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A specification of what packages to import.
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum PackageOrPackages {
|
||||
/// Instruction to import a single package or item.
|
||||
Package(Package),
|
||||
/// Instruction to import a packages or items with a common prefix.
|
||||
Packages(Packages),
|
||||
}
|
||||
|
||||
impl PackageOrPackages {
|
||||
/// Formats `self` to `f`.
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for PackageOrPackages {
|
||||
fn span(&self) -> &Span {
|
||||
match self {
|
||||
PackageOrPackages::Package(package) => &package.span,
|
||||
PackageOrPackages::Packages(packages) => &packages.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
match self {
|
||||
PackageOrPackages::Package(package) => package.span = span,
|
||||
PackageOrPackages::Packages(packages) => packages.span = span,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// Copyright (C) 2019-2022 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};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Import of `name.(accesses)`, that is, several sub-packages or items within `name`.
|
||||
#[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Packages {
|
||||
/// The common package that `accesses` are contained within.
|
||||
pub name: Identifier,
|
||||
/// The packages or items to import within the package `name`.
|
||||
pub accesses: Vec<PackageAccess>,
|
||||
/// The entire span for `name.(accesses)`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Packages {
|
||||
/// Formats `self` to `f`.
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user