pub mod fstar;
pub mod lean;
pub mod rust;
use std::{collections::HashMap, rc::Rc};
use crate::{
ast::{Item, Metadata, Module, span::Span},
attributes::LinkedItemGraph,
phase::legacy::group_consecutive_ocaml_phases,
printer::{HasLinkedItemGraph, Print, Printer},
};
use camino::Utf8PathBuf;
use hax_types::engine_api::File;
pub trait Backend {
type Printer: Printer;
fn printer(&self, linked_item_graph: Rc<LinkedItemGraph>) -> Self::Printer {
Self::Printer::default().with_linked_item_graph(linked_item_graph)
}
const NAME: &'static str = Self::Printer::NAME;
fn phases(&self) -> Vec<crate::phase::PhaseKind> {
vec![]
}
fn resugaring_phases() -> Vec<Box<dyn prelude::Resugaring>> {
vec![]
}
fn items_to_module(&self, items: Vec<Item>) -> Vec<Module> {
let mut modules: HashMap<_, Vec<_>> = HashMap::new();
for item in items {
let module_ident = item.ident.mod_only_closest_parent();
modules.entry(module_ident).or_default().push(item);
}
modules
.into_iter()
.map(|(ident, items)| Module {
ident,
items,
meta: Metadata {
span: Span::dummy(),
attributes: vec![],
},
})
.collect()
}
fn modules_to_files(&self, modules: Vec<Module>, mut printer: Self::Printer) -> Vec<File> {
modules
.into_iter()
.map(|module: Module| {
let path = self.module_path(&module).into_string();
let (contents, _) = printer.print(module);
File {
path,
contents,
sourcemap: None,
}
})
.collect()
}
fn module_path(&self, module: &Module) -> Utf8PathBuf;
}
impl<B: Backend> crate::phase::Phase for B {
fn apply(&self, items: &mut Vec<Item>) {
for phase in group_consecutive_ocaml_phases(self.phases()) {
phase.apply(items);
}
}
}
pub fn apply_backend<B: Backend + 'static>(backend: B, mut items: Vec<Item>) -> Vec<File> {
crate::phase::Phase::apply(&backend, &mut items);
for mut resugaring_phase in B::resugaring_phases() {
for item in &mut items {
resugaring_phase.visit(item)
}
}
let linked_items_graph = Rc::new(LinkedItemGraph::new(
&items,
prelude::diagnostics::Context::Printer(B::NAME.into()),
));
fn drop_skip_late_items(items: &mut Vec<Item>) {
items.retain_mut(|item| {
use hax_lib_macros_types::{AttrPayload, ItemStatus};
!item.meta.hax_attributes().any(|attr| {
matches!(
attr,
AttrPayload::ItemStatus(ItemStatus::Included { late_skip: true })
)
})
});
}
drop_skip_late_items(&mut items);
let modules = backend.items_to_module(items);
let printer = backend.printer(linked_items_graph.clone());
backend.modules_to_files(modules, printer)
}
mod prelude {
pub use super::Backend;
pub use crate::ast::{identifiers::global_id::view::AnyKind, literals::*, resugared::*, *};
pub use crate::printer::{
pretty_ast::{DocBuilder, PrettyAst, ToDocument, install_pretty_helpers},
render_view::*,
*,
};
pub use crate::resugarings::*;
pub use crate::symbol::Symbol;
pub use hax_rust_engine_macros::{prepend_associated_functions_with, setup_printer_struct};
}