Out-of-range enumerated attribute values (spec 3.2.1 and 3.5).
Statifier.Lowering.Attributes.atom/4 maps an unrecognised value onto the
attribute's default rather than erroring, so type="sideways" lowers to
:external and binding="whenever" lowers to :early - indistinguishable
on the struct from the valid spellings that produce the same atom. Only the
source text can tell them apart, which is what validate/2's source
argument exists for: the written attribute's span is sliced
back out and compared against the range.
Four reasons, one per enumerated attribute this check owns:
{:transition_bad_type, raw}- a<transition type="...">that is neither"internal"nor"external"(spec 3.5). Covers every transition the document holds, including those under an<initial>element and a<history>'s default transition, sinceStatifier.Validator.Contextalready walks all three.{:scxml_bad_binding, raw}- an<scxml binding="...">that is neither"early"nor"late"(spec 3.2.1).{:scxml_bad_datamodel, raw}- an<scxml datamodel="...">outside["predicator", "elixir", "null", "ecmascript", "xpath"](spec 3.2.1). 3.2.1's Valid Values clause is itself open-ended -"null", "ecmascript", "xpath" or other platform-defined values- so the allow-list is the spec's three named values plus this platform's two (docs/datamodel.md:6-7), not a strict["predicator", "elixir"]rejection of everything else. Accepting"ecmascript"does not mean this engine implements ECMAScript: which datamodel actually runs is ADR-0004's answer and the corpus tooling's, never this attribute's. What this check catches is a typo (datamodel="predicater",datamodel="javascript") - the ordinary job of a validator check on an enumerated NMTOKEN. An absentdatamodelattribute is"predicator", this platform's documented default (3.2.2), so it is never reported.{:invoke_bad_autoforward, raw}- an<invoke autoforward="...">that is neither"true"nor"false"(spec 6.4.1). Walks every<invoke>in the document directly (this check's ownflatten/1, the same shapeChecks.Donedata/Checks.Content/Checks.Paramuse), sinceStatifier.Validator.Contextindexes transitions but not invocations.
The fifth enumerated attribute lowering maps this way, <history type="...">, is not here: Statifier.Validator.Checks.History reports
it as :history_bad_type under spec 3.10, alongside that element's other
structural rules. The slice-and-compare shape is duplicated between the two
modules rather than shared, so each check stays readable on its own and
neither has to reach into the other's spec section.
An attribute that was never written has no attribute_locations entry and
is not reported - an absent enumerated attribute is its default, which is
always in range.
Summary
Functions
Returns a :transition_bad_type error for every <transition type="...">
whose written value is neither "internal" nor "external", a
:scxml_bad_binding error when the root <scxml binding="..."> is neither
"early" nor "late", a :scxml_bad_datamodel error when the root
<scxml datamodel="..."> is outside ["predicator", "elixir", "null", "ecmascript", "xpath"], and an :invoke_bad_autoforward error for every
<invoke autoforward="..."> whose written value is neither "true" nor
"false". All four slice the raw source text rather than trusting the
lowered atom/boolean, since an out-of-range value and a valid one can
lower to the same default. Returns [] when all four enumerated
attributes are in range everywhere they were written.
Functions
@spec check( document :: Statifier.Document.t(), context :: Statifier.Validator.Context.t() ) :: [ Statifier.Validator.Error.t() ]
Returns a :transition_bad_type error for every <transition type="...">
whose written value is neither "internal" nor "external", a
:scxml_bad_binding error when the root <scxml binding="..."> is neither
"early" nor "late", a :scxml_bad_datamodel error when the root
<scxml datamodel="..."> is outside ["predicator", "elixir", "null", "ecmascript", "xpath"], and an :invoke_bad_autoforward error for every
<invoke autoforward="..."> whose written value is neither "true" nor
"false". All four slice the raw source text rather than trusting the
lowered atom/boolean, since an out-of-range value and a valid one can
lower to the same default. Returns [] when all four enumerated
attributes are in range everywhere they were written.