use std::sync::Arc;
use mir_issues::Issue;
use php_ast::ast::Program;
use php_rs_parser::source_map::SourceMap;
use crate::pass2::Pass2Driver;
use crate::session::AnalysisSession;
use crate::symbol::ResolvedSymbol;
pub struct FileAnalysis {
pub issues: Vec<Issue>,
pub symbols: Vec<ResolvedSymbol>,
}
impl FileAnalysis {
pub fn symbol_at(&self, byte_offset: u32) -> Option<&ResolvedSymbol> {
self.symbols
.iter()
.filter(|s| s.span.start <= byte_offset && byte_offset < s.span.end)
.min_by_key(|s| s.span.end - s.span.start)
}
}
pub struct FileAnalyzer<'a> {
session: &'a AnalysisSession,
}
impl<'a> FileAnalyzer<'a> {
pub fn new(session: &'a AnalysisSession) -> Self {
Self { session }
}
pub fn analyze(
&self,
file: Arc<str>,
source: &str,
program: &Program<'_, '_>,
source_map: &SourceMap,
) -> FileAnalysis {
self.session.ensure_essential_stubs_loaded();
self.session.ensure_stubs_for_source(source);
let db = self.session.snapshot_db();
let driver = Pass2Driver::new(&db, self.session.php_version());
let (issues, symbols) = driver.analyze_bodies(program, file, source, source_map);
FileAnalysis { issues, symbols }
}
}