use std::path::Path;
#[derive(Clone, Copy)]
pub(crate) struct SourceCompilerAuthority {
trusted_host_dispatch: bool,
}
pub(crate) struct ImportedSymbols {
pub(crate) enum_candidates: Vec<String>,
pub(crate) callable_names: Vec<String>,
}
impl SourceCompilerAuthority {
pub(crate) fn for_source(path: &Path) -> Self {
Self {
trusted_host_dispatch: trusted_host_dispatch_for_source(path),
}
}
pub(crate) fn typechecker(self) -> harn_parser::TypeChecker {
harn_parser::TypeChecker::new().with_privileged_wire_builtins(self.trusted_host_dispatch)
}
pub(crate) fn compiler_with_imported_enums(
self,
candidates: impl IntoIterator<Item = String>,
) -> harn_vm::Compiler {
let compiler = if self.trusted_host_dispatch {
harn_vm::Compiler::new_trusted_host_dispatch()
} else {
harn_vm::Compiler::new()
};
compiler.with_imported_enum_candidates(candidates)
}
pub(crate) fn compiler_with_imported_symbols(
self,
enum_candidates: impl IntoIterator<Item = String>,
callable_names: impl IntoIterator<Item = String>,
) -> harn_vm::Compiler {
self.compiler_with_imported_enums(enum_candidates)
.with_imported_source_callable_names(callable_names)
}
pub(crate) fn compile_module_with_imported_symbols(
self,
source_path: &Path,
source: &str,
enum_candidates: impl IntoIterator<Item = String>,
callable_names: impl IntoIterator<Item = String>,
) -> Result<harn_vm::module_artifact::ModuleArtifact, harn_vm::VmError> {
if self.trusted_host_dispatch {
harn_vm::module_artifact::compile_trusted_host_dispatch_module_artifact_from_source_with_imported_symbols(
source_path,
source,
enum_candidates,
callable_names,
)
} else {
harn_vm::module_artifact::compile_module_artifact_from_source_with_imported_symbols(
source_path,
source,
enum_candidates,
callable_names,
)
}
}
}
pub(crate) fn ensure_builtin_signatures_installed() {
harn_parser::install_builtin_manifest(harn_vm::stdlib::all_builtin_manifest());
}
pub(crate) fn compiler_for_source(path: &Path, source: &str) -> harn_vm::Compiler {
let imported = imported_symbols_for_source(path, source);
SourceCompilerAuthority::for_source(path)
.compiler_with_imported_symbols(imported.enum_candidates, imported.callable_names)
}
pub(crate) fn imported_symbols_for_source(path: &Path, source: &str) -> ImportedSymbols {
let graph = harn_modules::build_with_source(path, source);
ImportedSymbols {
enum_candidates: graph
.imported_names_by_kind_for_file(path, harn_modules::DefKind::Enum)
.unwrap_or_default()
.into_iter()
.collect(),
callable_names: graph
.imported_callable_names_for_file(path)
.unwrap_or_default()
.into_iter()
.collect(),
}
}
pub(crate) fn trusted_host_dispatch_for_source(path: &Path) -> bool {
let absolute = path
.canonicalize()
.unwrap_or_else(|_| std::env::current_dir().unwrap_or_default().join(path));
crate::package::load_check_config(Some(&absolute)).trusted_host_dispatch
}
pub(crate) fn enable_trusted_host_dispatch_for_source(
vm: &mut harn_vm::Vm,
path: &Path,
) -> Result<(), harn_vm::VmError> {
if !trusted_host_dispatch_for_source(path) {
return Ok(());
}
vm.enable_trusted_host_dispatch()?;
Ok(())
}
pub(crate) fn compiler_with_imported_enum_candidates(
candidates: impl IntoIterator<Item = String>,
) -> harn_vm::Compiler {
harn_vm::Compiler::new().with_imported_enum_candidates(candidates)
}