Lockstep cut of @rhinostone/swig-core, @rhinostone/swig, and
@rhinostone/swig-twig at 2.0.0-alpha.5 under the `alpha` dist-tag.
Highlights since alpha.4:
* @rhinostone/swig-core gains an IRVarRefExists IR node + backend
emitter carrying a boolean defined-and-non-null signal for VarRef
paths. Needed by Twig `is defined` / `is null` tests and by `??`
undefined-fallback, both of which cannot use IRVarRef directly
because emitVarRef coerces missing / null to "".
* @rhinostone/swig-core backend now routes Twig/Jinja2 `??`
undefined-fallback through IRVarRefExists for VarRef LHS, matching
Twig-strict semantics (fallback on undefined OR missing property).
Non-VarRef LHS (FnCall, FilterCall, Literal) falls through to bare
`left??right` — those emitters do not coerce missing to "", so
JS-native `??` is sufficient.
* @rhinostone/swig-core backend now lowers Twig/Jinja2 `~` string-
concat to (String(left) + String(right)). Bare `<left>~<right>`
emission was JS unary bitwise-NOT and threw SyntaxError at compile
time.
* @rhinostone/swig-twig `is <test>` / `is not <test>` now routes
through _ext._test_<name>(subject, ...args). VarRef subjects with
`is defined` / `is null` special-case through IRVarRefExists to
preserve the defined-or-not-null signal. Seven built-in test
helpers (defined, null, empty, iterable, odd, even, divisibleby)
ship at packages/swig-twig/lib/tests/ and register on every Twig
instance via setExtension.
* @rhinostone/swig-twig `..` range operator now lowers through
_utils.range. swig-core adds range(start, end) with Twig-compatible
inclusive-both-ends semantics for numeric + single-char-string
bounds (ascending and descending).
* @rhinostone/swig-twig parser now routes STRING and NUMBER literal
LHS through parsePostfix, so filter chains like {{ "hi"|upper }}
and {{ 42|json_encode }} parse correctly instead of bailing with
Unexpected token "<filter>".
* @rhinostone/swig-twig ships an end-to-end render-fixture suite at
tests/swig-twig/cases/ (19 *.test.twig + .expectation.html pairs
across operators, Twig-specific tags, filter semantics, and
multi-template flows; 11 is-*, null-coalesce, and 3 range-*
fixtures land alongside the Phase 4 work).
Cross-package runtime and peerDeps stay pinned to exact versions
(`"@rhinostone/swig-core": "2.0.0-alpha.5"`) — alpha-grade IR ABI is
unstable across minor bumps.