use std::collections::BTreeSet;
use pedant_graph::GraphCache;
use super::cache_counting::{
Classification, EXACT_GRAPH_HITS, assert_build_classifies, assert_delta,
};
use super::cache_fixture::{
admitted, assert_clear_keeps_the_held_graph, assert_matches_direct, exact_only, pair,
};
use super::cache_ownership::assert_cache_public_boundary_is_exact;
use super::corpus_revision::{REVISION_CORPUS, REVISION_FRAGMENTS};
use super::fixture::{self, CORPUS_LIBRARY};
use super::inventory::{CACHE_SOURCES, PROJECTION_SOURCES, SOURCES};
use super::ownership_model::GO_VOCABULARY;
use super::scan::{code_only, compact, naming, parsed, source, token_text};
const CACHE_ENTRY: &str = "src/rust/cache.rs";
const RETENTION_SPELLINGS: &[&str] = &[
"crate::cache",
"GraphCache",
"CachedCodeGraph",
"CachedGraphState",
"BoundedStore",
"CacheCategory",
"CacheCounters",
"CacheEvent",
];
const RETENTION_OWNER: &str = "src/rust/reuse.rs";
const NEUTRAL_RETAINED_IMPORT: &str = "use crate::projection::draft::SourceFragment;";
const RETAINED_ENTRIES: &str = "BoundedStore<SourceKey,Arc<SourceFragment>>";
const RETAINED_RECORD: &str = "SourceFragment";
const MODULE_ROOT: &str = "src/lib.rs";
const CACHE_MODULE: &str = "cache";
const SELECTION: &str = "feature";
pub fn assert_cache_remains_rust_only() {
assert_cache_public_boundary_is_exact();
assert_no_cache_source_names_another_language();
assert_no_selection_reaches_the_cache();
assert_only_the_adapter_entry_names_a_resolution();
assert_the_neutral_family_holds_no_retention();
assert_retention_reuses_the_neutral_draft();
assert_retained_answers_are_exact();
}
fn assert_the_neutral_family_holds_no_retention() {
let offenders = naming(PROJECTION_SOURCES, RETENTION_SPELLINGS, "the retention");
assert!(
offenders.is_empty(),
"the neutral projection family holds a retention of its own: {offenders:?}"
);
}
fn assert_retention_reuses_the_neutral_draft() {
let owner = code_only(source(RETENTION_OWNER));
assert!(
owner.contains(NEUTRAL_RETAINED_IMPORT),
"{RETENTION_OWNER} retains what the neutral family declares: {NEUTRAL_RETAINED_IMPORT}"
);
assert!(
compact(source(RETENTION_OWNER)).contains(RETAINED_ENTRIES),
"{RETENTION_OWNER} retains its entries as {RETAINED_ENTRIES}"
);
let offenders: Vec<&str> = SOURCES
.iter()
.filter(|held| CACHE_SOURCES.contains(&held.path))
.filter(|held| code_only(held.text).contains(RETAINED_RECORD))
.map(|held| held.path)
.collect();
assert!(
offenders.is_empty(),
"a cache module names the retained record it only holds: {offenders:?}"
);
}
fn assert_no_cache_source_names_another_language() {
let offenders = naming(&cache_surface(), GO_VOCABULARY, "the Go spelling");
assert!(
offenders.is_empty(),
"the cache surface names a language it retains nothing for: {offenders:?}"
);
}
fn cache_surface() -> Vec<&'static str> {
CACHE_SOURCES
.iter()
.copied()
.chain(std::iter::once(CACHE_ENTRY))
.collect()
}
fn assert_no_selection_reaches_the_cache() {
let selected: Vec<&str> = cache_surface()
.into_iter()
.filter(|path| compact(source(path)).contains(SELECTION))
.collect();
assert!(
selected.is_empty(),
"the cache surface states a selection it could be gated by: {selected:?}"
);
let declaration = parsed(MODULE_ROOT)
.items
.into_iter()
.find_map(|item| match item {
syn::Item::Mod(module) if module.ident == CACHE_MODULE => Some(module),
_ => None,
})
.unwrap_or_else(|| panic!("{MODULE_ROOT} declares no mod {CACHE_MODULE}"));
let conditions: Vec<String> = declaration
.attrs
.iter()
.map(token_text)
.filter(|attribute| attribute.contains(SELECTION))
.collect();
assert!(
conditions.is_empty(),
"{MODULE_ROOT} admits mod {CACHE_MODULE} whatever the build selects: {conditions:?}"
);
}
fn assert_only_the_adapter_entry_names_a_resolution() {
let entry = code_only(source(CACHE_ENTRY));
for required in [
"RustResolutionSnapshot",
"RustTargetResolution",
"build_rust_graph",
] {
assert!(
entry.contains(required),
"{CACHE_ENTRY} states the Rust claim it retains: {required}"
);
}
let published: BTreeSet<&str> = SOURCES
.iter()
.filter(|held| CACHE_SOURCES.contains(&held.path))
.filter(|held| code_only(held.text).contains("pub fn build_"))
.map(|held| held.path)
.collect();
assert!(
published.is_empty(),
"no language-neutral cache module publishes a builder: {published:?}"
);
}
fn assert_retained_answers_are_exact() {
let subject = "the retained Rust claim";
let (_repository, base) = fixture::resolve_target(REVISION_CORPUS, CORPUS_LIBRARY);
let mut cache = GraphCache::new(exact_only(64));
let held = assert_build_classifies(
&mut cache,
pair(&base),
Classification::retained(0, REVISION_FRAGMENTS),
subject,
);
assert_matches_direct(held.graph(), pair(&base), subject);
let before = cache.stats();
let repeated = admitted(&mut cache, pair(&base), &format!("{subject}, repeated"));
assert_delta(
before,
cache.stats(),
&[(EXACT_GRAPH_HITS, 1)],
&format!("{subject}, repeated"),
);
assert!(
std::ptr::eq(held.graph(), repeated.graph()),
"{subject}: an equal claim is answered from the retained graph"
);
assert_clear_keeps_the_held_graph(&mut cache, &base, &held, subject);
}