hax_rust_engine/
backends.rs1pub mod fstar;
18pub mod lean;
19pub mod rust;
20
21use std::{collections::HashMap, rc::Rc};
22
23use crate::{
24 ast::{Item, Metadata, Module, span::Span},
25 attributes::LinkedItemGraph,
26 phase::legacy::group_consecutive_ocaml_phases,
27 printer::{HasLinkedItemGraph, Print, Printer},
28};
29use camino::Utf8PathBuf;
30use hax_types::engine_api::File;
31
32pub trait Backend {
42 type Printer: Printer;
44
45 fn printer(&self, linked_item_graph: Rc<LinkedItemGraph>) -> Self::Printer {
49 Self::Printer::default().with_linked_item_graph(linked_item_graph)
50 }
51
52 const NAME: &'static str = Self::Printer::NAME;
56
57 fn phases(&self) -> Vec<crate::phase::PhaseKind> {
62 vec![]
63 }
64
65 fn resugaring_phases() -> Vec<Box<dyn prelude::Resugaring>> {
67 vec![]
68 }
69
70 fn items_to_module(&self, items: Vec<Item>) -> Vec<Module> {
72 let mut modules: HashMap<_, Vec<_>> = HashMap::new();
73 for item in items {
74 let module_ident = item.ident.mod_only_closest_parent();
75 modules.entry(module_ident).or_default().push(item);
76 }
77 modules
78 .into_iter()
79 .map(|(ident, items)| Module {
80 ident,
81 items,
82 meta: Metadata {
83 span: Span::dummy(),
84 attributes: vec![],
85 },
86 })
87 .collect()
88 }
89
90 fn modules_to_files(&self, modules: Vec<Module>, mut printer: Self::Printer) -> Vec<File> {
92 modules
93 .into_iter()
94 .map(|module: Module| {
95 let path = self.module_path(&module).into_string();
96 let (contents, _) = printer.print(module);
97 File {
98 path,
99 contents,
100 sourcemap: None,
101 }
102 })
103 .collect()
104 }
105
106 fn module_path(&self, module: &Module) -> Utf8PathBuf;
108}
109
110impl<B: Backend> crate::phase::Phase for B {
112 fn apply(&self, items: &mut Vec<Item>) {
113 for phase in group_consecutive_ocaml_phases(self.phases()) {
114 phase.apply(items);
115 }
116 }
117}
118
119pub fn apply_backend<B: Backend + 'static>(backend: B, mut items: Vec<Item>) -> Vec<File> {
125 crate::phase::Phase::apply(&backend, &mut items);
126
127 for mut resugaring_phase in B::resugaring_phases() {
128 for item in &mut items {
129 resugaring_phase.visit(item)
130 }
131 }
132
133 let linked_items_graph = Rc::new(LinkedItemGraph::new(
134 &items,
135 prelude::diagnostics::Context::Printer(B::NAME.into()),
136 ));
137
138 fn drop_skip_late_items(items: &mut Vec<Item>) {
144 items.retain_mut(|item| {
145 use hax_lib_macros_types::{AttrPayload, ItemStatus};
146 !item.meta.hax_attributes().any(|attr| {
147 matches!(
148 attr,
149 AttrPayload::ItemStatus(ItemStatus::Included { late_skip: true })
150 )
151 })
152 });
153 }
154
155 drop_skip_late_items(&mut items);
156
157 let modules = backend.items_to_module(items);
158 let printer = backend.printer(linked_items_graph.clone());
159 backend.modules_to_files(modules, printer)
160}
161
162mod prelude {
163 pub use super::Backend;
168 pub use crate::ast::{identifiers::global_id::view::AnyKind, literals::*, resugared::*, *};
169 pub use crate::printer::{
170 pretty_ast::{DocBuilder, PrettyAst, ToDocument, install_pretty_helpers},
171 render_view::*,
172 *,
173 };
174 pub use crate::resugarings::*;
175 pub use crate::symbol::Symbol;
176 pub use hax_rust_engine_macros::{prepend_associated_functions_with, setup_printer_struct};
177}