Statifier.Validator.Checks.Assign (Statifier v2.5.0)

Copy Markdown View Source

Spec 5.4.2: "A conformant SCXML document MUST specify either 'expr' or children of <assign>, but not both." Reports {:assign_expr_and_text, expr} at the <assign>'s own element span, whether those children are text or markup (ADR-0041's 2026-09-02 Note) - same reason, same shape, regardless of which form the content takes, exactly as Checks.Content treats the two forms under <content>.

lib/statifier/document/assign.ex makes expr, text and markup all representable at once precisely so this check can report the shape rather than lowering refusing to build it - the same division of labour Checks.Content has with <content> and Checks.Data has with <data>.

Whitespace-only text is not text. Statifier.Parser.DOM.text/1 concatenates <assign>'s direct text children verbatim and untrimmed, so a pretty-printed <assign expr="1">\n </assign> carries a text of "\n ". That is source formatting, not a payload, and firing on it would reject documents the spec allows - the same rule Checks.Content.blank?/1 and Checks.Data.blank?/1 already follow. markup, when present, is never blank - it is nil unless <assign> has at least one element child - so no equivalent whitespace carve-out applies to it.

This check walks every state's own onentry/onexit blocks, every state's own transitions (both plain and a :history state's default - Statifier.Document.State.transitions covers both), and every state's <initial> element's own transition - the three places Statifier.Document.Assign can appear as executable content (Statifier.Document.Block.t()'s and Statifier.Document.Transition.t()'s own content fields).

Summary

Functions

Walks every <assign> reachable through a state's onentry/onexit blocks or its own (and its <initial> element's) transitions, and returns an :assign_expr_and_text error for each one that carries both an expr attribute and non-blank child content - markup, or text. Returns [] when no <assign> in the document mixes the two forms.

Functions

check(document, context)

@spec check(
  document :: Statifier.Document.t(),
  context :: Statifier.Validator.Context.t()
) :: [
  Statifier.Validator.Error.t()
]

Walks every <assign> reachable through a state's onentry/onexit blocks or its own (and its <initial> element's) transitions, and returns an :assign_expr_and_text error for each one that carries both an expr attribute and non-blank child content - markup, or text. Returns [] when no <assign> in the document mixes the two forms.