/** * Per-fixture build-time contracts for shapes this adapter intentionally * refuses to lower. Declared per adapter, not on the shared fixtures, so * adding a new adapter never touches a cross-adapter file. Per-fixture * rationale lives on each fixture's docstring * (`packages/adapter-tests/fixtures/.ts`) and spec/callback-fidelity.md; * comments below only mark where this adapter's set diverges from siblings. */ import type { ConformancePins } from '@barefootjs/jsx' export const conformancePins: ConformancePins = { 'format-date': [{ code: 'BF056', severity: 'error', limitation: 'authored-format-date-call' }], // #2843: graduated — a registered lowering call inside a ternary // attribute branch (or any nested value position) is now recognised via // `JinjaTopLevelEmitter`'s `lowering` seam + the registry-aware support // gate, matching the direct-call attribute path exactly. 'filter-typeof-predicate': [{ code: 'BF021', severity: 'error', limitation: 'off-subset-callback-body' }], 'map-array-builder-body': [{ code: 'BF021', severity: 'error', limitation: 'statement-body-callback' }], 'map-array-builder-escaping': [{ code: 'BF021', severity: 'error', limitation: 'statement-body-callback' }], 'fill-unsupported': [{ code: 'BF101', severity: 'error', limitation: 'array-fill' }], 'callback-index-param': [{ code: 'BF101', severity: 'error', limitation: 'callback-index-param' }], 'filter-index-param-loop': [{ code: 'BF021', severity: 'error', limitation: 'callback-index-param' }], 'sort-opaque-comparator': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'map-opaque-projection': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'reduce-nonliteral-seed': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'filter-opaque-predicate': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'filter-native-nested-index': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'filter-array-method-predicate': [{ code: 'BF101', severity: 'error', limitation: 'callback-outside-evaluator' }], 'find-typeof-predicate': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], 'some-typeof-predicate': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], 'every-typeof-predicate': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], 'reduce-typeof-body': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], 'reduce-right-typeof-body': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], 'flatmap-typeof-projection': [{ code: 'BF101', severity: 'error', limitation: 'off-subset-callback-body' }], // A pure PROJECTION flatMap body (`flatmap-expression-body`) is NOT pinned — // it lowers to neutral nested-loop IR this adapter templatizes natively; // only the statement-carrying body refuses. 'tag-cloud': [{ code: 'BF021', severity: 'error', limitation: 'statement-body-callback' }], 'preamble-cells': [{ code: 'BF021', severity: 'error', limitation: 'statement-body-callback' }], // Refused for the COMPUTED loop array (`const entries = Object.entries(...) // .filter(...)`), not the destructure param (that lowers, #2087) — loud // BF101 instead of Jinja's ChainableUndefined silently iterating zero times. 'static-array-from-props': [ { code: 'BF101', severity: 'error', limitation: 'computed-const-loop-source', }, ], // No BF103 pin: the harness registers sibling templates (#2205). 'static-array-from-props-with-component': [ { code: 'BF101', severity: 'error', limitation: 'computed-const-loop-source', }, ], // Module-scope companion of `static-array-from-props` above: the const // is computed via a function call, not a static literal — genuinely // unresolvable at SSR render time, same #2321 design gap applied // uniformly regardless of which scope the const lives in (#2946 fixed // the STATIC-literal module-scope case; this is the still-open // computed-const case). Escape twin: `module-const-loop-source-computed-client`. 'module-const-loop-source-computed': [ { code: 'BF101', severity: 'error', limitation: 'computed-const-loop-source', }, ], // The same computed-const source, parenthesized (`(keys).map(…)`): the // gate reads the parsed tree, so the parentheses do not hide it (#3473). 'computed-const-loop-source-parenthesized': [ { code: 'BF101', severity: 'error', limitation: 'computed-const-loop-source', }, ], // A loop filter predicate with no template form refuses rather than // rendering every row (#3534). 'filter-predicate-shape-loop': [ { code: 'BF101', severity: 'error', limitation: 'unlowerable-loop-filter-predicate' }, ], // A method call no template lowers, outside a callback, refuses rather // than rendering a read of the method name (#3493). 'unlowered-method-call': [ { code: 'BF101', severity: 'error', limitation: 'unlowered-method-call' }, ], // A zero-arg call on a JavaScript global (`Date.UTC()`) refuses rather // than rendering a member read of it (#3505). 'unlowered-global-call': [ { code: 'BF101', severity: 'error', limitation: 'unlowered-method-call' }, ], // The same refusal reached through a computed const read outside a loop: // the const reads as its initializer (#3494). 'computed-const-read-unlowerable': [ { code: 'BF101', severity: 'error', limitation: 'unlowered-method-call' }, ], // #2038: no inline comprehension-with-nested-callback form via the // evaluator-JSON `*_eval` mechanism (`jinja-adapter.ts`'s header, // divergence 3) — loud BF101 instead of lossy. 'filter-nested-callback-predicate': [ { code: 'BF101', severity: 'error', limitation: 'nested-callback-in-filter-predicate' }, ], 'filter-nested-find-predicate': [{ code: 'BF101', severity: 'error', limitation: 'nested-callback-in-filter-predicate' }], 'filter-nested-callback-reads-outer-param': [ { code: 'BF101', severity: 'error', limitation: 'nested-callback-in-filter-predicate' }, ], // `loop` is renamed to `__bf_loop`, so a component that also uses // `__bf_loop` would read one value under both names (#3404). 'reserved-name-and-internal-twin': [ { code: 'BF105', severity: 'error', limitation: 'reserved-name-collides-with-internal-name' }, ], 'reserved-name-filter-param-and-internal-prop': [ { code: 'BF105', severity: 'error', limitation: 'reserved-name-collides-with-internal-name' }, ], // Top-level `.find`/`.findIndex`/`.findLast`/`.findLastIndex` are NOT // pinned — unlike mojo (which refuses them), Jinja lowers them via the // same evaluator-JSON mechanism as `.filter`/`.some`. Only the nested form // above is refused. 'date-method-uncatalogued': [{ code: 'BF021', severity: 'error', limitation: 'ambient-locale-date-formatting' }], 'rich-prop-client-read': [{ code: 'BF049', severity: 'error', limitation: 'rich-typed-prop-hydration' }], // A ternary or array literal LITERALLY WRAPPING JSX at a non-children prop // position (e.g. `header={cond ? : }`) is refused ahead of // `adapter.generate()` in the shared jsx-to-ir.ts phase, so it is pinned // identically on every adapter (including Hono) — same reasoning as // `rich-prop-client-read` above. This is the permanent, intended behavior // (formerly tracked as #2667, closed): the issue's own acceptance criteria // treated a loud refusal as fully resolving the silent-divergence bug, so // no open issue tracks further work here. 'jsx-element-prop-ternary': [{ code: 'BF021', severity: 'error', limitation: 'jsx-wrapped-in-non-children-prop' }], 'jsx-element-prop-array': [{ code: 'BF021', severity: 'error', limitation: 'jsx-wrapped-in-non-children-prop' }], // A reactive primitive invoked through a namespace import // (`import * as bf from '@barefootjs/client'`, `bf.createSignal(...)`) // that the analyzer's checker-less fast path cannot recognize refuses // loudly (BF013) instead of silently dropping the declaration — fired // in the shared analyzer pass ahead of any adapter's `adapter.generate()`, // so all nine adapters (including Hono) pin this identically. A compile // that supplies a shared `ts.Program` (e.g. via `@barefootjs/vite`) // resolves the primitive normally and never reaches this refusal (formerly // tracked as #2771, closed) — no open issue tracks further work. 'namespace-import-primitive': [{ code: 'BF013', severity: 'error', limitation: 'namespace-import-primitive-without-program' }], // #2994 graduated the render-divergence pin: a call to a module-scope // helper (arrow-valued const OR `function` declaration) by bare name // has no Python binding in Jinja template scope — `call()`'s generic // fallback now refuses it loudly (BF101) instead of silently resolving // against Jinja's undefined-variable semantics (renders empty) and // dropping the call's arguments. No verified escape twin exists yet // (the shape has no structural lowering — see #2994's "Suggested fix // shape" for the deferred, harder direction); `/* @client */` works // informally but isn't pinned as a corpus fixture yet. 'module-const-arrow-helper': [ { code: 'BF101', severity: 'error', limitation: 'module-scope-helper-call', unescapable: true }, ], 'module-function-helper-chain': [ { code: 'BF101', severity: 'error', limitation: 'module-scope-helper-call', unescapable: true }, ], // #3012: same BF101 refusal as the two entries above, for a module-scope // helper called from a boolean-TEST position (a ternary `test`) rather // than a plain text position — the `_boolContext` structural exemption // that used to let this shape through (scoped by position, not by // callee identity) is now removed entirely; `isValidElement` (the one // caller that needed to keep compiling under it) is resolved ahead of // `call()`'s generic fallback as an identity-scoped `templatePrimitive` // instead (`bf.is_element`, `lib/constants.ts`). 'module-helper-boolcontext-call': [ { code: 'BF101', severity: 'error', limitation: 'module-scope-helper-call', unescapable: true }, ], // #3063: a client-interactive component with a multi-return chain // where one branch is a bare JSX fragment refuses ahead of // `adapter.generate()` in the shared jsx-to-ir.ts phase (the client // hydration claim can't tell branches apart — see the registry entry), // so it is pinned identically on every adapter including Hono. 'conditional-return-fragment-branch': [ { code: 'BF029', severity: 'error', limitation: 'fragment-wrapped-conditional-return-branch-scope' }, ], // A `ref` callback writing an attribute on mount that the element's JSX // never renders refuses (BF063) in the shared jsx-to-ir.ts phase, ahead // of `adapter.generate()` — a ref never runs at SSR, so the attribute // could never reach the server HTML on any backend — so it is pinned // identically on every adapter including Hono. 'ref-mount-attr': [ { code: 'BF063', severity: 'error', limitation: 'ref-effect-attr-state-ssr' }, ], // #3144: a component-body local bound to an opaque call // (`const label = makeLabel(); {label()}`), invoked in text position, // refuses ahead of the generic signal-getter fallback in this // adapter's own `call()` (`adapter/expr/emitters.ts` / // `go-template-adapter.ts`) -- not a shared jsx-to-ir.ts refusal, since // Hono's real JS runtime evaluates this shape correctly and must keep // doing so. 'opaque-local-accessor-call': [{ code: 'BF101', severity: 'error', limitation: 'opaque-local-accessor-call' }], }