1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Per-fixture, per-language exclusion checks the snippet driver's `expected` gate consults
//! before a coverage cell is ever pushed.
//!
//! Split out of `mod.rs` to keep that file under the repo's per-file line cap: these three
//! predicates share no state with the rest of the driver beyond [`super::SnippetRenderContext`]
//! and [`super::DocumentationLanguage`], which they take as ordinary parameters.
use ;
use crateLanguage;
use crateFixture;
/// Whether the function a fixture's call resolves to for `language` is excluded for that
/// language, and therefore can never be rendered into a snippet.
///
/// Reuses [`crate::docs::language_pages::excludes::language_excludes`] -- the accessor the
/// docs generator already consults for the same question -- rather than re-deriving the
/// per-language `exclude_functions` union here. A second copy of that rule is exactly how a
/// ledger and its emitter drift apart: one path evolves (a language gains an override, a new
/// per-language config field is added) and the other silently keeps checking the old shape.
/// [`CallConfig::core_lookup_name`] gives the Rust-spelled identity `exclude_functions`
/// entries are keyed by, matching every built-in snippet recipe's own resolution (see
/// `e2e/codegen/go/snippet.rs`, `kotlin/snippet.rs`, `php/snippet.rs`, `ruby/snippet.rs`, and
/// the WASM-specific `rust_identity_for_wasm_symbol`, which resolves the same identity for the
/// one target that also accepts the JS spelling of an override). ~keep
pub
/// Whether `fixture` exercises the fixture engine's generic visitor/trait-bridge entry point
/// ([`Fixture::visitor`]) and this language excludes it via the
/// [`crate::e2e::fixture::VISITOR_EXCLUDE_FUNCTION_NAME`] convention.
///
/// `exclude_functions` normally names a real Rust function, so
/// [`function_excluded_for_language`] cannot catch this case: a visitor fixture's *call*
/// resolves to some ordinary function (e.g. `convert`), while the visitor itself attaches
/// through a trait-bridge parameter or options-struct field that never has its own IR function
/// name. `e2e::codegen::kotlin_android::project` already applies this exact rule when deciding
/// whether to emit a fixture's Kotlin-Android e2e test or fall back to
/// `ExcludedBindingsTest.kt`; without the matching check here, snippet generation rendered real
/// code against a visitor API the binding never exposed for that language. ~keep
pub
/// Whether the function or method a fixture's call resolves to for `language` is
/// `binding_excluded` in the IR -- i.e. marked `#[alef::skip]`/`#[doc(hidden)]` at
/// extraction time, which excludes it from every generated binding regardless of what
/// `alef.toml` configures.
///
/// This is deliberately separate from [`function_excluded_for_language`]: that helper
/// only ever consults `alef.toml`-configured `exclude_functions` lists via
/// [`crate::docs::language_pages::excludes::language_excludes`], which never reads
/// `FunctionDef::binding_excluded` / `MethodDef::binding_excluded` at all -- see
/// `src/snippets/gaps.rs`'s `LedgerExpectations` doc comment, which documented this exact
/// gap before this function closed it. Without this check a function a Rust author
/// explicitly opted out of every binding still entered `coverage.expected` for every
/// non-Rust language, and the snippet coverage ledger reported the resulting absence as a
/// gap the consumer has no `alef.toml` knob to silence -- it was never a gap.
///
/// Mirrors the `lang == Language::Rust || !binding_excluded` rule
/// `docs::language_pages::mod::generate_lang_doc` already applies for the same flag: the
/// Rust documentation page still lists a `binding_excluded` item (it exists in Rust
/// source, it is just not exposed to other-language bindings), so `"rust"` is carved out
/// here too and never treated as excluded.
///
/// Resolution mirrors [`crate::e2e::codegen::call_ir::CallIr::signature`]'s
/// free-function-first, then agreeing-methods fallback, but answers the `binding_excluded`
/// question instead of a signature: a free function of the resolved name wins
/// unambiguously (a crate has at most one `pub fn` of a given path), and when only methods
/// match, every same-named method across every type must agree on the flag or this
/// answers `false` (not excluded) rather than guessing. This mirrors `CallIr::signature`'s
/// conservatism on disagreement -- "learned nothing" -- deliberately: treating
/// disagreement as excluded would drop a cell that is still fully bindable through at
/// least one of the disagreeing types, which is worse than occasionally letting a
/// genuinely-excluded cell surface as a coverage gap a human can then triage with a
/// `docs.coverage_exceptions` entry. ~keep
pub