Sibling articles under this feature previously restated requirements in inconsistent forms.
Analysis, query, and diagnostics facades - Design model
Platform spec article
Analysis, query, and diagnostics facades - Design model
Spec standingStandard
-
This feature hub owns normative MUST/SHOULD contract text for Analysis, query, and diagnostics facades.
Context
Decision
This feature hub owns normative MUST/SHOULD contract text. Sibling articles must not redefine hub requirements and should link here for authority.
Consequences
Contract changes start on the hub or in linked ADRs, then propagate to articles and implementation anchors.
Verification anchors
site/website/src/content/docs/platform-spec/compiler/compiler-mods/analysis-query-diagnostics-facade/index.mdxarticle bundle under the same feature directory.
-
Platform-spec text supersedes informal crate comments for Analysis, query, and diagnostics facades.
Context
Implementation crates accumulated informal notes that diverged from published contracts.
Decision
Normative platform-spec prose and ADRs under this feature supersede informal comments in implementation crates until explicitly migrated into spec text.
Consequences
Engineers file spec/ADR updates when behavior changes; crate comments are non-authoritative for conformance arguments.
Verification anchors
compiler/crates/beskid_analysis/src/analysis/compiler/crates/beskid_analysis/src/resolve/compiler/crates/beskid_lsp/src/diagnostics.rs
-
This feature hub defines the normative contract for **`Beskid.Compiler.Query`** and **`Beskid.Compiler.Diagnostics`** (a
Context
This feature hub defines the normative contract for
Beskid.Compiler.QueryandBeskid.Compiler.Diagnostics(and related analysis facades) and links detailed articles.Decision
The reference compiler must implement Analysis, query, and diagnostics facades as documented in this feature hub and its article bundle.
Consequences
Changes require hub/ADR updates and verification anchor extensions.
Verification anchors
compiler/crates/beskid_analysis/src/analysis/compiler/crates/beskid_analysis/src/resolve/compiler/crates/beskid_lsp/src/diagnostics.rs
- Analysis, query, and diagnostics facades - Contracts and edge cases Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
- Analysis, query, and diagnostics facades - Design model Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
- Analysis, query, and diagnostics facades - Examples Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
- Analysis, query, and diagnostics facades - FAQ and troubleshooting Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
- Analysis, query, and diagnostics facades - Flow and algorithm Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
- Analysis, query, and diagnostics facades - Verification and traceability Semantic queries, symbol handles, and diagnostic transport available inside meta execution.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
This article documents the design model for Analysis, query, and diagnostics facades.
Language alignment
Section titled “Language alignment”Process pipelines express fluent queries that lower to bounded Rust walkers; Diagnostics raised here must use compiler-stable codes for parity with beskid_analysis / LSP.
Persistent entities
Section titled “Persistent entities”- Compilation instance — implicit handle to the compilation under construction (Compiler Mod SDK /
Beskid.Compiler.Compilation). - Syntax snapshot — immutable tree with stable node identities suitable for incremental keys.
- Capability tokens — host-granted permissions for I/O, diagnostics, and emit operations during mod execution.
Boundaries
Section titled “Boundaries”- Mod SDK facades never bypass the host bridge for effects.
- Generation logic in the reference compiler remains Rust-internal; Beskid sees only the generated
Beskid.Compiler.*projection.
Anchored code paths
Section titled “Anchored code paths”compiler/crates/beskid_analysis/src/analysis/— staged rules and semantic state.compiler/crates/beskid_analysis/src/resolve/— resolution products queryable from facades.compiler/crates/beskid_lsp/src/diagnostics.rs— diagnostic shaping for editor parity.
Diagnostic parity rules
Section titled “Diagnostic parity rules”Beskid.Compiler.Diagnostics (and internal meta emitters) must:
- Emit
SemanticDiagnosticvalues compatible withrun_rulesoutput (same severity enum, string diagnostic codes matching registered ids). - Allocate mod and mod-host codes only inside E1801–E1899 using the sub-ranges in Diagnostic code registry / design model; register each code in
compiler/crates/beskid_analysis/src/analysis/diagnostic_kinds.rswhen introduced. - Never bypass
span_to_sourcespan/ miette adapters used elsewhere so LSP label offsets remain accurate.
Query lowering and bounded walkers
Section titled “Query lowering and bounded walkers”Fluent Beskid.Compiler.Query plans must lower to explicit Rust walkers with documented upper bounds on work (max nodes visited, max depth). Hosts must abort with diagnostics (not panics) when bounds trip. Optional query_semantic_snapshot reads must declare the minimum staged snapshot version (ties to semantic.snapshot events in Compiler Mods area hub).
When the Rust compiler maintains compile-time composition / IoC state for user programs (Native dependency injection), that state must be materialized into the same versioned semantic snapshot family as other staged products (exported after composition.resolve) so mod analyzers can query it without special casing: Mod SDK query types project compiler-native graphs into Beskid-visible handles; they must not recompute or replace Rust-owned resolution unless a dedicated, separately specified capability allows a narrow, audited code path.
Beskid.Compiler.Query surface (normative)
Section titled “Beskid.Compiler.Query surface (normative)”Facade version 0.4.0 (see QueryFacadeVersion()). All functions lower to beskid_analysis::query walkers over a host-built SyntaxSnapshot.
| Type / function | Semantics |
|---|---|
NodeRef | { syntaxGenerationId, nodeId } — opaque, host-allocated, stable within a generation window |
NodeSpan | { start, end, lineStart, columnStart, lineEnd, columnEnd } for one node in one syntax generation |
QueryBounds | { maxNodes, maxDepth } — default host caps apply when zero |
SyntaxQuery | Cursor at start with bounds |
At / AtProgram | Entry from NodeRef or Program root |
Descendants | Pre-order traversal (same order as Rust Descendants) |
Children | Direct children only |
Parent / Ancestors | Immediate parent and root-to-parent chain via snapshot parent table |
Span / TrySpan | Required span lookup and optional span lookup for a NodeRef |
OfKind / FindFirst | Filter by Beskid.Syntax.Nodes.NodeKind |
As* | Host downcast to concrete mirrored type (one helper per kind with a shape type) |
Walk + SyntaxVisitor | Depth-first enter/exit (maps to AstWalker) |
SyntaxPipeline | Query-driven transformation plan over NodeRef selections |
Select + WhereKind | Build a deterministic selection set from a root query |
Replace / Remove / InsertBefore / InsertAfter | Minimal rewrite operations over selected NodeRefs |
Apply | Validates and commits a pipeline as one host operation |
Bound trip — When maxNodes or maxDepth is exceeded, the host must stop iteration, return no further nodes from that query, and emit diagnostic E1880 (QueryBoundsExceeded). Must not panic.
Traversal vs rewrite — Mod analyzers traverse with NodeRef only; Rewriter still receives concrete mirrored source/target types from the host after As* validation.
Span and pipeline invariants
Section titled “Span and pipeline invariants”Span(nodeRef)must succeed whennodeRef.syntaxGenerationIdmatches the active snapshot generation andnodeIdresolves; otherwise host emits E1882 and returns an empty/default result per facade contract.TrySpan(nodeRef)must never emit diagnostics and returnsnonefor stale or unknown refs.- Pipeline application is deterministic: operations are ordered by snapshot pre-order index, then by operation kind precedence (
Remove,Replace,InsertBefore,InsertAfter). - Hosts must reject conflicting operations over the same anchor with E1883 (
QueryPipelineConflict) instead of implicit overwrite behavior. - Hosts must reject generation-stale pipeline handles with E1884 (
QueryPipelineStaleGeneration) and keep the previous committed snapshot unchanged.