@barefootjs/go-template 0.15.2 → 0.17.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/dist/adapter/analysis/component-tree.d.ts +23 -0
- package/dist/adapter/analysis/component-tree.d.ts.map +1 -0
- package/dist/adapter/emit-context.d.ts +53 -0
- package/dist/adapter/emit-context.d.ts.map +1 -0
- package/dist/adapter/expr/helper-inline.d.ts +31 -0
- package/dist/adapter/expr/helper-inline.d.ts.map +1 -0
- package/dist/adapter/expr/url-builder.d.ts +23 -0
- package/dist/adapter/expr/url-builder.d.ts.map +1 -0
- package/dist/adapter/go-template-adapter.d.ts +291 -1070
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +2859 -2618
- package/dist/adapter/lib/compile-state.d.ts +116 -0
- package/dist/adapter/lib/compile-state.d.ts.map +1 -0
- package/dist/adapter/lib/constants.d.ts +11 -0
- package/dist/adapter/lib/constants.d.ts.map +1 -0
- package/dist/adapter/lib/go-emit.d.ts +117 -0
- package/dist/adapter/lib/go-emit.d.ts.map +1 -0
- package/dist/adapter/lib/go-naming.d.ts +39 -0
- package/dist/adapter/lib/go-naming.d.ts.map +1 -0
- package/dist/adapter/lib/ir-scope.d.ts +13 -0
- package/dist/adapter/lib/ir-scope.d.ts.map +1 -0
- package/dist/adapter/lib/types.d.ts +165 -0
- package/dist/adapter/lib/types.d.ts.map +1 -0
- package/dist/adapter/memo/ctor-lowering.d.ts +39 -0
- package/dist/adapter/memo/ctor-lowering.d.ts.map +1 -0
- package/dist/adapter/memo/memo-compute.d.ts +124 -0
- package/dist/adapter/memo/memo-compute.d.ts.map +1 -0
- package/dist/adapter/memo/memo-type.d.ts +38 -0
- package/dist/adapter/memo/memo-type.d.ts.map +1 -0
- package/dist/adapter/memo/memo-value.d.ts +64 -0
- package/dist/adapter/memo/memo-value.d.ts.map +1 -0
- package/dist/adapter/memo/template-interp.d.ts +43 -0
- package/dist/adapter/memo/template-interp.d.ts.map +1 -0
- package/dist/adapter/props/prop-types.d.ts +31 -0
- package/dist/adapter/props/prop-types.d.ts.map +1 -0
- package/dist/adapter/spread/spread-codegen.d.ts +40 -0
- package/dist/adapter/spread/spread-codegen.d.ts.map +1 -0
- package/dist/adapter/type/type-codegen.d.ts +25 -0
- package/dist/adapter/type/type-codegen.d.ts.map +1 -0
- package/dist/adapter/value/parsed-literal-to-go.d.ts +17 -0
- package/dist/adapter/value/parsed-literal-to-go.d.ts.map +1 -0
- package/dist/adapter/value/value-lowering.d.ts +46 -0
- package/dist/adapter/value/value-lowering.d.ts.map +1 -0
- package/dist/build.js +2857 -2616
- package/dist/index.js +2859 -2618
- package/dist/test-render.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/derived-state-memo.test.ts +155 -84
- package/src/__tests__/go-template-adapter.test.ts +211 -60
- package/src/__tests__/lowering-plugin.test.ts +109 -0
- package/src/__tests__/query-href.test.ts +179 -0
- package/src/adapter/analysis/component-tree.ts +174 -0
- package/src/adapter/emit-context.ts +59 -0
- package/src/adapter/expr/helper-inline.ts +274 -0
- package/src/adapter/expr/url-builder.ts +123 -0
- package/src/adapter/go-template-adapter.ts +2100 -5316
- package/src/adapter/lib/compile-state.ts +150 -0
- package/src/adapter/lib/constants.ts +24 -0
- package/src/adapter/lib/go-emit.ts +289 -0
- package/src/adapter/lib/go-naming.ts +84 -0
- package/src/adapter/lib/ir-scope.ts +31 -0
- package/src/adapter/lib/types.ts +182 -0
- package/src/adapter/memo/ctor-lowering.ts +267 -0
- package/src/adapter/memo/memo-compute.ts +451 -0
- package/src/adapter/memo/memo-type.ts +74 -0
- package/src/adapter/memo/memo-value.ts +197 -0
- package/src/adapter/memo/template-interp.ts +246 -0
- package/src/adapter/props/prop-types.ts +84 -0
- package/src/adapter/spread/spread-codegen.ts +458 -0
- package/src/adapter/type/type-codegen.ts +95 -0
- package/src/adapter/value/parsed-literal-to-go.ts +94 -0
- package/src/adapter/value/value-lowering.ts +162 -0
- package/src/test-render.ts +2 -14
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go lowering of helper calls to template expressions. Renders backend-neutral
|
|
3
|
+
* `LoweringNode`s produced by registered lowering plugins (#2057) — one uniform
|
|
4
|
+
* path for both userland plugins and built-ins like `queryHref` (a default plugin
|
|
5
|
+
* that lowers to `bf_query`, #2042). Every node funnels through
|
|
6
|
+
* `renderLoweringNode`, which maps a logical helper id to its Go helper; the
|
|
7
|
+
* adapter carries no per-API recognition branch of its own.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
type LoweringNode,
|
|
12
|
+
type ParsedExpr,
|
|
13
|
+
parseExpression,
|
|
14
|
+
stringifyParsedExpr,
|
|
15
|
+
} from '@barefootjs/jsx'
|
|
16
|
+
|
|
17
|
+
import type { GoEmitContext } from '../emit-context.ts'
|
|
18
|
+
import { wrapIfMultiToken } from '../lib/go-emit.ts'
|
|
19
|
+
|
|
20
|
+
/** Logical helper id → Go template helper name. */
|
|
21
|
+
const GO_HELPER_NAMES: Record<string, string> = { query: 'bf_query' }
|
|
22
|
+
|
|
23
|
+
const BOOL_COMPARISON_OPS: ReadonlySet<string> = new Set([
|
|
24
|
+
'==', '===', '!=', '!==', '<', '>', '<=', '>=',
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Lower an expression to a Go *bool* for `bf_query`'s `include` argument. A
|
|
29
|
+
* comparison / negation / bool-literal already yields a bool
|
|
30
|
+
* (`convertConditionToGo`); anything else is JS string-truthiness, lowered to
|
|
31
|
+
* `ne <value> ""`. The arg must be a real bool — `bf_query` type-asserts it, so
|
|
32
|
+
* Go-template truthiness (`{{if x}}`) is not enough.
|
|
33
|
+
*
|
|
34
|
+
* The `ne <value> ""` path models *string* truthiness, which is the query
|
|
35
|
+
* domain: `queryHref` values are strings (`QueryParamValue`). A guard on a
|
|
36
|
+
* non-string value is outside the supported surface; the type-assert on
|
|
37
|
+
* `bf_query`'s include arg surfaces it as a build error rather than silently
|
|
38
|
+
* mis-including. (#2041 review.)
|
|
39
|
+
*/
|
|
40
|
+
function lowerUrlGuard(ctx: GoEmitContext, g: ParsedExpr): string {
|
|
41
|
+
// Comparisons, `!x`, and bool literals lower to a Go bool via the condition
|
|
42
|
+
// lowering. `&&` / `||` do NOT qualify: Go's `and`/`or` return one of their
|
|
43
|
+
// operands (a string for a truthiness guard like `tag && other`), not a
|
|
44
|
+
// bool — so they take the truthiness-wrap path below, yielding
|
|
45
|
+
// `ne (and …) ""`, an actual bool.
|
|
46
|
+
const isBoolShape =
|
|
47
|
+
(g.kind === 'binary' && BOOL_COMPARISON_OPS.has(g.op)) ||
|
|
48
|
+
(g.kind === 'unary' && g.op === '!') ||
|
|
49
|
+
(g.kind === 'literal' && g.literalType === 'boolean')
|
|
50
|
+
if (isBoolShape) {
|
|
51
|
+
return ctx.convertConditionToGo(stringifyParsedExpr(g), g).condition
|
|
52
|
+
}
|
|
53
|
+
const valueGo = wrapIfMultiToken(ctx.convertExpressionToGo(stringifyParsedExpr(g), undefined, g))
|
|
54
|
+
return `ne ${valueGo} ""`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Lower a helper call to a Go template expression, or null when no registered
|
|
59
|
+
* plugin recognises it (→ the generic lowering). Matchers — including the
|
|
60
|
+
* built-in `queryHref` plugin (#2042) — are bound to the component metadata at
|
|
61
|
+
* init (`ctx.state.loweringMatchers`), so this is one uniform loop with no
|
|
62
|
+
* per-API branch.
|
|
63
|
+
*
|
|
64
|
+
* Cheap-out: no active matchers → null; else reuse `preParsed` when it's already
|
|
65
|
+
* a call, otherwise a regex pre-filter gates the parse so non-call expressions
|
|
66
|
+
* never pay for `parseExpression`.
|
|
67
|
+
*/
|
|
68
|
+
export function lowerRegisteredCall(
|
|
69
|
+
ctx: GoEmitContext,
|
|
70
|
+
jsExpr: string,
|
|
71
|
+
preParsed?: ParsedExpr,
|
|
72
|
+
): string | null {
|
|
73
|
+
const matchers = ctx.state.loweringMatchers
|
|
74
|
+
if (matchers.length === 0) return null
|
|
75
|
+
|
|
76
|
+
let call: ParsedExpr | undefined = preParsed?.kind === 'call' ? preParsed : undefined
|
|
77
|
+
if (!call) {
|
|
78
|
+
if (!/^\s*[A-Za-z_$][\w$]*\s*\(/.test(jsExpr)) return null
|
|
79
|
+
const parsed = parseExpression(jsExpr)
|
|
80
|
+
if (parsed.kind !== 'call') return null
|
|
81
|
+
call = parsed
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (const matcher of matchers) {
|
|
85
|
+
const node = matcher(call.callee, call.args)
|
|
86
|
+
if (!node) continue
|
|
87
|
+
const rendered = renderLoweringNode(ctx, node)
|
|
88
|
+
if (rendered !== null) return rendered
|
|
89
|
+
}
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Render a backend-neutral lowering node to a Go template expression, or null
|
|
95
|
+
* when the node's `helper` has no Go mapping — the caller then declines
|
|
96
|
+
* (generic lowering → BF101), rather than emitting the raw helper id, which
|
|
97
|
+
* would be invalid Go. Adapters must switch on `helper`; an unknown one is not
|
|
98
|
+
* rendered.
|
|
99
|
+
*/
|
|
100
|
+
function renderLoweringNode(ctx: GoEmitContext, node: LoweringNode): string | null {
|
|
101
|
+
const helper = GO_HELPER_NAMES[node.helper]
|
|
102
|
+
if (!helper) return null
|
|
103
|
+
const lowerExpr = (n: ParsedExpr): string =>
|
|
104
|
+
ctx.convertExpressionToGo(stringifyParsedExpr(n), undefined, n)
|
|
105
|
+
if (node.kind === 'helper-call') {
|
|
106
|
+
const args = node.args.map(a => wrapIfMultiToken(lowerExpr(a)))
|
|
107
|
+
return [helper, ...args].join(' ')
|
|
108
|
+
}
|
|
109
|
+
// guard-list — `queryHref`-shaped. Inclusion mirrors the client exactly, where
|
|
110
|
+
// every param value is a STRING (`QueryParamValue`): bf_query drops an
|
|
111
|
+
// included-but-empty value and appends array members.
|
|
112
|
+
// - plain `key: v` (guard null) → `(true) "key" v`
|
|
113
|
+
// - conditional `key: cond ? a : <omit>` → `(<cond>) "key" a`, where the
|
|
114
|
+
// non-empty check is done by bf_query, not folded into the guard.
|
|
115
|
+
const parts: string[] = [wrapIfMultiToken(lowerExpr(node.base))]
|
|
116
|
+
for (const t of node.triples) {
|
|
117
|
+
const includeGo = t.guard === null ? 'true' : lowerUrlGuard(ctx, t.guard)
|
|
118
|
+
parts.push(`(${includeGo})`)
|
|
119
|
+
parts.push(JSON.stringify(t.key))
|
|
120
|
+
parts.push(wrapIfMultiToken(lowerExpr(t.value)))
|
|
121
|
+
}
|
|
122
|
+
return `${helper} ${parts.join(' ')}`
|
|
123
|
+
}
|