use std::collections::{BTreeMap, BTreeSet};
use crate::boilerplate::{self, Boilerplate};
use crate::candidate::{self, CandidateConfig, CandidateStats};
use crate::clone_class::CloneClass;
use crate::conditional::ArmPath;
use crate::control_flow::{self, ControlFlowConfig, ControlFlowStats};
use crate::discovery::{BuildVariant, Language};
use crate::engine::{LiteralNorm, normalize::Resolution};
use crate::features::{self, FileFeatures};
use crate::frontend::{Lexeme, Token, TokenKind, UnitKind};
use crate::grouping::{
self, GroupingConfig, GroupingSet, GroupingStats, GroupingUnit, SimilarityEdge,
};
use crate::ir::{ByteRange, IrNode, Shape, SyntaxIrFile};
use crate::maximal::{self, MaximalConfig, RegionSide, RegionStats, SharedRegion};
use crate::near_match::{self, NearMatchConfig, NearMatchStats};
use crate::stable_id::{
self, CloneGroupFingerprint, ContentNorm, CrossVariantComparisonId, CrossVariantGroupId,
FileContext, FragmentFingerprint, UnitFingerprint,
};
use crate::substitution;
use crate::test_code::{self, TestCodeEvidence};
use crate::types::{ApiEvidence, TypeEvidence, TypeTag};
use crate::verify::{self, SimilarityBreakdown, UnitView, VerifyConfig};
mod analysis;
mod evidence;
mod model;
mod pairs;
mod regions;
mod reporting;
mod siblings;
mod units;
use evidence::{UnitEvidence, token_count_meets_minimum, unit_evidence, unit_meets_minimum};
use pairs::{lift_to_unit_pairs, unrepresented_pairs};
use regions::{confirm_regions, drop_subsumed, grow_runs};
use reporting::{dominant_boilerplate_members, group_detail, written_once_per_width_members};
use siblings::sweep_siblings;
use units::{flatten_units, line_range, view};
#[cfg(test)]
use regions::{Confirmed, covers_run, merge_adjacent};
#[cfg(test)]
use reporting::{dominant_boilerplate, is_allocation_api, set_jaccard};
pub use analysis::*;
pub use evidence::*;
pub use model::*;
pub use reporting::span_identifier_jaccard;
struct Unit {
file: usize,
local: usize,
kind: UnitKind,
statements: Vec<crate::ir::StatementSummary>,
fingerprint: UnitFingerprint,
content: FragmentFingerprint,
normalized_content: FragmentFingerprint,
range: ByteRange,
lines: (u32, u32),
tokens: (usize, usize),
name: Option<Lexeme>,
boilerplate: Option<Boilerplate>,
test_code: bool,
test_code_evidence: Option<TestCodeEvidence>,
arms: ArmPath,
}
impl Unit {
const fn group_content(&self, class: CloneClass) -> FragmentFingerprint {
if matches!(class, CloneClass::Type1) {
self.content
} else {
self.normalized_content
}
}
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests;