@barefootjs/jinja 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/adapter/analysis/component-tree.d.ts +26 -0
- package/dist/adapter/analysis/component-tree.d.ts.map +1 -0
- package/dist/adapter/boolean-result.d.ts +84 -0
- package/dist/adapter/boolean-result.d.ts.map +1 -0
- package/dist/adapter/emit-context.d.ts +106 -0
- package/dist/adapter/emit-context.d.ts.map +1 -0
- package/dist/adapter/expr/array-method.d.ts +75 -0
- package/dist/adapter/expr/array-method.d.ts.map +1 -0
- package/dist/adapter/expr/emitters.d.ts +143 -0
- package/dist/adapter/expr/emitters.d.ts.map +1 -0
- package/dist/adapter/expr/operand.d.ts +25 -0
- package/dist/adapter/expr/operand.d.ts.map +1 -0
- package/dist/adapter/index.d.ts +6 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +189097 -0
- package/dist/adapter/jinja-adapter.d.ts +394 -0
- package/dist/adapter/jinja-adapter.d.ts.map +1 -0
- package/dist/adapter/lib/constants.d.ts +21 -0
- package/dist/adapter/lib/constants.d.ts.map +1 -0
- package/dist/adapter/lib/ir-scope.d.ts +50 -0
- package/dist/adapter/lib/ir-scope.d.ts.map +1 -0
- package/dist/adapter/lib/jinja-naming.d.ts +77 -0
- package/dist/adapter/lib/jinja-naming.d.ts.map +1 -0
- package/dist/adapter/lib/types.d.ts +27 -0
- package/dist/adapter/lib/types.d.ts.map +1 -0
- package/dist/adapter/memo/seed.d.ts +81 -0
- package/dist/adapter/memo/seed.d.ts.map +1 -0
- package/dist/adapter/props/prop-classes.d.ts +33 -0
- package/dist/adapter/props/prop-classes.d.ts.map +1 -0
- package/dist/adapter/spread/spread-codegen.d.ts +61 -0
- package/dist/adapter/spread/spread-codegen.d.ts.map +1 -0
- package/dist/adapter/value/parsed-literal.d.ts +28 -0
- package/dist/adapter/value/parsed-literal.d.ts.map +1 -0
- package/dist/build.d.ts +28 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +189117 -0
- package/dist/conformance-pins.d.ts +12 -0
- package/dist/conformance-pins.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +189118 -0
- package/package.json +66 -0
- package/python/VERSION +1 -0
- package/python/barefootjs/__init__.py +57 -0
- package/python/barefootjs/backend_jinja.py +125 -0
- package/python/barefootjs/evaluator.py +787 -0
- package/python/barefootjs/runtime.py +1334 -0
- package/python/barefootjs/search_params.py +89 -0
- package/python/pyproject.toml +32 -0
- package/python/tests/__init__.py +0 -0
- package/python/tests/test_eval_vectors.py +88 -0
- package/python/tests/test_evaluator.py +406 -0
- package/python/tests/test_helper_vectors.py +288 -0
- package/python/tests/test_omit.py +62 -0
- package/python/tests/test_props_attr.py +54 -0
- package/python/tests/test_query.py +41 -0
- package/python/tests/test_render.py +102 -0
- package/python/tests/test_render_child.py +96 -0
- package/python/tests/test_search_params.py +50 -0
- package/python/tests/test_spread_attrs.py +86 -0
- package/python/tests/test_template_primitives.py +347 -0
- package/python/tests/vector-divergences.json +42 -0
- package/src/__tests__/jinja-adapter-unit.test.ts +390 -0
- package/src/__tests__/jinja-adapter.test.ts +53 -0
- package/src/__tests__/jinja-counter.test.ts +62 -0
- package/src/__tests__/jinja-query-href.test.ts +99 -0
- package/src/__tests__/jinja-spread-attrs.test.ts +225 -0
- package/src/adapter/analysis/component-tree.ts +119 -0
- package/src/adapter/boolean-result.ts +176 -0
- package/src/adapter/emit-context.ts +118 -0
- package/src/adapter/expr/array-method.ts +346 -0
- package/src/adapter/expr/emitters.ts +608 -0
- package/src/adapter/expr/operand.ts +35 -0
- package/src/adapter/index.ts +6 -0
- package/src/adapter/jinja-adapter.ts +1747 -0
- package/src/adapter/lib/constants.ts +33 -0
- package/src/adapter/lib/ir-scope.ts +95 -0
- package/src/adapter/lib/jinja-naming.ts +114 -0
- package/src/adapter/lib/types.ts +30 -0
- package/src/adapter/memo/seed.ts +132 -0
- package/src/adapter/props/prop-classes.ts +65 -0
- package/src/adapter/spread/spread-codegen.ts +166 -0
- package/src/adapter/value/parsed-literal.ts +76 -0
- package/src/build.ts +37 -0
- package/src/conformance-pins.ts +101 -0
- package/src/index.ts +9 -0
- package/src/test-render.ts +714 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @barefootjs/jinja
|
|
2
|
+
|
|
3
|
+
Jinja2 adapter for BarefootJS: compiles the BarefootJS IR (JSX → IR, see
|
|
4
|
+
`spec/compiler.md`) into `.jinja` template files plus the client JS bundle
|
|
5
|
+
every other adapter produces, and ships a Python rendering runtime
|
|
6
|
+
(`python/barefootjs/`) that renders those templates through a plain
|
|
7
|
+
`jinja2.Environment` — no framework is required (Flask, Django, bare WSGI,
|
|
8
|
+
etc. all work the same way).
|
|
9
|
+
|
|
10
|
+
Near-mechanical port of `@barefootjs/xslate` (the Text::Xslate/Kolon
|
|
11
|
+
adapter) to Jinja2 syntax. See `src/adapter/jinja-adapter.ts`'s header
|
|
12
|
+
comment for the full Kolon↔Jinja syntax-mapping table and the JS/Python
|
|
13
|
+
semantics divergences this port handles uniformly (truthiness,
|
|
14
|
+
stringification, reserved-word identifier mangling, and the
|
|
15
|
+
evaluator-only higher-order-callback lowering since Jinja has no lambda
|
|
16
|
+
expression).
|
|
17
|
+
|
|
18
|
+
## Template output shape
|
|
19
|
+
|
|
20
|
+
- `name: 'jinja'`, `extension: '.jinja'`, `templatesPerComponent: true` —
|
|
21
|
+
one `.jinja` file per component, named by snake-casing the PascalCase
|
|
22
|
+
component name (`UserCard` → `user_card.jinja`).
|
|
23
|
+
- Hydration markers (`bf-s`, `bf-h`/`bf-m`/`bf-r`, `bf-p`, slot/conditional
|
|
24
|
+
comment markers, loop boundary comments) use the SAME runtime method
|
|
25
|
+
names as every other adapter's `bf.*` calls (`bf.scope_attr()`,
|
|
26
|
+
`bf.hydration_attrs()`, `bf.text_start`/`text_end`, `bf.comment(...)`,
|
|
27
|
+
…) — see `spec/template-helpers.md` for the shared helper contract.
|
|
28
|
+
- Every text/attribute interpolation of a possibly-non-string value is
|
|
29
|
+
routed through `bf.string(...)` (or `bf.bool_str(...)` for
|
|
30
|
+
boolean-shaped values); every non-comparison condition position is
|
|
31
|
+
routed through `bf.truthy(...)`. Both are pure Python-runtime helpers —
|
|
32
|
+
see the Python runtime pointer below.
|
|
33
|
+
|
|
34
|
+
## Python runtime
|
|
35
|
+
|
|
36
|
+
`python/barefootjs/` is a self-contained Python package (only dependency:
|
|
37
|
+
`jinja2`) implementing the engine-agnostic `bf` object every emitted
|
|
38
|
+
template calls into: hydration markers, context propagation
|
|
39
|
+
(`provide_context`/`use_context`), child-component rendering
|
|
40
|
+
(`render_child`), script registration, and the JS-compatible helper
|
|
41
|
+
library (`string`, `bool_str`, `truthy`, `number`, `floor`/`ceil`/`round`,
|
|
42
|
+
array/string helpers, the `*_eval` evaluator helpers, `spread_attrs`,
|
|
43
|
+
`query`, …). It mirrors the layering of `packages/adapter-perl/lib/` (an
|
|
44
|
+
engine-agnostic core plus a thin per-engine backend) — see
|
|
45
|
+
`spec/template-helpers.md` for the semantic contract each helper must
|
|
46
|
+
satisfy, and the package's own tests under `python/tests/`.
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// barefoot.config.ts
|
|
52
|
+
import { createConfig } from '@barefootjs/jinja/build'
|
|
53
|
+
|
|
54
|
+
export default createConfig({
|
|
55
|
+
components: ['./src/components'],
|
|
56
|
+
outDir: './dist',
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`bf build` then emits `.jinja` templates + client JS under `outDir`. A
|
|
61
|
+
Python host renders a component by constructing a `jinja2.Environment`
|
|
62
|
+
(with `autoescape=True`, `undefined=jinja2.ChainableUndefined`,
|
|
63
|
+
`trim_blocks=True`, `lstrip_blocks=True` — see the adapter header comment
|
|
64
|
+
for why the last two are required) over a `FileSystemLoader` pointed at
|
|
65
|
+
the emitted templates, wiring in `barefootjs.backend_jinja` as the render
|
|
66
|
+
backend.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component-tree analysis for the Jinja2 template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `packages/adapter-xslate/src/adapter/analysis/component-tree.ts`.
|
|
5
|
+
* Pure functions over the IR — they read no adapter instance state.
|
|
6
|
+
* `collectImportedLoopChildComponentErrors` returns its diagnostics instead
|
|
7
|
+
* of pushing onto the adapter's error list, so the adapter stays the sole
|
|
8
|
+
* owner of `errors`.
|
|
9
|
+
*/
|
|
10
|
+
import type { ComponentIR, CompilerError } from '@barefootjs/jsx';
|
|
11
|
+
/**
|
|
12
|
+
* Whether the component needs the client runtime — it owns reactive state
|
|
13
|
+
* (signals / effects / onMount) or the analyzer flagged it as needing init.
|
|
14
|
+
*/
|
|
15
|
+
export declare function hasClientInteractivity(ir: ComponentIR): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Build a `BF103` diagnostic for every component reference inside a loop body
|
|
18
|
+
* whose name is imported from a relative-path module. Mirror of the Go /
|
|
19
|
+
* Xslate adapter's check — the Jinja adapter has the same
|
|
20
|
+
* cross-template-registration constraint at request time (each `.jinja`
|
|
21
|
+
* component file must be registered with the shared `jinja2.Environment`
|
|
22
|
+
* loader alongside the parent). Returns the diagnostics so the caller pushes
|
|
23
|
+
* them onto its own error list.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectImportedLoopChildComponentErrors(ir: ComponentIR, componentName: string): CompilerError[];
|
|
26
|
+
//# sourceMappingURL=component-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-tree.d.ts","sourceRoot":"","sources":["../../../src/adapter/analysis/component-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,WAAW,EAUX,aAAa,EACd,MAAM,iBAAiB,CAAA;AAExB;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAO/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uCAAuC,CACrD,EAAE,EAAE,WAAW,EACf,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAqEjB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural classifier for JS expressions whose result is a boolean value
|
|
3
|
+
* (or unambiguously stringifies to "true"/"false" in JS).
|
|
4
|
+
*
|
|
5
|
+
* Ported from `packages/adapter-xslate/src/adapter/boolean-result.ts`
|
|
6
|
+
* (itself ported from the Mojo adapter's `bf->bool_str` classifier). Used by
|
|
7
|
+
* the Jinja adapter for TWO purposes — one inherited from Xslate, one new:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Attribute/text stringification** (inherited): route a boolean-shaped
|
|
10
|
+
* reactive binding through the runtime `bf.bool_str` helper so the
|
|
11
|
+
* serialised value matches JS `String(boolean)` ("true"/"false"). Python
|
|
12
|
+
* has a real `bool` type (unlike Perl's `1`/`''`), but Python's own
|
|
13
|
+
* `str(True)` == `"True"` (capitalised) — still wrong for HTML output —
|
|
14
|
+
* so the same explicit routing is required.
|
|
15
|
+
* 2. **Condition-position truthy wrapping** (new — `isBooleanResultParsed` is
|
|
16
|
+
* exported, not just the string-based `isBooleanResultExpr`): Python
|
|
17
|
+
* truthiness diverges from JS specifically on empty containers (`[]` /
|
|
18
|
+
* `{}` are JS-truthy, Python-falsy). Perl doesn't have this problem — a
|
|
19
|
+
* Perl array/hash REFERENCE is always true, matching JS objects/arrays
|
|
20
|
+
* being unconditionally truthy — which is why Xslate never needed a
|
|
21
|
+
* truthy-routing layer for `if`/ternary/`&&`/`||` conditions. The Jinja
|
|
22
|
+
* adapter's condition-emission call sites (see `jinja-adapter.ts`'s
|
|
23
|
+
* `convertConditionToJinja`) reuse this SAME structural classifier: a
|
|
24
|
+
* condition that is already unambiguously boolean-shaped emits directly;
|
|
25
|
+
* everything else is wrapped in `bf.truthy(...)` (a JS-faithful
|
|
26
|
+
* `ToBoolean`) before being used as an `{% if %}` / ternary test.
|
|
27
|
+
*
|
|
28
|
+
* The classifier walks a `ParsedExpr` produced by
|
|
29
|
+
* `@barefootjs/jsx::parseExpression` — same AST the filter / loop lowerings
|
|
30
|
+
* already use — so detection is structural rather than regex-text-matching.
|
|
31
|
+
* Wrapped expression text is left to the caller's existing
|
|
32
|
+
* `convertExpressionToJinja` pipeline; this module only decides whether to
|
|
33
|
+
* wrap.
|
|
34
|
+
*
|
|
35
|
+
* Detected shapes:
|
|
36
|
+
* - `binary` with a comparison operator (`<`, `>`, `<=`, `>=`, `==`, `===`,
|
|
37
|
+
* `!=`, `!==`)
|
|
38
|
+
* - `unary` with logical `!`
|
|
39
|
+
* - `literal` with `literalType: 'boolean'`
|
|
40
|
+
* - `logical` (`&&` / `||` / `??`) when both sides are themselves
|
|
41
|
+
* boolean-result (catches `x > 0 && y < 10`; intentionally does NOT
|
|
42
|
+
* catch `x() || 'fallback'` whose right side stringifies as a regular
|
|
43
|
+
* value)
|
|
44
|
+
* - `conditional` (`?:`) when both branches are themselves boolean-result
|
|
45
|
+
*
|
|
46
|
+
* Anything else returns `false` — including bare identifiers (`accepted`)
|
|
47
|
+
* and call expressions (`accepted()`) whose return type the adapter has no
|
|
48
|
+
* way to infer from source text alone.
|
|
49
|
+
*/
|
|
50
|
+
import { type ParsedExpr } from '@barefootjs/jsx';
|
|
51
|
+
/**
|
|
52
|
+
* Structural boolean-result check over an already-parsed `ParsedExpr` tree.
|
|
53
|
+
* Exported (unlike Xslate's private equivalent) so the condition-position
|
|
54
|
+
* truthy-wrapping call sites can reuse it without a stringify → re-parse
|
|
55
|
+
* round-trip.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isBooleanResultParsed(node: ParsedExpr): boolean;
|
|
58
|
+
export declare function isBooleanResultExpr(expr: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* True when `expr`'s top-level shape is an explicit JS `String(x)` call
|
|
61
|
+
* (the `EVAL_BUILTIN_IDENTS` builtin the compiler recognizes structurally —
|
|
62
|
+
* `packages/jsx/src/expression-parser.ts`'s `EVAL_BUILTIN_IDENTS`; lowered
|
|
63
|
+
* by this adapter's `String` template primitive to `bf.string(x)`, see
|
|
64
|
+
* `lib/constants.ts`).
|
|
65
|
+
*
|
|
66
|
+
* Guards the `isAriaBooleanAttr`-driven `bf.bool_str(...)` override in
|
|
67
|
+
* `jinja-adapter.ts`'s `elementAttrEmitter`: `bf.string` and `bf.bool_str`
|
|
68
|
+
* produce IDENTICAL text for a real Python `bool` (both are `"true"` /
|
|
69
|
+
* `"false"`), so applying `bf.bool_str` to `String(x)`'s ALREADY-STRINGIFIED
|
|
70
|
+
* result is not a no-op — it is a Python-truthiness test over that STRING
|
|
71
|
+
* ("false" is a non-empty Python string, hence truthy, so
|
|
72
|
+
* `bf.bool_str(bf.string(false))` would wrongly render `"true"`). The Kolon
|
|
73
|
+
* port has the identical double-wrap shape and "works" only by an
|
|
74
|
+
* unrelated accident (`JSON::PP::Boolean` stringifies to `"0"`/`"1"`, and
|
|
75
|
+
* Perl specifically treats the STRING `"0"` as falsy) that doesn't hold in
|
|
76
|
+
* Python. An author who explicitly writes `String(...)` has already opted
|
|
77
|
+
* into JS `String()` semantics — `bf.string(x)` alone (which DOES special-
|
|
78
|
+
* case booleans, see `runtime.js_string`) is the complete, correct
|
|
79
|
+
* lowering; no attribute-name-driven override should run again on top of
|
|
80
|
+
* it.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isExplicitStringCall(expr: string): boolean;
|
|
83
|
+
export declare function isAriaBooleanAttr(name: string): boolean;
|
|
84
|
+
//# sourceMappingURL=boolean-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boolean-result.d.ts","sourceRoot":"","sources":["../../src/adapter/boolean-result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAalE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAuB/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS1D;AAyCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract the extracted expression-emitter modules depend on instead of
|
|
3
|
+
* the concrete `JinjaAdapter`.
|
|
4
|
+
*
|
|
5
|
+
* Ported from `packages/adapter-xslate/src/adapter/emit-context.ts`. The
|
|
6
|
+
* Jinja adapter's top-level expression lowering is mutually recursive with
|
|
7
|
+
* the adapter's own const/record resolution and its filter-predicate
|
|
8
|
+
* emitter, so the extracted `JinjaTopLevelEmitter` still needs to call back
|
|
9
|
+
* into shared per-compile state and recursive entry points.
|
|
10
|
+
* `JinjaEmitContext` is that seam: the emitter takes a `JinjaEmitContext`
|
|
11
|
+
* built by the adapter's private `emitCtx` getter (the adapter does NOT
|
|
12
|
+
* `implements` this interface, so the wrapped members stay private and off
|
|
13
|
+
* its exported public type). The emitter depends on this narrow interface
|
|
14
|
+
* rather than the full class, so the coupling is explicit and it's
|
|
15
|
+
* unit-testable against a stub.
|
|
16
|
+
*
|
|
17
|
+
* Keep this surface minimal: add a member only when an extracted module
|
|
18
|
+
* genuinely needs it, so the seam documents the real cross-module coupling
|
|
19
|
+
* rather than re-exposing the whole adapter.
|
|
20
|
+
*/
|
|
21
|
+
import type { ParsedExpr, CompilerError, IRMetadata } from '@barefootjs/jsx';
|
|
22
|
+
export interface JinjaEmitContext {
|
|
23
|
+
/**
|
|
24
|
+
* (#1922) Local binding names the request-scoped `searchParams()` env signal
|
|
25
|
+
* is imported under. Non-empty enables the env-signal method-call lowering.
|
|
26
|
+
*/
|
|
27
|
+
readonly _searchParamsLocals: Set<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Inline a module-scope pure string-literal const by name as the resolved
|
|
30
|
+
* literal value, or null when the name is not such a const.
|
|
31
|
+
*/
|
|
32
|
+
_resolveModuleStringConst(name: string): string | null;
|
|
33
|
+
/** Resolve a literal const (`const totalPages = 5`) to its Jinja value, or null. */
|
|
34
|
+
_resolveLiteralConst(name: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a static property access on a module object-literal const
|
|
37
|
+
* (`variantClasses.ghost`) to its Jinja value at compile time, or null.
|
|
38
|
+
*/
|
|
39
|
+
_resolveStaticRecordLiteral(objectName: string, key: string): string | null;
|
|
40
|
+
/** Record a BF101 unsupported-expression diagnostic. */
|
|
41
|
+
_recordExprBF101(message: string, reason?: string): void;
|
|
42
|
+
/** Lower a filter/predicate body to its Jinja form, bound to `param`. */
|
|
43
|
+
_renderJinjaFilterExprPublic(expr: ParsedExpr, param: string): string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The contract the extracted object-literal / conditional-spread lowering
|
|
47
|
+
* (`spread/spread-codegen.ts`) depends on. Declared separately from
|
|
48
|
+
* `JinjaEmitContext` so each extracted module's real coupling is documented
|
|
49
|
+
* precisely. Mirror of the Xslate adapter's `XslateSpreadContext`.
|
|
50
|
+
*/
|
|
51
|
+
export interface JinjaSpreadContext {
|
|
52
|
+
/** Component name, for diagnostic source locations. */
|
|
53
|
+
readonly componentName: string;
|
|
54
|
+
/** Per-compile diagnostic list the spread lowering appends to. */
|
|
55
|
+
readonly errors: CompilerError[];
|
|
56
|
+
/** Local-constant metadata, for resolving `Record[key]` spread values. */
|
|
57
|
+
readonly localConstants: IRMetadata['localConstants'];
|
|
58
|
+
/** Prop params, for classifying a bare-identifier index as a prop. */
|
|
59
|
+
readonly propsParams: {
|
|
60
|
+
name: string;
|
|
61
|
+
}[];
|
|
62
|
+
/**
|
|
63
|
+
* Lower a JS expression to its Jinja form (the core recursive entry).
|
|
64
|
+
*
|
|
65
|
+
* When the IR already carries a structured `ParsedExpr` tree, pass it as
|
|
66
|
+
* `preParsed` so the converter threads it straight through instead of
|
|
67
|
+
* re-parsing `expr`. With `preParsed` set, `expr` is unused for parsing
|
|
68
|
+
* (the converter derives any diagnostic text from the tree), so callers
|
|
69
|
+
* may pass `''`.
|
|
70
|
+
*/
|
|
71
|
+
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string;
|
|
72
|
+
/**
|
|
73
|
+
* Lower a JS expression to a Jinja CONDITION (routes through `bf.truthy`
|
|
74
|
+
* unless the expression is structurally already boolean-shaped — see
|
|
75
|
+
* `boolean-result.ts`). Used for the conditional-spread ternary's test,
|
|
76
|
+
* which is a condition position, not a value position. Same `preParsed`
|
|
77
|
+
* contract as `convertExpressionToJinja`.
|
|
78
|
+
*/
|
|
79
|
+
convertConditionToJinja(expr: string, preParsed?: ParsedExpr): string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The contract the extracted in-template memo / context seeding
|
|
83
|
+
* (`memo/seed.ts`) depends on. The seed lowering recurses into the core
|
|
84
|
+
* expression lowering to compute a derived signal/memo value or a context
|
|
85
|
+
* default; that recursive entry is its only adapter coupling.
|
|
86
|
+
*/
|
|
87
|
+
export interface JinjaMemoContext {
|
|
88
|
+
/**
|
|
89
|
+
* Lower a JS expression to its Jinja form (the core recursive entry). See
|
|
90
|
+
* `JinjaSpreadContext.convertExpressionToJinja` for the `preParsed` contract.
|
|
91
|
+
*/
|
|
92
|
+
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string;
|
|
93
|
+
/**
|
|
94
|
+
* Per-compile diagnostic list `convertExpressionToJinja` appends to on an
|
|
95
|
+
* unsupported shape (`_recordExprBF101`). `memo/seed.ts`'s
|
|
96
|
+
* `generateDerivedMemoSeed` is a SPECULATIVE "try this in-template
|
|
97
|
+
* recomputation, else fall back to the static ssrDefault seed" attempt per
|
|
98
|
+
* plan step — unlike every other `convertExpressionToJinja` call site, a
|
|
99
|
+
* failure here must NOT become a hard compile error, so it snapshots this
|
|
100
|
+
* array's length before calling in and truncates back to it on failure
|
|
101
|
+
* (discarding whatever `_recordExprBF101` appended) rather than letting
|
|
102
|
+
* the error escape.
|
|
103
|
+
*/
|
|
104
|
+
readonly errors: CompilerError[];
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=emit-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CACjC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Array / string method lowering for the Jinja2 template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `packages/adapter-xslate/src/adapter/expr/array-method.ts`.
|
|
5
|
+
* Pure free functions shared by both the filter-context emitter and the
|
|
6
|
+
* top-level emitter — they take an `emit` callback for receiver / argument
|
|
7
|
+
* recursion and read no adapter instance state.
|
|
8
|
+
*
|
|
9
|
+
* The receiver/array helpers are the same runtime methods the Xslate adapter
|
|
10
|
+
* calls, invoked as `bf.NAME(...)` (bare, no `$` sigil) instead of
|
|
11
|
+
* `$bf.NAME(...)`.
|
|
12
|
+
*/
|
|
13
|
+
import type { ParsedExpr, ArrayMethod, SortComparator, FlatDepth } from '@barefootjs/jsx';
|
|
14
|
+
export declare function renderArrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Emit a `.sort(cmp)` / `.toSorted(cmp)` via the runtime evaluator (#2018):
|
|
17
|
+
* the comparator body travels as serialized-ParsedExpr JSON, evaluated per
|
|
18
|
+
* comparison against `{paramA, paramB, …captured}`. Returns null when the
|
|
19
|
+
* body is outside the evaluator surface (e.g. a `localeCompare` comparator —
|
|
20
|
+
* `serializeParsedExpr` refuses it), so the caller falls back to the
|
|
21
|
+
* structured `bf.sort`. `params` are the comparator arrow's two params
|
|
22
|
+
* (`[paramA, paramB]`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function renderSortEval(recv: string, body: ParsedExpr, params: string[], emit: (e: ParsedExpr) => string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Emit a `.reduce(fn, init)` / `.reduceRight(fn, init)` via the runtime
|
|
27
|
+
* evaluator (#2018): the reducer body travels as serialized-ParsedExpr JSON,
|
|
28
|
+
* folded over the receiver from `init` in `direction` order. `params` are the
|
|
29
|
+
* reducer arrow's params (`[paramAcc, paramItem]`); `init` is the initial-value
|
|
30
|
+
* `ParsedExpr` from the call's trailing argument. Returns null when the body is
|
|
31
|
+
* outside the evaluator surface, or when `init` is not a literal string/number
|
|
32
|
+
* (→ caller refuses with BF101). A numeric seed passes through as a bare
|
|
33
|
+
* Jinja number; a string seed as a single-quoted literal.
|
|
34
|
+
*/
|
|
35
|
+
export declare function renderReduceEval(recv: string, body: ParsedExpr, params: string[], init: ParsedExpr, direction: 'left' | 'right', emit: (e: ParsedExpr) => string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Emit a higher-order predicate call via the runtime evaluator (#2018, P2):
|
|
38
|
+
* `bf.filter_eval` / `bf.every_eval` / `bf.some_eval` / `bf.find_eval` /
|
|
39
|
+
* `bf.find_index_eval`, carrying the serialized predicate body + captured env
|
|
40
|
+
* dict. Generalizes the lambda lowering to the same JS-faithful evaluator
|
|
41
|
+
* the Go/Xslate adapters use. Returns null when the predicate is outside the
|
|
42
|
+
* evaluator surface (e.g. a method-call predicate — `serializeParsedExpr`
|
|
43
|
+
* refuses it), so the caller falls back to the lambda form. `forward`
|
|
44
|
+
* (find / findIndex family only) selects the search direction — `false` =
|
|
45
|
+
* findLast / findLastIndex.
|
|
46
|
+
*/
|
|
47
|
+
export declare function renderPredicateEval(funcName: string, recv: string, predicate: ParsedExpr, param: string, emit: (e: ParsedExpr) => string, forward?: boolean): string | null;
|
|
48
|
+
/**
|
|
49
|
+
* Emit a `.flatMap(proj)` via the runtime evaluator (#2018, P3): the projection
|
|
50
|
+
* body serializes to JSON and `bf.flat_map_eval` projects + flattens one
|
|
51
|
+
* level. `param` is the projection arrow's single param. Returns null when the
|
|
52
|
+
* projection is outside the evaluator surface (→ caller refuses with BF101).
|
|
53
|
+
*/
|
|
54
|
+
export declare function renderFlatMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Emit a value-producing `.map(cb)` via the runtime evaluator (#2073): the
|
|
57
|
+
* projection body serializes to JSON and `bf.map_eval` projects each element,
|
|
58
|
+
* one result per element (no flatten — the JS `.map` contract). Composes
|
|
59
|
+
* through the array-method chain (`.map(cb).join(' ')`). Returns null when
|
|
60
|
+
* the projection is outside the evaluator surface (→ caller refuses with
|
|
61
|
+
* BF101). The JSX-returning `.map` is an IRLoop upstream and never reaches
|
|
62
|
+
* this emit.
|
|
63
|
+
*/
|
|
64
|
+
export declare function renderMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Shared Jinja emit for `.sort(cmp)` / `.toSorted(cmp)`. Used by both the
|
|
67
|
+
* filter-context emitter and the top-level emitter, plus the loop-array
|
|
68
|
+
* wrap in `renderLoop`. The runtime `bf.sort` accepts an opts dict and
|
|
69
|
+
* returns a fresh list.
|
|
70
|
+
*/
|
|
71
|
+
export declare function renderSortMethod(recv: string, c: SortComparator): string;
|
|
72
|
+
export declare function renderFlatMethod(recv: string, depth: FlatDepth | {
|
|
73
|
+
expr: ParsedExpr;
|
|
74
|
+
}, emit: (e: ParsedExpr) => string): string;
|
|
75
|
+
//# sourceMappingURL=array-method.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAGxB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA6HR;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAmBR"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ParsedExpr → Jinja2 emitters for the Jinja template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `packages/adapter-xslate/src/adapter/expr/emitters.ts`
|
|
5
|
+
* (`XslateFilterEmitter` / `XslateTopLevelEmitter`). Two `ParsedExprEmitter`
|
|
6
|
+
* implementations:
|
|
7
|
+
*
|
|
8
|
+
* - `JinjaFilterEmitter` — filter/predicate context (loop param + local
|
|
9
|
+
* aliases + bare identifier signal fallback); self-contained, reads no
|
|
10
|
+
* adapter state.
|
|
11
|
+
* - `JinjaTopLevelEmitter` — top-level / per-render-var context; depends on
|
|
12
|
+
* the adapter only through the narrow `JinjaEmitContext` seam.
|
|
13
|
+
*
|
|
14
|
+
* Two deliberate divergences from the Kolon port, both documented at their
|
|
15
|
+
* definition site below:
|
|
16
|
+
*
|
|
17
|
+
* 1. **JS-truthy condition wrapping** (`truthyTest`) — Python truthiness
|
|
18
|
+
* diverges from JS on empty containers; Perl doesn't have this problem
|
|
19
|
+
* (a Perl ref is always true), so Kolon never needed this. Every
|
|
20
|
+
* condition-TEST position (`!x`, the left operand of `&&`/`||`, a
|
|
21
|
+
* ternary's test) routes through the shared `bf.truthy(...)` runtime
|
|
22
|
+
* helper unless the operand is structurally already boolean-shaped
|
|
23
|
+
* (`isBooleanResultParsed`). `&&`/`||` still return the ORIGINAL
|
|
24
|
+
* operand VALUE (not a coerced bool) on the taken branch — matching JS
|
|
25
|
+
* `a || b` returning `a` itself, not `true` — only the BRANCH TEST uses
|
|
26
|
+
* `bf.truthy`. Because Jinja's `if/else` ternary has no way to reuse an
|
|
27
|
+
* already-computed test value for both the test and (conditionally) the
|
|
28
|
+
* result, the left operand's rendered text is emitted TWICE (once as
|
|
29
|
+
* the test, once as the value) — safe because every operand reaching
|
|
30
|
+
* this pipeline is a pure, side-effect-free read (a signal/prop lookup
|
|
31
|
+
* or a call into a pure runtime helper), never a stateful expression.
|
|
32
|
+
* 2. **No Jinja lambda for the predicate-callback fallback.** Kolon's
|
|
33
|
+
* `-> $x { … }` lambda is the Xslate top-level emitter's fallback when a
|
|
34
|
+
* `.filter`/`.every`/`.some`/`.find*` predicate can't be serialized to
|
|
35
|
+
* the runtime evaluator's JSON form (e.g. a nested method-call
|
|
36
|
+
* predicate). Jinja has no lambda-expression syntax at all, so there is
|
|
37
|
+
* no equivalent fallback to port. `JinjaTopLevelEmitter` therefore uses
|
|
38
|
+
* ONE mechanism for every higher-order callback: the evaluator-JSON
|
|
39
|
+
* `*_eval` payload (`bf.filter_eval`, `bf.sort_eval`, …). When
|
|
40
|
+
* `serializeParsedExpr` refuses the body, the call surfaces `BF101`
|
|
41
|
+
* instead of silently degrading — `.sort`/`.toSorted` is the one
|
|
42
|
+
* exception, whose non-lambda STRUCTURED fallback (`bf.sort` with a
|
|
43
|
+
* `{keys: […]}` descriptor, no callback body at all) survives the port
|
|
44
|
+
* unchanged since it was never lambda-shaped to begin with.
|
|
45
|
+
* `JinjaFilterEmitter` (the loop `.filter().map()` INLINE predicate,
|
|
46
|
+
* rendered as a plain boolean expression, never a lambda) is otherwise
|
|
47
|
+
* unaffected and still used for that path plus the filter-predicate
|
|
48
|
+
* entry point `_renderJinjaFilterExprPublic`.
|
|
49
|
+
*/
|
|
50
|
+
import { type ParsedExprEmitter, type ArrayMethod, type LiteralType, type ParsedExpr, type ObjectLiteralProperty, type FlatDepth, type TemplatePart } from '@barefootjs/jsx';
|
|
51
|
+
import type { JinjaEmitContext } from '../emit-context.ts';
|
|
52
|
+
/**
|
|
53
|
+
* Route a condition-TEST position through `bf.truthy(...)` unless the node
|
|
54
|
+
* is structurally already boolean-shaped. See the file header (divergence
|
|
55
|
+
* 1). Shared by both emitters below and reused by the adapter's top-level
|
|
56
|
+
* `convertConditionToJinja` for IR-level `if` / loop-filter conditions.
|
|
57
|
+
*/
|
|
58
|
+
export declare function truthyTest(node: ParsedExpr, rendered: string): string;
|
|
59
|
+
/**
|
|
60
|
+
* Lowering for the predicate body of a filter / every / some / find, plus the
|
|
61
|
+
* same shape used by the loop-hoist `.filter().map()` inline condition.
|
|
62
|
+
* Higher-order predicates are emitted using Jinja's own scalar comparison
|
|
63
|
+
* operators.
|
|
64
|
+
*
|
|
65
|
+
* NOTE: Jinja has no `[x for x in … if …]`-as-expression form usable inline
|
|
66
|
+
* here (a comprehension is a value producer, not a boolean test), so a
|
|
67
|
+
* nested higher-order call (`x.tags.filter(...)`, `other.some(...)`) inside
|
|
68
|
+
* a predicate has no faithful scalar lowering here either — same BF101
|
|
69
|
+
* surfacing as Kolon (#2038) instead of silently degrading to the
|
|
70
|
+
* callback's receiver.
|
|
71
|
+
*/
|
|
72
|
+
export declare class JinjaFilterEmitter implements ParsedExprEmitter {
|
|
73
|
+
private readonly param;
|
|
74
|
+
private readonly localVarMap;
|
|
75
|
+
private readonly isStringName;
|
|
76
|
+
private readonly onUnsupported?;
|
|
77
|
+
constructor(param: string, localVarMap: Map<string, string>, isStringName?: (n: string) => boolean, onUnsupported?: ((message: string, reason?: string) => void) | undefined);
|
|
78
|
+
identifier(name: string): string;
|
|
79
|
+
literal(value: string | number | boolean | null, literalType: LiteralType): string;
|
|
80
|
+
member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
|
|
81
|
+
indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
82
|
+
call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
83
|
+
unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
84
|
+
binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
85
|
+
logical(op: '&&' | '||' | '??', left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
86
|
+
callbackMethod(method: string, object: ParsedExpr, _arrow: Extract<ParsedExpr, {
|
|
87
|
+
kind: 'arrow';
|
|
88
|
+
}>, _restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
89
|
+
arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
90
|
+
arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
91
|
+
flatMethod(object: ParsedExpr, depth: FlatDepth | {
|
|
92
|
+
expr: ParsedExpr;
|
|
93
|
+
}, emit: (e: ParsedExpr) => string): string;
|
|
94
|
+
conditional(_test: ParsedExpr, _consequent: ParsedExpr, _alternate: ParsedExpr): string;
|
|
95
|
+
templateLiteral(_parts: TemplatePart[]): string;
|
|
96
|
+
arrow(_params: string[], _body: ParsedExpr): string;
|
|
97
|
+
regex(_raw: string): string;
|
|
98
|
+
unsupported(_raw: string, _reason: string): string;
|
|
99
|
+
objectLiteral(_properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Lowering for top-level expressions whose identifiers resolve against the
|
|
103
|
+
* Jinja template's per-render context vars (signals, props, locals
|
|
104
|
+
* introduced by `{% set x = … %}`). Differs from the filter emitter mainly
|
|
105
|
+
* in
|
|
106
|
+
* - `conditional` is supported (filter predicates can't return ternaries),
|
|
107
|
+
* - higher-order methods route through `bf.*` array/evaluator helpers,
|
|
108
|
+
* - no lambda fallback exists (see the file header, divergence 2).
|
|
109
|
+
*/
|
|
110
|
+
export declare class JinjaTopLevelEmitter implements ParsedExprEmitter {
|
|
111
|
+
private readonly ctx;
|
|
112
|
+
constructor(ctx: JinjaEmitContext);
|
|
113
|
+
identifier(name: string): string;
|
|
114
|
+
literal(value: string | number | boolean | null, literalType: LiteralType): string;
|
|
115
|
+
member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
|
|
116
|
+
indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
117
|
+
call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
118
|
+
unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
119
|
+
binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
120
|
+
logical(op: '&&' | '||' | '??', left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
121
|
+
callbackMethod(method: string, object: ParsedExpr, arrow: Extract<ParsedExpr, {
|
|
122
|
+
kind: 'arrow';
|
|
123
|
+
}>, restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Lower a boolean-predicate callback (`filter` / `find*` / `every` /
|
|
126
|
+
* `some`). See the file header, divergence 2: Jinja has no lambda
|
|
127
|
+
* expression, so — unlike Kolon — there is no non-evaluator fallback here.
|
|
128
|
+
* A predicate the evaluator can't model surfaces `BF101`.
|
|
129
|
+
*/
|
|
130
|
+
private _emitPredicateCallback;
|
|
131
|
+
arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
132
|
+
arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
|
|
133
|
+
flatMethod(object: ParsedExpr, depth: FlatDepth | {
|
|
134
|
+
expr: ParsedExpr;
|
|
135
|
+
}, emit: (e: ParsedExpr) => string): string;
|
|
136
|
+
conditional(test: ParsedExpr, consequent: ParsedExpr, alternate: ParsedExpr, emit: (e: ParsedExpr) => string): string;
|
|
137
|
+
templateLiteral(parts: TemplatePart[], emit: (e: ParsedExpr) => string): string;
|
|
138
|
+
arrow(_params: string[], _body: ParsedExpr): string;
|
|
139
|
+
regex(_raw: string): string;
|
|
140
|
+
unsupported(_raw: string, _reason: string): string;
|
|
141
|
+
objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=emitters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operand-type classification for the Jinja2 template adapter.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `packages/adapter-xslate/src/adapter/expr/operand.ts`. Pure
|
|
5
|
+
* function over `ParsedExpr` taking an `isStringName` predicate rather than
|
|
6
|
+
* reading adapter instance state.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: like Kolon's `==`/`!=`, Jinja/Python's `==`/`!=` are value-equality
|
|
9
|
+
* operators that compare strings and numbers correctly, so the Jinja
|
|
10
|
+
* emitters never need to steer string comparisons onto a different operator
|
|
11
|
+
* family. This helper is therefore not consumed by the Jinja lowering
|
|
12
|
+
* today either — kept only as the parallel of the Xslate/Mojo adapters'
|
|
13
|
+
* `expr/operand.ts` (groundwork for a future shared codegen surface).
|
|
14
|
+
*/
|
|
15
|
+
import type { ParsedExpr } from '@barefootjs/jsx';
|
|
16
|
+
/**
|
|
17
|
+
* Whether a comparison operand is string-typed. In the Mojo adapter this
|
|
18
|
+
* selects Perl `eq`/`ne` over numeric `==`/`!=` for a `===`/`!==` against a
|
|
19
|
+
* string operand. Neither the Kolon nor the Jinja emitters consume it —
|
|
20
|
+
* both languages' `==`/`!=` compare strings and numbers correctly, so
|
|
21
|
+
* `===`/`!==` always map to `==`/`!=`. Kept only as the parallel of the
|
|
22
|
+
* Xslate/Mojo helper.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean;
|
|
25
|
+
//# sourceMappingURL=operand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operand.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/operand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CASpG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
|