One thing the compiler has to say about one block (ADR-0004 decision 10).
Every finding names a block. There is no chart-level finding without an
owner, which is what lets an editor render findings as annotations on the
tree with no fallback presentation, and decision 5's totality is what
buys it for the :chart stage - the one stage whose findings arrive with
no idea that blocks exist.
The pipeline, and which stage produces what
| Stage | Errors it produces |
|---|---|
:document | :invalid_document - Document.validate/1's reason |
:resolve | :unknown_block_type, :block_type_too_new, :migration_failed |
:config | validate_config/1 findings, one per {key, message} pair |
:structure | assignability (ADR-0003); slot arity and :undeclared_slot are sb-da9's |
:emit | emit/2 findings, :invalid_role, :unspliced_child, :unknown_attribution |
:chart | mapped statifier findings, both faults (decision 9) |
The pipeline stops at the first stage that produces errors and reports every error from that stage. Stopping rather than accumulating across stages is deliberate: a document with an unresolvable block type has no meaningful structural check to run, and reporting a cascade of consequences beside the cause is how an error panel becomes noise. Within a stage every finding is reported, because those are siblings rather than consequences.
The :document stage is not in decision 10's table, and it is not a new
decision either: decision 1 requires compile/3 never to raise, and
Document.to_json/1 raises on a document that fails ADR-0001's
structural rules. Checking first and reporting it as a finding is what
totality costs. It runs before :resolve because a document that is not
structurally a document has no blocks worth resolving.
fault: whose problem is this?
Decision 9 states the split for the :chart stage, where it is subtle
because the finding was raised against generated SCXML by a validator
that has never heard of blocks. The rule generalizes, and this module
applies the generalized form at every stage:
:author- a document edit fixes it. Every:configfinding, every:structurefinding (an author placed the block), and every:chartfinding whose owning span carries a config key.:package- a bug in this package or in a host's block type, and no edit to the document will help.:resolvefindings (the palette is the host's, not the author's), every:emitfinding that names no config key, and every:chartfinding whose owning span carries no config key: an author cannot express{:unresolved_target, id}, because the block vocabulary has no way to name a state id.
The editor renders the two differently, and "this cannot be fixed here" is the only honest message for the second.
severity
:error fails the compile; :warning rides on
StatifierBlocks.Compiled's warnings and does not. Upstream warnings
(st-ADR-0033) and decision 8's optional invoke-type lint are the two
sources of warnings, and decision 8 is explicit that the lint is never
an error.
Summary
Functions
reason's stable tag: the tuple's first element, or the reason itself
when it is already an atom.
Builds a finding.
Types
@type fault() :: :package | :author
Whose problem this is. See the moduledoc.
@type stage() :: :document | :resolve | :config | :structure | :emit | :chart
The pipeline stage that produced this finding.
@type t() :: %StatifierBlocks.Compiler.Finding{ block_id: StatifierBlocks.Block.id() | nil, code: atom(), config_key: String.t() | nil, fault: fault(), message: String.t(), path: StatifierBlocks.Document.path() | nil, reason: term(), severity: :error | :warning, stage: stage() }
Functions
reason's stable tag: the tuple's first element, or the reason itself
when it is already an atom.
Builds a finding.
opts carries :block_id, :path, :config_key, :severity,
:fault and :code. code defaults to reason's own tag, which is the
stable atom an editor switches on while reason keeps carrying the
offending ids as data - the same split
Statifier.Validator.Error.code/1 makes upstream. fault defaults to
the stage's own rule, refined by whether a config key is present.