Skip to content

Commit

Permalink
Fix entry point reimports to give an error
Browse files Browse the repository at this point in the history
  • Loading branch information
LunaAmora committed Jun 24, 2024
1 parent cafd7e6 commit ae170b3
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 81 deletions.
16 changes: 8 additions & 8 deletions src/fun/load_book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
diagnostics::{Diagnostics, DiagnosticsConfig},
imports::PackageLoader,
};
use std::{fmt::Display, path::Path};
use std::path::Path;

// TODO: Refactor so that we don't mix the two syntaxes here.

Expand All @@ -17,11 +17,11 @@ pub fn load_file_to_book(
diag: DiagnosticsConfig,
) -> Result<Book, Diagnostics> {
let code = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
load_to_book(path.display(), &code, package_loader, diag)
load_to_book(path, &code, package_loader, diag)
}

pub fn load_to_book<T: Display>(
origin: T,
pub fn load_to_book(
origin: &Path,
code: &str,
package_loader: impl PackageLoader,
diag: DiagnosticsConfig,
Expand All @@ -31,11 +31,11 @@ pub fn load_to_book<T: Display>(
book.load_imports(package_loader, diag)
}

pub fn do_parse_book<T: Display>(code: &str, origin: T, mut book: ParseBook) -> Result<ParseBook, String> {
book.source = Name::new(format!("{origin}"));
TermParser::new(code).parse_book(book, false).map_err(|e| format!("In {} :\n{}", origin, e))
pub fn do_parse_book(code: &str, origin: &Path, mut book: ParseBook) -> Result<ParseBook, String> {
book.source = Name::new(origin.to_string_lossy());
TermParser::new(code).parse_book(book, false).map_err(|e| format!("In {} :\n{}", origin.display(), e))
}

pub fn do_parse_book_default<T: Display>(code: &str, origin: T) -> Result<Book, String> {
pub fn do_parse_book_default(code: &str, origin: &Path) -> Result<Book, String> {
do_parse_book(code, origin, ParseBook::builtins())?.to_fun()
}
82 changes: 63 additions & 19 deletions src/imports/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::fun::Name;
use indexmap::IndexMap;
use std::{
collections::HashSet,
path::{Path, PathBuf},
path::{Component, Path, PathBuf},
};

pub type Sources = IndexMap<Name, String>;
Expand Down Expand Up @@ -40,23 +40,33 @@ pub trait PackageLoader {
pub struct DefaultLoader {
local_path: PathBuf,
loaded: HashSet<Name>,
entrypoint: Name,
}

impl DefaultLoader {
pub fn new(local_path: &Path) -> Self {
let entrypoint = Name::new(local_path.file_stem().unwrap().to_string_lossy());
let local_path = local_path.parent().unwrap().to_path_buf();
Self { local_path, loaded: HashSet::new() }
Self { local_path, loaded: HashSet::new(), entrypoint }
}

fn read_file(&mut self, path: &Path, file: Name, src: &mut Sources) -> Option<Name> {
if !self.is_loaded(&file) {
self.loaded.insert(file.clone());
fn read_file(&mut self, path: &Path, file_path: &str, src: &mut Sources) -> Result<Option<Name>, String> {
let normalized = normalize_path(&PathBuf::from(file_path));
let file_path = Name::new(normalized.to_string_lossy());

if self.entrypoint == file_path {
return Err("Can not import the entry point of the program.".to_string());
};

if !self.is_loaded(&file_path) {
self.loaded.insert(file_path.clone());

let path = path.with_extension("bend");
let code = std::fs::read_to_string(path).ok()?;
src.insert(file.clone(), code);
let Some(code) = std::fs::read_to_string(path).ok() else { return Ok(None) };
src.insert(file_path.clone(), code);
}
Some(file)

Ok(Some(file_path))
}

fn read_file_in_folder(
Expand All @@ -65,24 +75,28 @@ impl DefaultLoader {
folder: &str,
file_name: &str,
src: &mut Sources,
) -> Option<Name> {
let file_path = Name::new(format!("{}/{}", folder, file_name));
) -> Result<Option<Name>, String> {
let full_path = full_path.join(file_name);

self.read_file(&full_path, file_path, src)
if folder.is_empty() {
self.read_file(&full_path, file_name, src)
} else {
let file_name = &format!("{}/{}", folder, file_name);
self.read_file(&full_path, file_name, src)
}
}

fn read_path(
&mut self,
base_path: &Path,
path: &Name,
imp_type: &ImportType,
) -> Option<(BoundSource, Sources)> {
) -> Result<Option<(BoundSource, Sources)>, String> {
let full_path = base_path.join(path.as_ref());
let mut src = IndexMap::new();

let file = if full_path.with_extension("bend").is_file() {
self.read_file(&full_path, path.clone(), &mut src)
self.read_file(&full_path, path.as_ref(), &mut src)?
} else {
None
};
Expand All @@ -92,13 +106,13 @@ impl DefaultLoader {

match imp_type {
ImportType::Single(file, _) => {
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src) {
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src)? {
names.insert(file.clone(), name);
}
}
ImportType::List(list) => {
for (file, _) in list {
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src) {
if let Some(name) = self.read_file_in_folder(&full_path, path, file, &mut src)? {
names.insert(file.clone(), name);
}
}
Expand All @@ -109,7 +123,7 @@ impl DefaultLoader {

if let Some("bend") = file.extension().and_then(|f| f.to_str()) {
let file = file.file_stem().unwrap().to_string_lossy();
if let Some(name) = self.read_file_in_folder(&full_path, path, &file, &mut src) {
if let Some(name) = self.read_file_in_folder(&full_path, path, &file, &mut src)? {
names.insert(Name::new(file), name);
}
}
Expand All @@ -126,12 +140,14 @@ impl DefaultLoader {
None
};

match (file, dir) {
let src = match (file, dir) {
(Some(f), None) => Some((BoundSource::File(f), src)),
(None, Some(d)) => Some((BoundSource::Dir(d), src)),
(Some(f), Some(d)) => Some((BoundSource::Either(f, d), src)),
(None, None) => None,
}
};

Ok(src)
}

fn is_loaded(&self, name: &Name) -> bool {
Expand All @@ -154,7 +170,7 @@ impl PackageLoader for DefaultLoader {
};

for base in folders {
let Some((names, new_pkgs)) = self.read_path(&base, path, imp_type) else { continue };
let Some((names, new_pkgs)) = self.read_path(&base, path, imp_type)? else { continue };

*src = names;
sources.extend(new_pkgs);
Expand All @@ -168,3 +184,31 @@ impl PackageLoader for DefaultLoader {
Ok(sources)
}
}

// Taken from 'cargo/util/paths.rs'
pub fn normalize_path(path: &Path) -> PathBuf {
let mut components = path.components().peekable();
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
components.next();
PathBuf::from(c.as_os_str())
} else {
PathBuf::new()
};

for component in components {
match component {
Component::Prefix(..) => unreachable!(),
Component::RootDir => {
ret.push(component.as_os_str());
}
Component::CurDir => {}
Component::ParentDir => {
ret.pop();
}
Component::Normal(c) => {
ret.push(c);
}
}
}
ret
}
40 changes: 4 additions & 36 deletions src/imports/packages.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use super::{loader::PackageLoader, BoundSource, ImportCtx, ImportType, ImportsMap};
use super::{loader::PackageLoader, normalize_path, BoundSource, ImportCtx, ImportType, ImportsMap};
use crate::{
diagnostics::Diagnostics,
fun::{load_book::do_parse_book, parser::ParseBook, Name},
};
use indexmap::{IndexMap, IndexSet};
use std::{
cell::RefCell,
collections::VecDeque,
path::{Component, Path, PathBuf},
};
use std::{cell::RefCell, collections::VecDeque, path::PathBuf};

#[derive(Default)]
pub struct Packages {
Expand All @@ -23,7 +19,7 @@ pub struct Packages {
impl Packages {
pub fn new(book: ParseBook) -> Self {
Self {
books: IndexMap::from([(Name::default(), book.into())]),
books: IndexMap::from([(book.source.clone(), book.into())]),
load_queue: VecDeque::new(),
loaded_adts: IndexMap::new(),
}
Expand Down Expand Up @@ -84,7 +80,7 @@ impl Packages {
}

for (psrc, code) in sources {
let module = do_parse_book(&code, &psrc, ParseBook::default())?;
let module = do_parse_book(&code, &PathBuf::from(psrc.as_ref()), ParseBook::default())?;
self.load_queue.push_back(self.books.len());
self.books.insert(psrc, module.into());
}
Expand Down Expand Up @@ -239,31 +235,3 @@ impl Packages {
bound_book.top_level_names().cloned().collect()
}
}

// Taken from 'cargo/util/paths.rs'
fn normalize_path(path: &Path) -> PathBuf {
let mut components = path.components().peekable();
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
components.next();
PathBuf::from(c.as_os_str())
} else {
PathBuf::new()
};

for component in components {
match component {
Component::Prefix(..) => unreachable!(),
Component::RootDir => {
ret.push(component.as_os_str());
}
Component::CurDir => {}
Component::ParentDir => {
ret.pop();
}
Component::Normal(c) => {
ret.push(c);
}
}
}
ret
}
Loading

0 comments on commit ae170b3

Please sign in to comment.