StatifierBlocks.Finding (StatifierBlocks v0.1.0)

Copy Markdown View Source

A finding as the editor renders it: normalized for presentation, and the anchor routes it (ADR-0005 decision 11).

Findings arrive from sources with different shapes - validate_config/1 returns {key, message} pairs, arity and undeclared-slot violations are about a slot, resolution failures are about a block - so this struct normalizes them to one shape with one routing mechanism: the anchor. StatifierBlocks.ViewModel is what actually does the routing; this module owns only the shape.

Two Finding modules, on purpose

StatifierBlocks.Compiler.Finding already exists, and it is a different struct for a different layer: it carries stage/fault/code/reason for the compile pipeline (ADR-0004 decision 10), keyed to the stage that produced it and to whether the problem is the author's or the package's. This module, StatifierBlocks.Finding, is the presentation finding ADR-0005 decision 11 specifies: anchor/severity/source/message, keyed to where in the rendered tree the finding shows up. Neither is a degenerate case of the other, neither wraps the other, and nothing in this package adapts one into the other (see StatifierBlocks.ViewModel's moduledoc for why that adapter is deliberately not built here). If you are about to import this module and get stage, fault, code, or reason back, you have the wrong one - reach for StatifierBlocks.Compiler.Finding instead.

Summary

Types

The whole routing mechanism (ADR-0005 decision 11). A :config finding renders inline beneath its field, a :slot finding on that slot's header, a :block finding on the block's chrome.

Where this finding's rule lives. See StatifierBlocks.ViewModel's moduledoc.

t()

Functions

Builds a finding, in the shape StatifierBlocks.Compiler.Finding.new/4 already uses: the fixed positional arguments first, message last among them, and everything else in opts.

Types

anchor()

@type anchor() ::
  {:config, StatifierBlocks.Block.id(), key :: String.t()}
  | {:slot, StatifierBlocks.Block.id(), StatifierBlocks.Block.slot_name()}
  | {:block, StatifierBlocks.Block.id()}

The whole routing mechanism (ADR-0005 decision 11). A :config finding renders inline beneath its field, a :slot finding on that slot's header, a :block finding on the block's chrome.

source()

@type source() :: :config | :arity | :assignability | :resolution | :lint

Where this finding's rule lives. See StatifierBlocks.ViewModel's moduledoc.

t()

@type t() :: %StatifierBlocks.Finding{
  anchor: anchor(),
  message: String.t(),
  severity: :error | :warning,
  source: source()
}

Functions

new(anchor, source, message, opts \\ [])

@spec new(anchor(), source(), String.t(), keyword()) :: t()

Builds a finding, in the shape StatifierBlocks.Compiler.Finding.new/4 already uses: the fixed positional arguments first, message last among them, and everything else in opts.

opts carries :severity, defaulting to :error - the default every source but :lint uses (ADR-0005 decision 11).