Import and export improved

- Import paths are now vname and not sym
- Imports and exports accept multiple space-delimited operators in []

as a result, we can now reliably import and export the operator *

- error reporting ergonomics
This commit is contained in:
2023-08-18 21:10:29 +01:00
parent 3fdabc29da
commit 9186bce956
33 changed files with 269 additions and 228 deletions

View File

@@ -75,7 +75,7 @@ fn source_to_module(
.collect::<Vec<_>>();
let imports_from = (imports.iter())
.map(|imp| -> ProjectResult<_> {
let mut imp_path_v = i.r(imp.path).clone();
let mut imp_path_v = imp.path.clone();
imp_path_v.push(imp.name.expect("glob imports had just been resolved"));
let mut abs_path = absolute_path(&path_v, &imp_path_v, i)
.expect("should have failed in preparsing");

View File

@@ -7,7 +7,7 @@ use crate::error::{NotFound, ProjectError, ProjectResult};
use crate::interner::{Interner, Tok};
use crate::pipeline::source_loader::LoadedSourceTable;
use crate::representations::tree::WalkErrorKind;
use crate::utils::{split_max_prefix, unwrap_or, Cache};
use crate::utils::{split_max_prefix, Cache};
use crate::Sym;
pub type OpsResult = ProjectResult<Rc<HashSet<Tok<String>>>>;
@@ -33,40 +33,43 @@ pub fn collect_exported_ops(
) -> OpsResult {
let injected = injected(path).unwrap_or_else(|| Rc::new(HashSet::new()));
let path_s = &i.r(path)[..];
let name_split = split_max_prefix(path_s, &|n| loaded.contains_key(n));
let (fpath, subpath) = unwrap_or!(name_split; return Ok(Rc::new(
(loaded.keys())
.filter_map(|modname| {
if path_s.len() == coprefix(path_s.iter(), modname.iter()) {
Some(modname[path_s.len()])
} else {
None
}
})
.chain(injected.iter().copied())
.collect::<HashSet<_>>(),
)));
let preparsed = &loaded[fpath].preparsed;
let module =
preparsed.0.walk_ref(subpath, false).map_err(
|walk_err| match walk_err.kind {
WalkErrorKind::Private => {
unreachable!("visibility is not being checked here")
match split_max_prefix(path_s, &|n| loaded.contains_key(n)) {
None => {
let ops = (loaded.keys())
.filter_map(|modname| {
if path_s.len() == coprefix(path_s.iter(), modname.iter()) {
Some(modname[path_s.len()])
} else {
None
}
})
.chain(injected.iter().copied())
.collect::<HashSet<_>>();
Ok(Rc::new(ops))
},
Some((fpath, subpath)) => {
let preparsed = &loaded[fpath].preparsed;
let module = preparsed.0.walk_ref(subpath, false).map_err(
|walk_err| match walk_err.kind {
WalkErrorKind::Private => {
unreachable!("visibility is not being checked here")
},
WalkErrorKind::Missing => NotFound {
source: None,
file: fpath.to_vec(),
subpath: subpath[..walk_err.pos].to_vec(),
}
.rc(),
},
WalkErrorKind::Missing => NotFound {
source: None,
file: fpath.to_vec(),
subpath: subpath[..walk_err.pos].to_vec(),
}
.rc(),
},
)?;
let out = (module.items.iter())
.filter(|(_, v)| v.exported)
.map(|(k, _)| *k)
.chain(injected.iter().copied())
.collect::<HashSet<_>>();
Ok(Rc::new(out))
)?;
let out = (module.items.iter())
.filter(|(_, v)| v.exported)
.map(|(k, _)| *k)
.chain(injected.iter().copied())
.collect::<HashSet<_>>();
Ok(Rc::new(out))
},
}
}
pub fn mk_cache<'a>(

View File

@@ -44,7 +44,7 @@ pub fn collect_ops_for(
ret.insert(n);
} else {
let path = i.expect(
import_abs_path(file, modpath, &i.r(import.path)[..], i),
import_abs_path(file, modpath, &import.path, i),
"This error should have been caught during loading",
);
ret.extend(ops_cache.find(&i.i(&path))?.iter().copied());

View File

@@ -59,7 +59,7 @@ fn entv_rec(
.flat_map(|import| {
if let Import { name: None, path } = import {
let p = i.expect(
import_abs_path(mod_path, mod_stack, &i.r(path)[..], i),
import_abs_path(mod_path, mod_stack, &path, i),
"Should have emerged in preparsing",
);
let names = i.expect(
@@ -67,7 +67,7 @@ fn entv_rec(
"Should have emerged in second parsing",
);
let imports = (names.iter())
.map(move |&n| Import { name: Some(n), path })
.map(|&n| Import { name: Some(n), path: path.clone() })
.collect::<Vec<_>>();
Box::new(imports.into_iter()) as BoxedIter<Import>
} else {