use std::cell::OnceCell;
use marker_adapter::{Adapter, LintCrateInfo};
use marker_api::Lint;
use crate::context::{storage::Storage, RustcContext};
thread_local! {
static ADAPTER: OnceCell<Adapter> = OnceCell::new();
}
pub struct RustcLintPass;
impl RustcLintPass {
#[allow(clippy::missing_errors_doc)]
pub fn init_adapter(lint_crates: &[LintCrateInfo]) -> Result<(), marker_adapter::Error> {
ADAPTER.with(move |cell| {
cell.get_or_try_init(|| Adapter::new(lint_crates))?;
Ok(())
})
}
#[must_use]
pub fn marker_lints() -> Vec<&'static Lint> {
ADAPTER.with(|adapter| adapter.get().unwrap().marker_lints())
}
}
rustc_lint_defs::impl_lint_pass!(RustcLintPass => []);
impl<'tcx> rustc_lint::LateLintPass<'tcx> for RustcLintPass {
fn check_crate(&mut self, rustc_cx: &rustc_lint::LateContext<'tcx>) {
ADAPTER.with(|adapter| {
process_crate(rustc_cx, adapter.get().unwrap());
});
}
}
pub fn process_crate(rustc_cx: &rustc_lint::LateContext<'_>, adapter: &Adapter) {
let storage = Storage::default();
process_crate_lifetime(rustc_cx, &storage, adapter);
}
fn process_crate_lifetime<'ast, 'tcx: 'ast>(
rustc_cx: &rustc_lint::LateContext<'tcx>,
storage: &'ast Storage<'ast>,
adapter: &Adapter,
) {
let driver_cx = RustcContext::new(rustc_cx.tcx, rustc_cx.lint_store, storage);
marker_api::context::set_ast_cx(driver_cx.ast_cx());
let krate = driver_cx.marker_converter.local_crate();
adapter.process_krate(driver_cx.ast_cx(), krate);
}