[DEV-7084] TAMER: AsgBuilderState
This completes the POC extraction for AsgBuilder, but is still POC code. The commits that follow will clean it up and provide tests.master
parent
3f46917da9
commit
da69118592
|
@ -25,12 +25,12 @@ use crate::fs::{
|
|||
};
|
||||
use crate::global;
|
||||
use crate::ir::asg::{
|
||||
Asg, AsgError, DefaultAsg, IdentObject, IdentObjectData, ObjectRef,
|
||||
Sections, SortableAsg,
|
||||
Asg, AsgError, DefaultAsg, IdentObject, IdentObjectData, Sections,
|
||||
SortableAsg,
|
||||
};
|
||||
use crate::obj::xmle::writer::XmleWriter;
|
||||
use crate::obj::xmlo::reader::{XmloError, XmloReader};
|
||||
use crate::obj::xmlo::{AsgBuilder, AsgBuilderResult};
|
||||
use crate::obj::xmlo::{AsgBuilder, AsgBuilderState};
|
||||
use crate::sym::{DefaultInterner, Interner, Symbol};
|
||||
use fxhash::{FxBuildHasher, FxHashMap};
|
||||
use std::error::Error;
|
||||
|
@ -39,39 +39,33 @@ use std::io::BufReader;
|
|||
use std::path::PathBuf;
|
||||
|
||||
type LinkerAsg<'i> = DefaultAsg<'i, IdentObject<'i>, global::ProgIdentSize>;
|
||||
type LinkerObjectRef = ObjectRef<global::ProgIdentSize>;
|
||||
|
||||
type LoadResult<'i> =
|
||||
Result<Option<(Option<&'i Symbol<'i>>, Option<String>)>, Box<dyn Error>>;
|
||||
type LinkerAsgBuilderState<'i> =
|
||||
AsgBuilderState<'i, FxBuildHasher, global::ProgIdentSize>;
|
||||
|
||||
pub fn main(package_path: &str, output: &str) -> Result<(), Box<dyn Error>> {
|
||||
let mut fs = VisitOnceFilesystem::new();
|
||||
let mut fragments: FxHashMap<&str, String> = Default::default();
|
||||
let mut depgraph = LinkerAsg::with_capacity(65536, 65536);
|
||||
let mut roots = Vec::new();
|
||||
let interner = DefaultInterner::new();
|
||||
|
||||
let abs_path = fs::canonicalize(package_path)?;
|
||||
|
||||
let (name, relroot) = load_xmlo(
|
||||
let state = load_xmlo(
|
||||
&abs_path.to_str().unwrap().to_string(),
|
||||
&mut fs,
|
||||
&mut fragments,
|
||||
&mut depgraph,
|
||||
&interner,
|
||||
&mut roots,
|
||||
)?
|
||||
.expect("missing root package information");
|
||||
Default::default(),
|
||||
)?;
|
||||
|
||||
// println!(
|
||||
// "Graph {:?}",
|
||||
// depgraph
|
||||
// .graph
|
||||
// .raw_nodes()
|
||||
// .iter()
|
||||
// .map(|node| &node.weight)
|
||||
// .collect::<Vec<_>>()
|
||||
// );
|
||||
let AsgBuilderState {
|
||||
mut roots,
|
||||
name,
|
||||
relroot,
|
||||
found: _,
|
||||
} = state;
|
||||
|
||||
roots.extend(
|
||||
vec!["___yield", "___worksheet"]
|
||||
|
@ -127,31 +121,24 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>(
|
|||
fragments: &mut FxHashMap<&'i str, String>,
|
||||
depgraph: &mut LinkerAsg<'i>,
|
||||
interner: &'i I,
|
||||
roots: &mut Vec<LinkerObjectRef>,
|
||||
) -> LoadResult<'i> {
|
||||
let first = fs.visit_len() == 0;
|
||||
|
||||
state: LinkerAsgBuilderState<'i>,
|
||||
) -> Result<LinkerAsgBuilderState<'i>, Box<dyn Error>> {
|
||||
let cfile: CanonicalFile<BufReader<fs::File>> = match fs.open(path_str)? {
|
||||
VisitOnceFile::FirstVisit(file) => file,
|
||||
VisitOnceFile::Visited => return Ok(None),
|
||||
VisitOnceFile::Visited => return Ok(state),
|
||||
};
|
||||
|
||||
let (path, file) = cfile.into();
|
||||
|
||||
let xmlo: XmloReader<'_, _, _> = (file, interner).into();
|
||||
|
||||
let AsgBuilderResult::<'i, FxBuildHasher, _> {
|
||||
found,
|
||||
roots: mut pkgroots,
|
||||
name,
|
||||
relroot,
|
||||
} = xmlo.build(depgraph, first)?;
|
||||
|
||||
roots.append(&mut pkgroots);
|
||||
let mut state = xmlo.build(depgraph, state)?;
|
||||
|
||||
let mut dir: PathBuf = path.clone();
|
||||
dir.pop();
|
||||
|
||||
let found = state.found.take().unwrap_or_default();
|
||||
|
||||
for relpath in found.iter() {
|
||||
let mut path_buf = dir.clone();
|
||||
path_buf.push(relpath);
|
||||
|
@ -161,14 +148,10 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>(
|
|||
let path_abs = path_buf.canonicalize()?;
|
||||
let path = path_abs.to_str().unwrap();
|
||||
|
||||
load_xmlo(path, fs, fragments, depgraph, interner, roots)?;
|
||||
state = load_xmlo(path, fs, fragments, depgraph, interner, state)?;
|
||||
}
|
||||
|
||||
if first {
|
||||
Ok(Some((name, relroot)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
fn get_ident<'a, 'i>(
|
||||
|
|
|
@ -29,15 +29,16 @@ use std::io::BufRead;
|
|||
|
||||
// TODO error type
|
||||
pub type Result<'i, S, Ix> =
|
||||
std::result::Result<AsgBuilderResult<'i, S, Ix>, Box<dyn Error>>;
|
||||
std::result::Result<AsgBuilderState<'i, S, Ix>, Box<dyn Error>>;
|
||||
|
||||
pub struct AsgBuilderResult<'i, S, Ix>
|
||||
#[derive(Debug, Default)]
|
||||
pub struct AsgBuilderState<'i, S, Ix>
|
||||
where
|
||||
S: BuildHasher + Default,
|
||||
S: BuildHasher,
|
||||
Ix: IndexType,
|
||||
{
|
||||
pub roots: Vec<ObjectRef<Ix>>,
|
||||
pub found: HashSet<&'i str, S>,
|
||||
pub found: Option<HashSet<&'i str, S>>,
|
||||
pub name: Option<&'i Symbol<'i>>,
|
||||
pub relroot: Option<String>,
|
||||
}
|
||||
|
@ -45,13 +46,13 @@ where
|
|||
pub trait AsgBuilder<'i, O, S, Ix>
|
||||
where
|
||||
O: IdentObjectState<'i, O>,
|
||||
S: BuildHasher + Default,
|
||||
S: BuildHasher,
|
||||
Ix: IndexType,
|
||||
{
|
||||
fn build<G: Asg<'i, O, Ix>>(
|
||||
self,
|
||||
graph: &mut G,
|
||||
first: bool,
|
||||
state: AsgBuilderState<'i, S, Ix>,
|
||||
) -> Result<'i, S, Ix>;
|
||||
}
|
||||
|
||||
|
@ -63,27 +64,22 @@ where
|
|||
S: BuildHasher + Default,
|
||||
Ix: IndexType,
|
||||
{
|
||||
// TOOD: remove first
|
||||
fn build<G: Asg<'i, O, Ix>>(
|
||||
mut self,
|
||||
graph: &mut G,
|
||||
first: bool,
|
||||
mut state: AsgBuilderState<'i, S, Ix>,
|
||||
) -> Result<'i, S, Ix> {
|
||||
// TODO
|
||||
let mut found: HashSet<&'i str, S> = Default::default();
|
||||
|
||||
let mut roots = Vec::new();
|
||||
let mut elig = None;
|
||||
let first = state.name.is_none();
|
||||
|
||||
let mut name: Option<&'i Symbol<'i>> = None;
|
||||
let mut relroot: Option<String> = None;
|
||||
let found = state.found.get_or_insert(Default::default());
|
||||
|
||||
loop {
|
||||
match self.read_event() {
|
||||
Ok(XmloEvent::Package(attrs)) => {
|
||||
if first {
|
||||
name = attrs.name;
|
||||
relroot = attrs.relroot;
|
||||
state.name = attrs.name;
|
||||
state.relroot = attrs.relroot;
|
||||
}
|
||||
elig = attrs.elig;
|
||||
}
|
||||
|
@ -135,7 +131,7 @@ where
|
|||
graph.declare(sym, kindval, src)?;
|
||||
|
||||
if link_root {
|
||||
roots.push(node);
|
||||
state.roots.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,16 +164,11 @@ where
|
|||
}
|
||||
|
||||
if let Some(elig_sym) = elig {
|
||||
roots.push(graph.lookup(elig_sym).expect(
|
||||
state.roots.push(graph.lookup(elig_sym).expect(
|
||||
"internal error: package elig references nonexistant symbol",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(AsgBuilderResult {
|
||||
roots,
|
||||
found,
|
||||
name,
|
||||
relroot,
|
||||
})
|
||||
Ok(state)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,4 +77,4 @@
|
|||
pub mod reader;
|
||||
mod asg_builder;
|
||||
|
||||
pub use asg_builder::{AsgBuilder, AsgBuilderResult};
|
||||
pub use asg_builder::{AsgBuilder, AsgBuilderState};
|
||||
|
|
Loading…
Reference in New Issue