use crate::compiling;
use crate::{Diagnostics, Options};
use runestick::{Context, Unit};
use std::rc::Rc;
use thiserror::Error;
mod source_loader;
mod sources;
pub use self::source_loader::{FileSourceLoader, SourceLoader};
pub use self::sources::Sources;
#[derive(Debug, Error)]
#[error("failed to load sources (see `errors` for details)")]
pub struct LoadSourcesError;
pub fn load_sources(
context: &Context,
options: &Options,
sources: &mut Sources,
diagnostics: &mut Diagnostics,
) -> Result<Unit, LoadSourcesError> {
let visitor = Rc::new(compiling::NoopCompileVisitor::new());
let source_loader = Rc::new(FileSourceLoader::new());
load_sources_with_visitor(
context,
options,
sources,
diagnostics,
visitor,
source_loader,
)
}
pub fn load_sources_with_visitor<'a>(
context: &Context,
options: &Options,
sources: &mut Sources,
diagnostics: &mut Diagnostics,
visitor: Rc<dyn compiling::CompileVisitor>,
source_loader: Rc<dyn SourceLoader + 'a>,
) -> Result<Unit, LoadSourcesError> {
let unit = if context.has_default_modules() {
compiling::UnitBuilder::with_default_prelude()
} else {
compiling::UnitBuilder::default()
};
let result = compiling::compile_with_options(
&*context,
sources,
&unit,
diagnostics,
&options,
visitor,
source_loader,
);
if let Err(()) = result {
return Err(LoadSourcesError);
}
if options.link_checks {
unit.link(&*context, diagnostics);
if diagnostics.has_error() {
return Err(LoadSourcesError);
}
}
match unit.build() {
Ok(unit) => Ok(unit),
Err(error) => {
diagnostics.error(0, error);
Err(LoadSourcesError)
}
}
}