Hwaro::Assets::Sass::Evaluator
Inherits Hwaro::Assets::Sass::Expr::Host < Reference < Object
Constants
At-rules whose body is a descriptor block: the declarations belong to the at-rule itself, so bubbling one out of a style rule must NOT wrap them in the parent selector.
This is a denylist on purpose. Everything else — @media, @supports, @layer, @container, @starting-style, and any at-rule newer than this compiler — is a grouping at-rule and keeps the selector. An allowlist silently dropped the selector for anything it hadn't heard of, emitting a selector-less declaration that browsers discard.
Binds arguments to parameters (shared by mixins and functions).
soft: true raises SoftEvalError instead of located errors —
function calls happen inside expression evaluation, where
lenient contexts fall back and strict contexts add locations.
Hidden variable prefix carrying a variadic parameter's keyword
arguments (meta.keywords($args) / spread forwarding). @ can
never appear in a user identifier, so the side-channel is
unreachable from stylesheet code.
Total loop-body evaluations across @for/@each/@while in ONE
compile. MAX_WHILE_ITERATIONS bounds a single @while and nothing
bounded @for at all, so @for $i from 1 through 100000000 — one
mistyped bound — emitted rules until the process ran out of memory,
and nesting two capped loops still multiplies. A shared budget is the
only form that survives nesting. Six figures of loop bodies is orders
of magnitude past any real stylesheet (palettes and grid systems land
in the hundreds).
& slots per selector beyond which the parent cross-product is
not expanded (it grows as parents**slots).
Ceiling on the selectors ONE rule may expand to. MAX_PARENT_REF_SLOTS
bounds the exponent but not the base, and the base is the enclosing
rule's own expansion — so nesting compounds:
.a,.b,…,.j { & & { & & { & & { color: red } } } }
is 10 → 10² → 10⁴ → 10⁸ selectors from eight lines of SCSS. The build did not crash, it simply never finished, allocating the whole way. No hand-written rule needs four figures of selectors, so cap it and say so instead of hanging.
sass:meta functions that need evaluator state (scopes, mixins, @content) and therefore can't live in the static builtin tables.
Pseudo-classes whose argument is a selector list: a & inside
resolves to the whole parent list (dart-sass), not per parent.