Add PackageLoader documentation, rename some enums

This commit is contained in:
LunaAmora 2024-06-20 15:53:24 -03:00
parent 21fe38e8be
commit b7f5b9fb27
5 changed files with 40 additions and 15 deletions

View File

@ -299,7 +299,7 @@ impl<'a> TermParser<'a> {
}
let (import, alias) = self.parse_name_maybe_alias("Import")?;
Ok(Import::new(path, ImportType::Simple(import, alias), relative))
Ok(Import::new(path, ImportType::Single(import, alias), relative))
}
fn parse_import(&mut self) -> Result<Vec<Import>, String> {
@ -312,7 +312,7 @@ impl<'a> TermParser<'a> {
None => (Name::default(), import),
};
Import::new(path, ImportType::Simple(import, alias), relative)
Import::new(path, ImportType::Single(import, alias), relative)
};
if self.try_consume("(") {

View File

@ -118,7 +118,7 @@ impl ParseBook {
'outer: for (bind, src) in self.import_ctx.map.binds.iter().rev() {
if self.contains_def(bind) | self.ctrs.contains_key(bind) | self.adts.contains_key(bind) {
// TODO: Here we should show warnings for shadowing of imported names by local def/ctr/adt
// It can be done, but when importing with `ImportType::Simple` files in the same folder,
// It can be done, but when importing with `ImportType::Single` files in the same folder,
// it gives a false positive warning
continue;
}

View File

@ -6,14 +6,37 @@ use std::{
path::{Path, PathBuf},
};
pub const BEND_PATH: &[&str] = &[""];
pub type Sources = IndexMap<Name, String>;
/// Trait to load packages from various sources.
pub trait PackageLoader {
/// Load a package specified by the `import` parameter.
///
/// # Parameters
///
/// - `import`: A mutable reference to an `Import` structure, which contains:
/// - `path`: The path to the package or directory to be imported.
/// - `imp_type`: The type of import, which can specify a single name, a list of names, or all names in a path.
/// - `relative`: A boolean indicating if the path is relative to the current directory.
/// - `src`: A `BoundSource` to be updated with the names of the located files.
///
/// # Behavior
///
/// The `load` method is responsible for locating and loading the requested package(s).
/// The loaded packages are returned as a `Sources` map, where the key is the package name and the value is its content.
/// Implementers must:
///
/// - Track already loaded sources to avoid loading and returning them again.
/// - Update `import.src` with the names of the found packages, even if they are not included in the `Sources` map.
///
/// The implementation should handle the following import types:
/// - **Single**: Load a specific file by its name.
/// - **List**: Load a list of specified files or names from a specific file.
/// - **Glob**: Load all files in a directory or all names from a specific file.
fn load(&mut self, import: &mut Import) -> Result<Sources, String>;
}
/// Default implementation of `PackageLoader` that loads packages from the local directory.
pub struct DefaultLoader {
local_path: PathBuf,
loaded: HashSet<Name>,
@ -68,7 +91,7 @@ impl DefaultLoader {
let mut names = Vec::new();
match imp_type {
ImportType::Simple(file, _) => {
ImportType::Single(file, _) => {
let name = self.read_file_in_folder(&full_path, path, file, &mut src)?;
names.push(name);
}
@ -91,7 +114,7 @@ impl DefaultLoader {
}
}
return Some((BoundSource::Folder(names), src));
return Some((BoundSource::Dir(names), src));
}
None
@ -102,6 +125,8 @@ impl DefaultLoader {
}
}
pub const BEND_PATH: &[&str] = &[""];
impl PackageLoader for DefaultLoader {
fn load(&mut self, import: &mut Import) -> Result<Sources, String> {
let mut sources = Sources::new();

View File

@ -38,7 +38,7 @@ impl ImportCtx {
match &imps.src {
BoundSource::None => {}
BoundSource::File(f) => names.push(f),
BoundSource::Folder(v) => names.extend(v),
BoundSource::Dir(v) => names.extend(v),
}
}
names
@ -61,7 +61,7 @@ impl Import {
#[derive(Debug, Clone)]
pub enum ImportType {
Simple(Name, Option<Name>),
Single(Name, Option<Name>),
List(Vec<(Name, Option<Name>)>),
Glob,
}
@ -69,7 +69,7 @@ pub enum ImportType {
impl Display for ImportType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImportType::Simple(n, _) => write!(f, "{n}"),
ImportType::Single(n, _) => write!(f, "{n}"),
ImportType::List(l) => write!(f, "({})", l.iter().map(|(n, _)| n).join(", ")),
ImportType::Glob => write!(f, "*"),
}
@ -80,7 +80,7 @@ impl Display for ImportType {
pub enum BoundSource {
None,
File(Name),
Folder(Vec<Name>),
Dir(Vec<Name>),
}
#[derive(Debug, Clone, Default)]

View File

@ -94,7 +94,7 @@ impl Packages {
for Import { imp_type, src: pkgs, .. } in imports {
match (pkgs, imp_type) {
(BoundSource::File(src), ImportType::Simple(nam, alias)) => {
(BoundSource::File(src), ImportType::Single(nam, alias)) => {
let bound_book = self.books.get(&src).unwrap();
if !bound_book.top_level_names().contains(&nam) {
@ -140,18 +140,18 @@ impl Packages {
}
}
(BoundSource::Folder(mut src), ImportType::Simple(nam, alias)) => {
(BoundSource::Dir(mut src), ImportType::Single(nam, alias)) => {
let src = src.pop().unwrap();
self.add_book_bind(idx, src, nam, alias, diag);
}
(BoundSource::Folder(pkgs), ImportType::List(names)) => {
(BoundSource::Dir(pkgs), ImportType::List(names)) => {
for (src, (nam, alias)) in pkgs.into_iter().zip_eq(names) {
self.add_book_bind(idx, src, nam, alias, diag);
}
}
(BoundSource::Folder(pkgs), ImportType::Glob) => {
(BoundSource::Dir(pkgs), ImportType::Glob) => {
for src in pkgs {
let nam = Name::new(src.split('/').last().unwrap());
self.add_book_bind(idx, src, nam, None, diag);