use super::super::facts::DataFlowFact;
use super::common::{FnContext, LockAcquisition};
#[derive(Clone, Copy)]
pub(super) struct FlowRange {
start: u32,
end: u32,
}
impl FlowRange {
pub(super) fn new(start: usize, end: usize) -> Self {
Self {
start: start as u32,
end: end as u32,
}
}
pub(super) fn slice<'a>(&self, flows: &'a [DataFlowFact]) -> &'a [DataFlowFact] {
&flows[self.start as usize..self.end as usize]
}
}
pub(super) struct FunctionSummaryData {
pub(super) lock_acquisitions: Box<[LockAcquisition]>,
pub(super) taint: FlowRange,
pub(super) quality: FlowRange,
pub(super) performance: FlowRange,
pub(super) concurrency: FlowRange,
}
pub(super) struct DetectorRanges {
taint: FlowRange,
quality: FlowRange,
performance: FlowRange,
concurrency: FlowRange,
}
impl DetectorRanges {
pub(super) fn into_summary(
self,
lock_acquisitions: Box<[LockAcquisition]>,
) -> FunctionSummaryData {
FunctionSummaryData {
lock_acquisitions,
taint: self.taint,
quality: self.quality,
performance: self.performance,
concurrency: self.concurrency,
}
}
}
pub(super) fn run_detectors(
ctx: &FnContext<'_, '_>,
all_flows: &mut Vec<DataFlowFact>,
) -> DetectorRanges {
let taint = super::taint::detect(ctx);
let quality = super::quality::detect(ctx);
let performance = super::perf::detect(ctx);
let concurrency = super::concurrency::detect(ctx);
DetectorRanges {
taint: append_flows(all_flows, taint),
quality: append_flows(all_flows, quality),
performance: append_flows(all_flows, performance),
concurrency: append_flows(all_flows, concurrency),
}
}
fn append_flows(all: &mut Vec<DataFlowFact>, facts: Box<[DataFlowFact]>) -> FlowRange {
let start = all.len();
all.extend(facts.into_vec());
FlowRange::new(start, all.len())
}
pub struct FunctionAnalysisSummary<'a> {
data: &'a FunctionSummaryData,
flows: &'a [DataFlowFact],
}
impl<'a> FunctionAnalysisSummary<'a> {
pub(super) fn new(data: &'a FunctionSummaryData, flows: &'a [DataFlowFact]) -> Self {
Self { data, flows }
}
pub fn quality_issues(&self) -> &[DataFlowFact] {
self.data.quality.slice(self.flows)
}
pub fn performance_issues(&self) -> &[DataFlowFact] {
self.data.performance.slice(self.flows)
}
pub fn concurrency_issues(&self) -> &[DataFlowFact] {
self.data.concurrency.slice(self.flows)
}
pub fn taint_flows(&self) -> &[DataFlowFact] {
self.data.taint.slice(self.flows)
}
}