September-october commit
- manual parser - stl refinements - all language constructs are now Send
This commit is contained in:
@@ -13,7 +13,7 @@ use crate::sourcefile::{
|
||||
};
|
||||
use crate::tree::{ModEntry, ModMember, Module};
|
||||
use crate::utils::get_or::get_or_default;
|
||||
use crate::utils::pure_push::pushed_ref;
|
||||
use crate::utils::pure_seq::pushed_ref;
|
||||
use crate::{Tok, VName};
|
||||
|
||||
#[must_use = "A submodule may not be integrated into the tree"]
|
||||
@@ -28,7 +28,7 @@ pub struct TreeReport {
|
||||
pub fn build_tree(
|
||||
path: &VName,
|
||||
source: Vec<FileEntry>,
|
||||
Module { entries, extra }: PreMod,
|
||||
Module { entries, .. }: PreMod,
|
||||
imports: ImpMod,
|
||||
prelude: &[FileEntry],
|
||||
) -> ProjectResult<TreeReport> {
|
||||
@@ -56,20 +56,11 @@ pub fn build_tree(
|
||||
MemberKind::Constant(Constant { name, value }) => {
|
||||
consts.insert(name, value /* .prefix(path, &|_| false) */);
|
||||
},
|
||||
MemberKind::Operators(_) => (),
|
||||
MemberKind::Rule(rule) => rule_fragments.push(rule),
|
||||
},
|
||||
}
|
||||
}
|
||||
let mod_details = extra.details().expect("Directories handled elsewhere");
|
||||
let rules = (mod_details.patterns.iter())
|
||||
.zip(rule_fragments.into_iter())
|
||||
.map(|(p, Rule { prio, template: t, .. })| {
|
||||
// let p = p.iter().map(|e| e.prefix(path, &|_| false)).collect();
|
||||
// let t = t.into_iter().map(|e| e.prefix(path, &|_| false)).collect();
|
||||
Rule { pattern: p.clone(), prio, template: t }
|
||||
})
|
||||
.collect();
|
||||
let rules = rule_fragments;
|
||||
let (pre_subs, pre_items) = (entries.into_iter())
|
||||
.partition_map::<HashMap<_, _>, HashMap<_, _>, _, _, _>(
|
||||
|(k, ModEntry { exported, member })| match member {
|
||||
@@ -98,7 +89,7 @@ pub fn build_tree(
|
||||
Ok((k, ModEntry { exported, member }))
|
||||
})
|
||||
.chain((pre_items.into_iter()).map(
|
||||
|(k, (exported, PreItem { has_value, is_op, location }))| {
|
||||
|(k, (exported, PreItem { has_value, location }))| {
|
||||
let item = match imports_from.get(&k) {
|
||||
Some(_) if has_value => {
|
||||
// Local value cannot be assigned to imported key
|
||||
@@ -112,12 +103,10 @@ pub fn build_tree(
|
||||
},
|
||||
None => {
|
||||
let k = consts.remove(&k).map_or(ItemKind::None, ItemKind::Const);
|
||||
ProjectItem { is_op, kind: k }
|
||||
},
|
||||
Some(report) => ProjectItem {
|
||||
is_op: is_op | report.is_op,
|
||||
kind: ItemKind::Alias(report.source.clone()),
|
||||
ProjectItem { kind: k }
|
||||
},
|
||||
Some(report) =>
|
||||
ProjectItem { kind: ItemKind::Alias(report.source.clone()) },
|
||||
};
|
||||
Ok((k, ModEntry { exported, member: ModMember::Item(item) }))
|
||||
},
|
||||
@@ -129,7 +118,6 @@ pub fn build_tree(
|
||||
exported: false,
|
||||
member: ModMember::Item(ProjectItem {
|
||||
kind: ItemKind::Alias(from.source.clone()),
|
||||
is_op: from.is_op,
|
||||
}),
|
||||
})
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::representations::project::ImpReport;
|
||||
use crate::sourcefile::{absolute_path, Import};
|
||||
use crate::tree::{ErrKind, ModEntry, ModMember, Module, WalkError};
|
||||
use crate::utils::boxed_iter::{box_chain, box_once};
|
||||
use crate::utils::pure_push::pushed_ref;
|
||||
use crate::utils::pure_seq::pushed_ref;
|
||||
use crate::utils::{unwrap_or, BoxedIter};
|
||||
use crate::{Interner, ProjectTree, Tok, VName};
|
||||
|
||||
@@ -65,17 +65,13 @@ pub fn assert_visible_overlay<'a>(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn process_donor_module<'a, TItem: Clone>(
|
||||
module: &'a Module<TItem, impl Clone>,
|
||||
pub fn process_donor_module<TItem: Clone>(
|
||||
module: &Module<TItem, impl Clone>,
|
||||
abs_path: Rc<VName>,
|
||||
is_op: impl Fn(&TItem) -> bool + 'a,
|
||||
) -> impl Iterator<Item = (Tok<String>, VName, bool)> + 'a {
|
||||
(module.entries.iter()).filter(|(_, ent)| ent.exported).map(
|
||||
move |(n, ent)| {
|
||||
let is_op = ent.item().map_or(false, &is_op);
|
||||
(n.clone(), pushed_ref(abs_path.as_ref(), n.clone()), is_op)
|
||||
},
|
||||
)
|
||||
) -> impl Iterator<Item = (Tok<String>, VName)> + '_ {
|
||||
(module.entries.iter())
|
||||
.filter(|(_, ent)| ent.exported)
|
||||
.map(move |(n, _)| (n.clone(), pushed_ref(abs_path.as_ref(), n.clone())))
|
||||
}
|
||||
|
||||
pub fn import_tree(
|
||||
@@ -99,14 +95,7 @@ pub fn import_tree(
|
||||
// println!("Old root: {:#?}", &prev_root.0);
|
||||
panic!("{}", e.at(location))
|
||||
})?;
|
||||
let is_op = (root.0.walk1_ref(&[], &abs_path, false))
|
||||
.map(|(ent, _)| ent.item().map_or(false, |i| i.is_op))
|
||||
.or_else(|e| if e.kind == ErrKind::Missing {
|
||||
(prev_root.0.walk1_ref(&[], &abs_path, false))
|
||||
.map(|(ent, _)| ent.item().map_or(false, |i| i.is_op))
|
||||
} else {Err(e)})
|
||||
.map_err(|e| e.at(location))?;
|
||||
box_once((name.clone(), abs_path, is_op))
|
||||
box_once((name.clone(), abs_path))
|
||||
} else {
|
||||
let rc_path = Rc::new(abs_path);
|
||||
// wildcard imports are validated
|
||||
@@ -116,8 +105,7 @@ pub fn import_tree(
|
||||
let new_imports = match (root.0).walk_ref(&[], &rc_path, false) {
|
||||
Err(e) if e.kind == ErrKind::Missing => Err(e),
|
||||
Err(e) => return Err(e.at(location)),
|
||||
Ok(module)
|
||||
=> Ok(process_donor_module(module, rc_path.clone(), |i| i.is_op))
|
||||
Ok(module) => Ok(process_donor_module(module, rc_path.clone()))
|
||||
};
|
||||
let old_m = match (prev_root.0).walk_ref(&[], &rc_path, false) {
|
||||
Err(e) if e.kind != ErrKind::Missing => return Err(e.at(location)),
|
||||
@@ -134,7 +122,7 @@ pub fn import_tree(
|
||||
},
|
||||
Ok(old_m) => old_m,
|
||||
};
|
||||
let it1 = process_donor_module(old_m, rc_path.clone(), |i| i.is_op);
|
||||
let it1 = process_donor_module(old_m, rc_path.clone());
|
||||
match new_imports {
|
||||
Err(_) => Box::new(it1),
|
||||
Ok(it2) => box_chain!(it1, it2)
|
||||
@@ -144,10 +132,10 @@ pub fn import_tree(
|
||||
// leaf sets flattened to leaves
|
||||
.flatten_ok()
|
||||
// translated to entries
|
||||
.map_ok(|(name, source, is_op)| {
|
||||
.map_ok(|(name, source)| {
|
||||
(name, ModEntry {
|
||||
exported: false, // this is irrelevant but needed
|
||||
member: ModMember::Item(ImpReport { source, is_op }),
|
||||
member: ModMember::Item(ImpReport { source }),
|
||||
})
|
||||
})
|
||||
.chain(
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
|
||||
@@ -7,15 +5,14 @@ use super::build_tree::{build_tree, TreeReport};
|
||||
use super::import_tree::{import_tree, ImpMod};
|
||||
use crate::error::ProjectResult;
|
||||
use crate::pipeline::source_loader::{
|
||||
LoadedSourceTable, PreExtra, PreItem, PreMod, Preparsed,
|
||||
LoadedSourceTable, PreExtra, PreMod, Preparsed,
|
||||
};
|
||||
use crate::representations::project::{ImpReport, ProjectExt, ProjectMod};
|
||||
use crate::representations::project::{ProjectExt, ProjectMod};
|
||||
use crate::sourcefile::FileEntry;
|
||||
use crate::tree::{ModEntry, ModMember, Module};
|
||||
use crate::utils::never::{always, unwrap_always};
|
||||
use crate::utils::pure_push::pushed_ref;
|
||||
use crate::utils::pure_seq::pushed_ref;
|
||||
use crate::utils::unwrap_or;
|
||||
use crate::{parse, Interner, ProjectTree, Tok, VName};
|
||||
use crate::{Interner, ProjectTree, Tok, VName};
|
||||
|
||||
pub fn rebuild_file(
|
||||
path: Vec<Tok<String>>,
|
||||
@@ -23,35 +20,12 @@ pub fn rebuild_file(
|
||||
imports: ImpMod,
|
||||
source: &LoadedSourceTable,
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner,
|
||||
) -> ProjectResult<ProjectMod<VName>> {
|
||||
let file = match &pre.extra {
|
||||
PreExtra::Dir => panic!("Dir should not hand this node off"),
|
||||
PreExtra::Submod(_) => panic!("should not have received this"),
|
||||
PreExtra::File(f) => f,
|
||||
};
|
||||
let mut ops = Vec::new();
|
||||
unwrap_always(imports.search_all((), &mut |_, module, ()| {
|
||||
ops.extend(
|
||||
(module.entries.iter())
|
||||
.filter(|(_, ent)| {
|
||||
matches!(ent.member, ModMember::Item(ImpReport { is_op: true, .. }))
|
||||
})
|
||||
.map(|(name, _)| name.clone()),
|
||||
);
|
||||
always(())
|
||||
}));
|
||||
unwrap_always(pre.search_all((), &mut |_, module, ()| {
|
||||
ops.extend(
|
||||
(module.entries.iter())
|
||||
.filter(|(_, ent)| {
|
||||
matches!(ent.member, ModMember::Item(PreItem { is_op: true, .. }))
|
||||
})
|
||||
.map(|(name, _)| name.clone()),
|
||||
);
|
||||
always(())
|
||||
}));
|
||||
let ctx = parse::ParsingContext::new(&ops, i, Rc::new(path.clone()));
|
||||
let src = source.get(&file.name).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"{} should have been preparsed already. Preparsed files are {}",
|
||||
@@ -62,13 +36,11 @@ pub fn rebuild_file(
|
||||
.join(", ")
|
||||
)
|
||||
});
|
||||
let entries = parse::parse2(&src.text, ctx)?;
|
||||
let TreeReport { entries: items, rules, imports_from } =
|
||||
let entries = src.entries.clone();
|
||||
let TreeReport { entries, rules, imports_from } =
|
||||
build_tree(&path, entries, pre, imports, prelude)?;
|
||||
Ok(Module {
|
||||
entries: items,
|
||||
extra: ProjectExt { file: Some(path.clone()), path, imports_from, rules },
|
||||
})
|
||||
let file = Some(path.clone());
|
||||
Ok(Module { entries, extra: ProjectExt { file, path, imports_from, rules } })
|
||||
}
|
||||
|
||||
pub fn rebuild_dir(
|
||||
@@ -77,15 +49,14 @@ pub fn rebuild_dir(
|
||||
mut imports: ImpMod,
|
||||
source: &LoadedSourceTable,
|
||||
prelude: &[FileEntry],
|
||||
i: &Interner,
|
||||
) -> ProjectResult<ProjectMod<VName>> {
|
||||
match pre.extra {
|
||||
PreExtra::Dir => (),
|
||||
PreExtra::File(_) =>
|
||||
return rebuild_file(path, pre, imports, source, prelude, i),
|
||||
return rebuild_file(path, pre, imports, source, prelude),
|
||||
PreExtra::Submod(_) => panic!("Dirs contain dirs and files"),
|
||||
}
|
||||
let items = (pre.entries.into_iter())
|
||||
let entries = (pre.entries.into_iter())
|
||||
.map(|(name, entry)| {
|
||||
match imports.entries.remove(&name).map(|e| e.member) {
|
||||
Some(ModMember::Sub(impmod)) => (name, entry, impmod),
|
||||
@@ -97,12 +68,8 @@ pub fn rebuild_dir(
|
||||
let pre = unwrap_or!(member => ModMember::Sub;
|
||||
panic!("Dirs can only contain submodules")
|
||||
);
|
||||
Ok((name, ModEntry {
|
||||
exported,
|
||||
member: ModMember::Sub(rebuild_dir(
|
||||
path, pre, impmod, source, prelude, i,
|
||||
)?),
|
||||
}))
|
||||
let module = rebuild_dir(path, pre, impmod, source, prelude)?;
|
||||
Ok((name, ModEntry { exported, member: ModMember::Sub(module) }))
|
||||
})
|
||||
.collect::<Result<HashMap<_, _>, _>>()?;
|
||||
Ok(Module {
|
||||
@@ -112,7 +79,7 @@ pub fn rebuild_dir(
|
||||
rules: Vec::new(),
|
||||
file: None,
|
||||
},
|
||||
entries: items,
|
||||
entries,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -126,6 +93,6 @@ pub fn rebuild_tree(
|
||||
) -> ProjectResult<ProjectTree<VName>> {
|
||||
let imports =
|
||||
import_tree(Vec::new(), &preparsed.0, &preparsed, prev_root, i)?;
|
||||
rebuild_dir(Vec::new(), preparsed.0, imports, source, prelude, i)
|
||||
rebuild_dir(Vec::new(), preparsed.0, imports, source, prelude)
|
||||
.map(ProjectTree)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user