use std::path::{Path, PathBuf};
use harn_vm::bytecode_cache::PrecompiledInterface;
use crate::compiler_context::SourceCompilerAuthority;
pub(super) struct ArtifactKeys {
pub(super) entry: harn_vm::bytecode_cache::CacheKey,
pub(super) module: harn_vm::bytecode_cache::CacheKey,
}
impl ArtifactKeys {
pub(super) fn match_artifacts_at(&self, entry_dest: &Path, module_dest: &Path) -> bool {
harn_vm::bytecode_cache::entry_artifact_at_matches(entry_dest, &self.entry)
&& harn_vm::bytecode_cache::module_artifact_at_matches(module_dest, &self.module)
}
}
pub(super) fn artifact_keys(
source_path: &Path,
source: &str,
source_root: Option<&Path>,
authority: &SourceCompilerAuthority,
interface_dest: &Path,
) -> Result<(ArtifactKeys, PrecompiledInterface), String> {
let mut interface =
harn_vm::bytecode_cache::prepare_precompiled_interface(interface_dest, source_path, source)
.map_err(|e| format!("prepare {}: {e}", interface_dest.display()))?;
if !interface.package_import_aliases().is_empty() {
let graph = harn_modules::build_with_source(source_path, source);
crate::package::ensure_reachable_dependencies_materialized(source_path, &graph)
.map_err(|e| e.to_string())?;
interface = harn_vm::bytecode_cache::prepare_precompiled_interface(
interface_dest,
source_path,
source,
)
.map_err(|e| e.to_string())?;
}
let aliases = crate::package::declared_package_import_aliases(
source_path,
interface.package_import_aliases(),
)
.map_err(|e| e.to_string())?;
let digest = crate::package::reachable_dependency_lock_digest(source_path, &aliases)
.map_err(|e| e.to_string())?;
interface.set_package_authority(aliases, digest);
let entry = if source_root.is_some() {
harn_vm::bytecode_cache::CacheKey::from_relocatable_source(source_path, source)
} else {
harn_vm::bytecode_cache::CacheKey::from_source(source_path, source)
};
let module_source = harn_vm::module_source::ModuleSource::from_text(source);
let module = harn_vm::bytecode_cache::CacheKey::from_module_source(
&module_source,
interface.context(),
authority.module_provenance(),
);
Ok((ArtifactKeys { entry, module }, interface))
}
pub(super) enum Outcome {
Compiled(PathBuf),
Reused(PathBuf),
}
impl Outcome {
pub(super) fn destination(&self) -> &PathBuf {
match self {
Outcome::Compiled(path) | Outcome::Reused(path) => path,
}
}
}