Skip to main content

Module analysis

Module analysis 

Source
Expand description

The project-level analysis entry point (P4.1, #1115): discovery (bynk-project) → parse → resolve → check, returning the bynk-ide-facing analogue of bynk-emit’s ProjectAnalysis — without ever emitting.

bynk-ide is repointed at analyse_project as of P4.2 (#1122) — bynk_emit::project::analyse_project_with is no longer reachable from bynk-ide at all (it has no bynk-emit dependency left). This entry point is what every real caller uses today; the differential fixture (bynk-check/tests/differential_analysis.rs) still pins it against analyse_project_with directly (both remain real, exercised paths — bynk-emit’s own CLI build still drives run_checks), so a future divergence between the two is still caught even though only one of them feeds the editor now.

§The residual gap

This entry point was diagnostically faithful to bynk-emit’s run_checks’s Mode::Analyse arm minus seven categories of whole-project checking at P4.2 (recorded on the tracking issue’s own scope-correction comments, not silently assumed). Categories 2, 3, 4 and 6 closed at P5.0/P5.1/P5.2 (design/tracks/semantics-in-the-checker.md §6) — crate::project_model::phase_messages_bundles/ crate::project_model::phase_locale_bundle_ambiguity/ crate::project_model::phase_event_subscriptions/ crate::project_model::phase_function_type_boundaries are now called from analyse_project at the same points run_checks calls them. Categories 1 and 5 closed at P5.3, structurally rather than observably — both were already unreachable from the editor before P4.2 even shipped, so porting them changed nothing observable. Category 7 closed at P5.4, the last of the seven and the one this doc comment’s own author flagged as needing more care (§9 of the design doc) — see below. All seven categories are now closed:

  1. Schema-registry reconciliationclosed at P5.3. crate::schema_registry::reconcile is now called from analyse_project, right after crate::project_model::phase_validate_providers (the same relative point run_checks calls it). Still unreachable on this path — it only ever fires under SchemaLock::On, and this entry point has no on-disk lock concept at all, so it always reconciles against an empty registry, which every event baselines against silently — so relocating it changed nothing observable; it now simply originates in bynk-check, per R3.5.
  2. messages bundle validationclosed at P5.0, see above.
  3. Locale bundle ambiguityclosed at P5.0, see above.
  4. Event-subscription validationclosed at P5.1, see above.
  5. Platform-lock enforcementclosed at P5.3. crate::project_model::phase_platform_lock is now called from analyse_project, right after the per-unit compose/check loop (the same relative point run_checks calls it, gated the same way on a clean error sink so far). Still unreachable on this path, for the same reason as before the relocation: analyse_project hardcodes Platform::default() (Cloudflare) and BuildTarget::Bundle, and bynk.cloudflare is the only platform-native unit that exists (firstparty::platform_of) — so lock_violation can never find a native platform disagreeing with the selected one, for any project, on this path. No fixture can observe this category regressing (or improving) because it never fired through this path to begin with, both before and after this relocation.
  6. Function-type-boundary checksclosed at P5.2. Formerly reached, in bynk-emit, only through phase_group’s optional boundary-check hook (Some from run_checks, None here); the hook is gone — crate::project_model::phase_group now calls crate::project_model::phase_function_type_boundaries directly, at the exact point the hook used to fire, so both callers see it in the same diagnostic-ordering position as before.
  7. Test/integration-suite processing (process_tests/process_integration_tests) — closed at P5.4. Unlike categories 2-6, these run unconditionally in run_checks, in Mode::Analyse too, and push into the same shared error sink (bynk-emit’s own check_project_reports_a_test_body_error_past_an_earlier_structural_error pins a bynk.types.let_annotation_mismatch originating inside a suite/test integration body). The two functions were emission-coupled (CompiledFile, RunnableTest, ImportExt, contracts, a shared emitted_barrels set) deeply enough that P5.4 split them at the check/emit boundary rather than porting the whole thing: their checking half relocated to crate::test_suites::phase_test_bodies/ crate::test_suites::phase_integration_bodies, now called from analyse_project right after the per-unit compose/check loop (the same relative point run_checks calls the originals, unconditionally — unlike categories 2-6, neither is gated on a clean error sink), while emission itself stays in bynk-emit::project::tests_emit, which now calls the relocated checking phase too rather than duplicating it. Both functions still take &mut RefSink, so every binding edge inside a .bynk suite file is populated here again too — go-to-definition inside a test file works through this entry point once more.

Emission itself is orthogonal rather than a gap: this entry point never emits, by construction (it has no BuildTarget/ImportExt/contracts concept at all), so there is no diagnostic-agreement question to ask of it.

A fixture that exercises none of the seven categories above sees identical diagnostics from this entry point and from analyse_project_with — that is what the differential fixture’s two clean/broken cases assert. A third case (new_entry_point_omits_test_body_diagnostics) pinned category 7’s divergence directly; now that P5.4 closed it, that test asserts parity instead (see its own doc comment).

§Two sites outside the seven-category accounting

bynk-check/src/analysis.rs’s own seven categories were run_checks’s whole-project checks; two more registered diagnostics were still constructed in bynk-emit and outside that accounting, found and closed at P5.5 (design/tracks/semantics-in-the-checker.md §6, §9):

  • bynk.project.schema_registry_corrupt — a malformed on-disk bynk.schema.lock. crate::schema_registry::parse_or_diagnose now constructs it. Unreachable from this entry point, same reason as category 1: no on-disk lock concept exists here.
  • bynk.secrets.computed_name — see crate::project_model::phase_secrets_computed_name’s own doc. Unlike the seven categories (scoped and confirmed live gaps or confirmed gap-in-name-only by this settling pass), this one’s reachability from this entry point was still open at settling time — §9 named it a risk rather than a scoped item. It resolved the same way categories 1 and 5 did: gap-in-name-only, since run_checks’s own gate (target == BuildTarget::Workers) can never pass against this entry point’s hardcoded BuildTarget::Bundle.

Structs§

ContextBoundaryInfo
#855: the per-unit slice of resolution the wire-contract peek needs — see ProjectAnalysis::boundary_info. A sibling of ContextSequenceInfo, not a field on it: that struct is named and documented for #846, and this is a separate retained table serving a separate query (hover/panel over a single handler’s boundary, not the sequence-diagram classifier). Moved verbatim (Decision C, #1115).
ContextSequenceInfo
#846: the per-unit slice of resolution the sequence-diagram classifier needs — see ProjectAnalysis::sequence_info. Moved verbatim (Decision C, #1115) from bynk-emit/src/project/diagnostics.rs.
ProjectAnalysis
v0.24: the analyse-mode result — every discovered file’s analysed text snapshot (positions must convert against the text that was analysed, not a newer buffer) plus the attributed diagnostics. Moved verbatim (Decision C, #1115) from bynk-emit/src/project/diagnostics.rs; bynk-emit re-exports this type at its old path (bynk_emit::project::ProjectAnalysis) so bynk-ide’s existing destructuring needs no field-by-field rewrite.

Functions§

analyse_project
The bynk-check-native discovery→parse→resolve→check entry point (P4.1, #1115) — see this module’s own doc comment for the documented residual gap against bynk-emit’s analyse_project_with. Mirrors analyse_project_with’s own call shape exactly where the two overlap: BuildTarget::Bundle-equivalent (this entry point has no build target at all — it never emits), Platform::default(), no schema-registry lock.