always return dependencies, even when hitting an error

This commit is contained in:
2022-03-05 21:02:58 +01:00
parent 896385654a
commit 557c3a8426
2 changed files with 59 additions and 53 deletions

View File

@@ -28,65 +28,71 @@ pub struct CompiledModule {
pub dependencies: Vec<PathBuf>, pub dependencies: Vec<PathBuf>,
} }
pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> Result<CompiledModule> { pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> (Result<Vec<u8>>, Vec<PathBuf>) {
let mut dependencies = HashSet::new(); fn compile_file_inner(
path: &Path,
options: Options,
dependencies: &mut HashSet<PathBuf>,
) -> Result<Vec<u8>> {
let mut script = ast::Script::default();
let path = path.as_ref(); let mut sources = Sources::new();
let mut script = ast::Script::default();
let mut sources = Sources::new(); let mut pending_files = vec![(path.to_path_buf(), None)];
while let Some((path, span)) = pending_files.pop() {
match sources.add(&path) {
Ok((id, true)) => {
dependencies.insert(path.clone());
let mut new_script = match parser::parse(&sources, id) {
Ok(script) => script,
Err(_) => bail!("Parse failed"),
};
let mut pending_files = vec![(path.to_path_buf(), None)]; includes::resolve_includes(&mut new_script, dependencies, &path)?;
while let Some((path, span)) = pending_files.pop() {
match sources.add(&path) {
Ok((id, true)) => {
dependencies.insert(path.clone());
let mut new_script = match parser::parse(&sources, id) {
Ok(script) => script,
Err(_) => bail!("Parse failed"),
};
includes::resolve_includes(&mut new_script, &mut dependencies, &path)?; for include in std::mem::take(&mut new_script.includes) {
let mut path = path
.parent()
.expect("Script path has no parent")
.to_path_buf();
path.push(include.path);
pending_files.push((path, Some(include.span)));
}
for include in std::mem::take(&mut new_script.includes) { script.merge(new_script);
let mut path = path
.parent()
.expect("Script path has no parent")
.to_path_buf();
path.push(include.path);
pending_files.push((path, Some(include.span)));
} }
Ok((_, false)) => (), // already parsed this include
script.merge(new_script); Err(err) => {
} if let Some(span) = span {
Ok((_, false)) => (), // already parsed this include let _ = typecheck::report_error(&err.to_string(), &span, &sources);
Err(err) => { } else {
if let Some(span) = span { eprintln!("Failed to load script {}: {}", path.display(), err);
let _ = typecheck::report_error(&err.to_string(), &span, &sources); }
} else { bail!("Parse failed");
eprintln!("Failed to load script {}: {}", path.display(), err);
} }
bail!("Parse failed");
} }
} }
if constfold::fold_script(&mut script, &sources).is_err() {
bail!("Constant folding failed");
}
if typecheck::tc_script(&mut script, &sources).is_err() {
bail!("Type check failed");
}
let wasm = emit::emit(
&script,
&path
.file_stem()
.unwrap_or_else(|| OsStr::new("unknown"))
.to_string_lossy(),
&options,
);
Ok(wasm)
} }
if constfold::fold_script(&mut script, &sources).is_err() { let mut dependencies = HashSet::new();
bail!("Constant folding failed");
} let result = compile_file_inner(path.as_ref(), options, &mut dependencies);
if typecheck::tc_script(&mut script, &sources).is_err() {
bail!("Type check failed"); (result, dependencies.into_iter().collect())
}
let wasm = emit::emit(
&script,
&path
.file_stem()
.unwrap_or_else(|| OsStr::new("unknown"))
.to_string_lossy(),
&options,
);
Ok(CompiledModule {
wasm,
dependencies: dependencies.into_iter().collect(),
})
} }

View File

@@ -15,12 +15,12 @@ fn main() -> Result<()> {
let mut filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?; let mut filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
let module = compile_file(&filename, options)?; let wasm = compile_file(&filename, options).0?;
wasmparser::validate(&module.wasm)?; wasmparser::validate(&wasm)?;
filename.set_extension("wasm"); filename.set_extension("wasm");
File::create(filename)?.write_all(&module.wasm)?; File::create(filename)?.write_all(&wasm)?;
Ok(()) Ok(())
} }