@barefootjs/jsx 0.5.3 → 0.6.1
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/adapters/parsed-expr-emitter.d.ts +15 -2
- package/dist/adapters/parsed-expr-emitter.d.ts.map +1 -1
- package/dist/expression-parser.d.ts +138 -1
- package/dist/expression-parser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +450 -23
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/generate-init.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +30 -1
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/phases/provider-and-child-inits.d.ts.map +1 -1
- package/dist/ir-to-client-js/plan/build-static-array-child-init.d.ts +4 -0
- package/dist/ir-to-client-js/plan/build-static-array-child-init.d.ts.map +1 -1
- package/dist/ir-to-client-js/plan/static-array-child-init.d.ts +46 -2
- package/dist/ir-to-client-js/plan/static-array-child-init.d.ts.map +1 -1
- package/dist/ir-to-client-js/stringify/static-array-child-init.d.ts.map +1 -1
- package/dist/ir-to-client-js/types.d.ts +10 -0
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/child-components-in-map.test.ts +84 -0
- package/src/__tests__/expression-parser.test.ts +276 -14
- package/src/__tests__/foreach-client-only.test.ts +80 -0
- package/src/__tests__/ir-reduce-op.test.ts +51 -0
- package/src/__tests__/ir-to-client-js/reactivity.test.ts +1 -0
- package/src/__tests__/reduce-op.test.ts +201 -0
- package/src/__tests__/staged-ir/06-multi-stage-soak.test.ts +18 -3
- package/src/adapters/parsed-expr-emitter.ts +50 -1
- package/src/expression-parser.ts +770 -21
- package/src/index.ts +1 -1
- package/src/ir-to-client-js/collect-elements.ts +9 -3
- package/src/ir-to-client-js/emit-registration.ts +1 -1
- package/src/ir-to-client-js/generate-init.ts +16 -1
- package/src/ir-to-client-js/html-template.ts +156 -2
- package/src/ir-to-client-js/index.ts +1 -0
- package/src/ir-to-client-js/phases/provider-and-child-inits.ts +12 -1
- package/src/ir-to-client-js/plan/build-static-array-child-init.ts +55 -1
- package/src/ir-to-client-js/plan/static-array-child-init.ts +47 -1
- package/src/ir-to-client-js/stringify/static-array-child-init.ts +69 -0
- package/src/ir-to-client-js/types.ts +10 -0
|
@@ -128,6 +128,20 @@ export interface TemplateOptions {
|
|
|
128
128
|
loopDepth?: number;
|
|
129
129
|
/** Emit `bf-s` placeholder on scoped elements inside a jsx-children prop (#1320). */
|
|
130
130
|
inHoistedChildren?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Slot ids of direct child components whose render must be DEFERRED to
|
|
133
|
+
* init because at least one forwarded (non-`/* @client *\/`) prop value
|
|
134
|
+
* references an init-scope-only / non-inlinable local — the module-scope
|
|
135
|
+
* template lambda can't supply it, so eagerly calling `renderChild` with
|
|
136
|
+
* the prop dropped would make the child template read `undefined`.
|
|
137
|
+
*
|
|
138
|
+
* For these slots the CSR `component` case emits a `data-bf-ph`
|
|
139
|
+
* placeholder instead of `renderChild(...)`; the parent init replaces it
|
|
140
|
+
* via `upsertChild` (→ `createComponent` with the complete getter props).
|
|
141
|
+
* Computed up front by `computeDeferredChildSlots` so the init phase and
|
|
142
|
+
* the template phase agree on which children defer (dropped-prop fix).
|
|
143
|
+
*/
|
|
144
|
+
deferredChildSlots?: ReadonlySet<string>;
|
|
131
145
|
}
|
|
132
146
|
/**
|
|
133
147
|
* Generate HTML template for registerTemplate().
|
|
@@ -176,7 +190,22 @@ export declare function canGenerateStaticTemplate(node: IRNode, propNames: Set<s
|
|
|
176
190
|
* @param inlinableConstants - Map of constant names to their resolved CSR values
|
|
177
191
|
* @param ctx - ClientJsContext supplying signals/memos for `csrSubstitute`
|
|
178
192
|
*/
|
|
179
|
-
export declare function generateCsrTemplate(node: IRNode, inlinableConstants: Map<string, string> | undefined, ctx: ClientJsContext, insideLoop?: boolean, restSpreadNames?: Set<string>, propsObjectName?: string | null, unsafeLocalNames?: Set<string>): string;
|
|
193
|
+
export declare function generateCsrTemplate(node: IRNode, inlinableConstants: Map<string, string> | undefined, ctx: ClientJsContext, insideLoop?: boolean, restSpreadNames?: Set<string>, propsObjectName?: string | null, unsafeLocalNames?: Set<string>, deferredChildSlots?: ReadonlySet<string>): string;
|
|
194
|
+
/**
|
|
195
|
+
* Walk the component IR and collect the slot ids of DIRECT child
|
|
196
|
+
* components whose render must be deferred to init because at least one
|
|
197
|
+
* forwarded (non-`/* @client *\/`, non-event) prop resolves to an
|
|
198
|
+
* init-scope-only / non-inlinable local. The module-scope CSR template
|
|
199
|
+
* lambda can't supply such a value, so `renderChild(...)` would drop the
|
|
200
|
+
* prop and the child template would read `undefined` and throw.
|
|
201
|
+
*
|
|
202
|
+
* Only top-level (non-loop, non-clientOnly-conditional) children are
|
|
203
|
+
* considered — those are the ones rendered via the `renderChild(...)` form
|
|
204
|
+
* in the registration template and wired through `ctx.childInits`. Loop /
|
|
205
|
+
* conditional-branch children already go through their own
|
|
206
|
+
* placeholder + `createComponent` materialize paths.
|
|
207
|
+
*/
|
|
208
|
+
export declare function computeDeferredChildSlots(node: IRNode, ctx: ClientJsContext, inlinableConstants: Map<string, string> | undefined, unsafeLocalNames: ReadonlySet<string> | undefined, propsObjectName?: string | null): Set<string>;
|
|
180
209
|
/**
|
|
181
210
|
* Check if an expression is a simple prop-based expression.
|
|
182
211
|
* Simple prop expressions access props only: todo.done, todo.text, props.name
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/html-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,
|
|
1
|
+
{"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/html-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-and-child-inits.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/phases/provider-and-child-inits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"provider-and-child-inits.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/phases/provider-and-child-inits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CA4BrF"}
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* 2. `outer-nested` for each depth-0 entry in `elem.nestedComponents`.
|
|
9
9
|
* 3. `inner-loop-nested` for each `elem.innerLoops` entry that has
|
|
10
10
|
* matching depth-N components.
|
|
11
|
+
* 4. `component-rooted-inner-loop` instead of (3) when the outer item is
|
|
12
|
+
* itself a child component (#1725) — the inner `.map()` lives inside
|
|
13
|
+
* the component's JSX children, so it's addressed by a document-order
|
|
14
|
+
* zip rather than element offsets.
|
|
11
15
|
*
|
|
12
16
|
* Selector / propsExpr / offset decisions all resolve here. The
|
|
13
17
|
* stringifier never inspects raw IR.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/plan/build-static-array-child-init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"build-static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/plan/build-static-array-child-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAO/C,OAAO,KAAK,EAQV,yBAAyB,EAC1B,MAAM,2BAA2B,CAAA;AAElC,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,eAAe,GACnB,yBAAyB,CAsC3B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plan types for `emitStaticArrayChildInits` — the
|
|
2
|
+
* Plan types for `emitStaticArrayChildInits` — the shapes that
|
|
3
3
|
* `static array` loops emit for child component initialisation:
|
|
4
4
|
*
|
|
5
5
|
* - `single-comp` — `loop.childComponent` ケース。一つの child component
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
* `__iterEl.querySelector(...)` 経由で initChild。
|
|
9
9
|
* - `inner-loop-nested` — depth > 0 の `nestedComponents`。outer + inner
|
|
10
10
|
* forEach の二重ループで initChild。
|
|
11
|
+
* - `component-rooted-inner-loop`
|
|
12
|
+
* — outer の loop item root が **child component**
|
|
13
|
+
* (`loop.childComponent`) で、その JSX children に
|
|
14
|
+
* component の nested `.map()` を持つケース (#1725)。
|
|
15
|
+
* element offset では fragment-root passthrough の
|
|
16
|
+
* flatten 済み items に届かないため、document order
|
|
17
|
+
* の zip (`qsaChildScopes` + cursor) で initChild。
|
|
11
18
|
*
|
|
12
19
|
* All decisions (selector, propsExpr, offset expressions) are resolved at
|
|
13
20
|
* build time so the stringifier becomes a deterministic walk.
|
|
@@ -122,6 +129,43 @@ export interface InnerLoopNestedInitPlan {
|
|
|
122
129
|
/** Per-component initialisers emitted inside the inner forEach body. */
|
|
123
130
|
comps: readonly InnerLoopComp[];
|
|
124
131
|
}
|
|
125
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Plan for an inner `.map()` of components living inside a **component-rooted**
|
|
134
|
+
* outer loop item (#1725). The outer loop body is a single child component
|
|
135
|
+
* (`loop.childComponent`, e.g. a `SelectGroup` passthrough) whose JSX
|
|
136
|
+
* `children` contain a nested `.map()` of components (e.g. `SelectItem`).
|
|
137
|
+
*
|
|
138
|
+
* `inner-loop-nested` can't be reused here: it addresses inner components via
|
|
139
|
+
* `containerVar.children[outerOffset]`, which assumes the outer loop item is a
|
|
140
|
+
* DOM **element**. A fragment-rooted passthrough component (`<>{children}</>`)
|
|
141
|
+
* emits no wrapper element, so its rendered items are flattened directly under
|
|
142
|
+
* the parent container with no per-group element to index.
|
|
143
|
+
*
|
|
144
|
+
* Instead this shape zips the inner component scopes — found in document order
|
|
145
|
+
* via `qsaChildScopes(container, <selector>)` — against the flattened
|
|
146
|
+
* `outer.forEach(o => inner.forEach(i => ...))` iteration. Document order is
|
|
147
|
+
* the SSR render order, so position `__ci++` pairs each scope with its data
|
|
148
|
+
* item regardless of whether the outer component root is an element or a
|
|
149
|
+
* fragment.
|
|
150
|
+
*/
|
|
151
|
+
export interface ComponentRootedInnerLoopInitPlan {
|
|
152
|
+
kind: 'component-rooted-inner-loop';
|
|
153
|
+
containerVar: string;
|
|
154
|
+
/** Outer loop's array expression. */
|
|
155
|
+
outerArrayExpr: string;
|
|
156
|
+
outerParam: string;
|
|
157
|
+
/** Outer `.map()` callback preamble locals (#1064). */
|
|
158
|
+
outerPreludeStatements: PreludeStatements;
|
|
159
|
+
/** Inner loop's array expression (references the outer param). */
|
|
160
|
+
innerArrayExpr: string;
|
|
161
|
+
innerParam: string;
|
|
162
|
+
/** Inner `.map()` callback preamble locals (#1064). */
|
|
163
|
+
innerPreludeStatements: PreludeStatements;
|
|
164
|
+
/** Depth used in the leading comment line. */
|
|
165
|
+
depth: number;
|
|
166
|
+
/** Per-component initialisers emitted inside the inner forEach body. */
|
|
167
|
+
comps: readonly InnerLoopComp[];
|
|
168
|
+
}
|
|
169
|
+
export type StaticArrayChildInitPlan = SingleCompInitPlan | OuterNestedInitPlan | InnerLoopNestedInitPlan | ComponentRootedInnerLoopInitPlan;
|
|
126
170
|
export type StaticArrayChildInitsPlan = readonly StaticArrayChildInitPlan[];
|
|
127
171
|
//# sourceMappingURL=static-array-child-init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/plan/static-array-child-init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/plan/static-array-child-init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/stringify/static-array-child-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"static-array-child-init.d.ts","sourceRoot":"","sources":["../../../src/ir-to-client-js/stringify/static-array-child-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,EAMV,yBAAyB,EAC1B,MAAM,iCAAiC,CAAA;AAGxC,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,yBAAyB,GAC/B,IAAI,CAIN"}
|
|
@@ -39,6 +39,16 @@ export interface ClientJsContext {
|
|
|
39
39
|
loopElements: TopLevelLoop[];
|
|
40
40
|
refElements: RefElement[];
|
|
41
41
|
childInits: ChildInit[];
|
|
42
|
+
/**
|
|
43
|
+
* Slot ids of direct child components whose render is DEFERRED to init
|
|
44
|
+
* (dropped-prop fix). For these, the CSR registration template emits a
|
|
45
|
+
* `data-bf-ph` placeholder instead of `renderChild(...)`, and the init
|
|
46
|
+
* body uses `upsertChild` (→ `createComponent` with full getter props)
|
|
47
|
+
* instead of `initChild`. Computed in `generateInitFunction` once
|
|
48
|
+
* `unsafeLocalNames` is known, then read by the child-init phase and the
|
|
49
|
+
* registration-template emit so both agree on which children defer.
|
|
50
|
+
*/
|
|
51
|
+
deferredChildSlots: Set<string>;
|
|
42
52
|
reactiveProps: ReactiveComponentProp[];
|
|
43
53
|
reactiveChildProps: ReactiveChildProp[];
|
|
44
54
|
reactiveAttrs: ReactiveAttribute[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ir-to-client-js/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/jsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "JSX compiler for BarefootJS - transforms JSX to server HTML + client JS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"directory": "packages/jsx"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@barefootjs/shared": "0.
|
|
56
|
+
"@barefootjs/shared": "0.6.1"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@barefootjs/client": ">=0.2.0",
|
|
@@ -1181,4 +1181,88 @@ describe('child components inside .map() (#344)', () => {
|
|
|
1181
1181
|
expect(content).toContain('const __compEl =')
|
|
1182
1182
|
expect(content).not.toContain('__compEl0')
|
|
1183
1183
|
})
|
|
1184
|
+
|
|
1185
|
+
describe('nested .map() inside a component-rooted loop item (#1725)', () => {
|
|
1186
|
+
// The outer loop item root is a *component* (a passthrough wrapper like
|
|
1187
|
+
// `SelectGroup`), not an element. Its JSX children contain a nested
|
|
1188
|
+
// `.map()` of components. The parent init emitted `initChild` for the
|
|
1189
|
+
// outer wrapper but never descended into its children to init the inner
|
|
1190
|
+
// loop's components — they rendered from SSR but never hydrated (silent).
|
|
1191
|
+
test('emits initChild for the inner-loop component (component wrapper)', () => {
|
|
1192
|
+
const source = `
|
|
1193
|
+
'use client'
|
|
1194
|
+
|
|
1195
|
+
export function Repro() {
|
|
1196
|
+
const GROUPS = [
|
|
1197
|
+
{ id: 'a', items: [{ id: 'a1', label: 'A1' }] },
|
|
1198
|
+
{ id: 'b', items: [{ id: 'b1', label: 'B1' }] },
|
|
1199
|
+
]
|
|
1200
|
+
return (
|
|
1201
|
+
<div>
|
|
1202
|
+
{GROUPS.map(group => (
|
|
1203
|
+
<Group key={group.id}>
|
|
1204
|
+
{group.items.map(it => (
|
|
1205
|
+
<Item key={it.id} label={it.label} />
|
|
1206
|
+
))}
|
|
1207
|
+
</Group>
|
|
1208
|
+
))}
|
|
1209
|
+
</div>
|
|
1210
|
+
)
|
|
1211
|
+
}
|
|
1212
|
+
`
|
|
1213
|
+
const result = compileJSX(source, 'Repro.tsx', { adapter })
|
|
1214
|
+
expect(result.errors).toHaveLength(0)
|
|
1215
|
+
|
|
1216
|
+
const content = result.files.find(f => f.type === 'clientJs')!.content
|
|
1217
|
+
// Both the outer wrapper and the inner-loop component must init.
|
|
1218
|
+
expect(content).toContain("initChild('Group'")
|
|
1219
|
+
expect(content).toContain("initChild('Item'")
|
|
1220
|
+
// The inner component's props read the inner loop param.
|
|
1221
|
+
expect(content).toContain('return it.label')
|
|
1222
|
+
// Document-order zip shape — a flat cursor over the queried scopes
|
|
1223
|
+
// pairs each with its data item across the nested forEach. This shape
|
|
1224
|
+
// is fragment-root safe (no per-group wrapper element to index).
|
|
1225
|
+
expect(content).toContain('qsaChildScopes')
|
|
1226
|
+
expect(content).toMatch(/__compScopes\[__ci\+\+\]/)
|
|
1227
|
+
// No element-offset addressing (`__outerEl = ...children[...]`) — that
|
|
1228
|
+
// would break for a fragment-rooted passthrough.
|
|
1229
|
+
expect(content).not.toContain('__outerEl')
|
|
1230
|
+
})
|
|
1231
|
+
|
|
1232
|
+
test('multiple inner components each get their own document-order cursor', () => {
|
|
1233
|
+
const source = `
|
|
1234
|
+
'use client'
|
|
1235
|
+
|
|
1236
|
+
export function Repro() {
|
|
1237
|
+
const GROUPS = [{ id: 'a', items: [{ id: 'a1', label: 'A1' }] }]
|
|
1238
|
+
return (
|
|
1239
|
+
<div>
|
|
1240
|
+
{GROUPS.map(group => (
|
|
1241
|
+
<Group key={group.id}>
|
|
1242
|
+
{group.items.map(it => (
|
|
1243
|
+
<>
|
|
1244
|
+
<Item key={it.id} label={it.label} />
|
|
1245
|
+
<Badge text={it.label} />
|
|
1246
|
+
</>
|
|
1247
|
+
))}
|
|
1248
|
+
</Group>
|
|
1249
|
+
))}
|
|
1250
|
+
</div>
|
|
1251
|
+
)
|
|
1252
|
+
}
|
|
1253
|
+
`
|
|
1254
|
+
const result = compileJSX(source, 'Repro.tsx', { adapter })
|
|
1255
|
+
expect(result.errors).toHaveLength(0)
|
|
1256
|
+
|
|
1257
|
+
const content = result.files.find(f => f.type === 'clientJs')!.content
|
|
1258
|
+
expect(content).toContain("initChild('Item'")
|
|
1259
|
+
expect(content).toContain("initChild('Badge'")
|
|
1260
|
+
// Distinct scope arrays + cursors so each comp consumes its own
|
|
1261
|
+
// document-order stream (no `const __compEl` redeclaration, #1664).
|
|
1262
|
+
expect(content).toContain('__compScopes0')
|
|
1263
|
+
expect(content).toContain('__compScopes1')
|
|
1264
|
+
expect(content).toMatch(/__ci0\+\+/)
|
|
1265
|
+
expect(content).toMatch(/__ci1\+\+/)
|
|
1266
|
+
})
|
|
1267
|
+
})
|
|
1184
1268
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, test, expect } from 'bun:test'
|
|
2
2
|
import ts from 'typescript'
|
|
3
|
-
import { parseExpression, isSupported, exprToString, parseBlockBody } from '../expression-parser'
|
|
3
|
+
import { parseExpression, isSupported, exprToString, stringifyParsedExpr, parseBlockBody } from '../expression-parser'
|
|
4
4
|
import { collectAllTypeRanges, reconstructWithoutTypes } from '../strip-types'
|
|
5
5
|
|
|
6
6
|
describe('expression-parser', () => {
|
|
@@ -398,25 +398,104 @@ describe('expression-parser', () => {
|
|
|
398
398
|
const result = parseExpression("items().filter(({name = 'anon'}) => name.startsWith('a'))")
|
|
399
399
|
expect(result.kind).toBe('higher-order')
|
|
400
400
|
if (result.kind === 'higher-order') {
|
|
401
|
-
// Predicate: `(_t.name ?? 'anon').startsWith('a')`.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
401
|
+
// Predicate: `(_t.name ?? 'anon').startsWith('a')`. Since #1448
|
|
402
|
+
// Tier B, `.startsWith` lowers to an `array-method` node (it was
|
|
403
|
+
// a generic `call` before), so the receiver is on `.object`.
|
|
404
|
+
expect(result.predicate.kind).toBe('array-method')
|
|
405
|
+
if (result.predicate.kind === 'array-method') {
|
|
406
|
+
expect(result.predicate.method).toBe('startsWith')
|
|
407
|
+
expect(result.predicate.object.kind).toBe('logical')
|
|
408
|
+
if (result.predicate.object.kind === 'logical') {
|
|
409
|
+
expect(result.predicate.object.op).toBe('??')
|
|
410
|
+
expect(result.predicate.object.right.kind).toBe('literal')
|
|
411
|
+
if (result.predicate.object.right.kind === 'literal') {
|
|
412
|
+
expect(result.predicate.object.right.value).toBe('anon')
|
|
414
413
|
}
|
|
415
414
|
}
|
|
416
415
|
}
|
|
417
416
|
}
|
|
418
417
|
})
|
|
419
418
|
|
|
419
|
+
test('lowers .startsWith(search, position) — full arity (#1448 Tier B)', () => {
|
|
420
|
+
const result = parseExpression(`name().startsWith("world", 6)`)
|
|
421
|
+
expect(result.kind).toBe('array-method')
|
|
422
|
+
if (result.kind === 'array-method') {
|
|
423
|
+
expect(result.method).toBe('startsWith')
|
|
424
|
+
// Both the search string and the position survive as args so the
|
|
425
|
+
// adapter can emit the re-anchored test.
|
|
426
|
+
expect(result.args.length).toBe(2)
|
|
427
|
+
}
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
test('refuses .startsWith() with no search string (#1448 Tier B)', () => {
|
|
431
|
+
// JS coerces the missing argument to the string "undefined" — a
|
|
432
|
+
// degenerate result not worth lowering (mirrors `.includes()`).
|
|
433
|
+
const result = parseExpression(`name().startsWith()`)
|
|
434
|
+
expect(result.kind).toBe('unsupported')
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
test('lowers .replace(pattern, replacement, extra) — ignores 3rd+ arg (#1448 Tier B)', () => {
|
|
438
|
+
const result = parseExpression(`name().replace("o", "0", "extra")`)
|
|
439
|
+
expect(result.kind).toBe('array-method')
|
|
440
|
+
if (result.kind === 'array-method') {
|
|
441
|
+
expect(result.method).toBe('replace')
|
|
442
|
+
}
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
test('refuses .replace(pattern) with no replacement (#1448 Tier B)', () => {
|
|
446
|
+
// JS coerces the missing replacement to the string "undefined".
|
|
447
|
+
const result = parseExpression(`name().replace("o")`)
|
|
448
|
+
expect(result.kind).toBe('unsupported')
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
test('refuses .replace() with no arguments (#1448 Tier B)', () => {
|
|
452
|
+
// The zero-arg form is degenerate too (both pattern and
|
|
453
|
+
// replacement coerce to "undefined") — pin it alongside the
|
|
454
|
+
// one-arg case so neither regresses.
|
|
455
|
+
const result = parseExpression(`name().replace()`)
|
|
456
|
+
expect(result.kind).toBe('unsupported')
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
test('.replace with a non-regex unsupported arg surfaces its own reason (#1448 Tier B)', () => {
|
|
460
|
+
// An object-literal replacement must NOT be mislabelled as the
|
|
461
|
+
// deferred regex form — the guard only special-cases a
|
|
462
|
+
// regex-literal pattern.
|
|
463
|
+
const result = parseExpression(`name().replace("a", {x: 1})`)
|
|
464
|
+
expect(result.kind).toBe('unsupported')
|
|
465
|
+
if (result.kind === 'unsupported') {
|
|
466
|
+
expect(result.reason).not.toContain('regex form is deferred')
|
|
467
|
+
}
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
test('.replace(/re/, repl) refuses the regex form with the deferred reason (#1448 Tier B)', () => {
|
|
471
|
+
const result = parseExpression(`name().replace(/a/g, "b")`)
|
|
472
|
+
expect(result.kind).toBe('unsupported')
|
|
473
|
+
if (result.kind === 'unsupported') {
|
|
474
|
+
expect(result.reason).toContain('regex form is deferred')
|
|
475
|
+
}
|
|
476
|
+
})
|
|
477
|
+
|
|
478
|
+
test('lowers .repeat() and .repeat(n, extra) — full arity (#1448 Tier B)', () => {
|
|
479
|
+
// `.repeat()` is `repeat(0)` → "" in JS (not a RangeError); a
|
|
480
|
+
// second+ argument is ignored. Both stay on the lowering path.
|
|
481
|
+
for (const expr of [`name().repeat()`, `name().repeat(3, 4)`]) {
|
|
482
|
+
const result = parseExpression(expr)
|
|
483
|
+
expect(result.kind).toBe('array-method')
|
|
484
|
+
if (result.kind === 'array-method') {
|
|
485
|
+
expect(result.method).toBe('repeat')
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
test('lowers .padStart() / .padEnd(t, p, extra) — full arity (#1448 Tier B)', () => {
|
|
491
|
+
// `.padStart()` is `padStart(0)` → the receiver unchanged; a
|
|
492
|
+
// third+ argument is ignored. Both stay on the lowering path.
|
|
493
|
+
for (const expr of [`name().padStart()`, `name().padEnd(5, "0", "x")`]) {
|
|
494
|
+
const result = parseExpression(expr)
|
|
495
|
+
expect(result.kind).toBe('array-method')
|
|
496
|
+
}
|
|
497
|
+
})
|
|
498
|
+
|
|
420
499
|
test('lowers .filter(({label = `untitled-${suffix}`}) => label) — template-literal default (#1531)', () => {
|
|
421
500
|
const result = parseExpression('items().filter(({label = `untitled-${suffix}`}) => label)')
|
|
422
501
|
expect(result.kind).toBe('higher-order')
|
|
@@ -1358,3 +1437,186 @@ describe('expression-parser', () => {
|
|
|
1358
1437
|
})
|
|
1359
1438
|
})
|
|
1360
1439
|
})
|
|
1440
|
+
|
|
1441
|
+
// =============================================================================
|
|
1442
|
+
// Full-arity lowering for the array / string methods (#1448)
|
|
1443
|
+
// =============================================================================
|
|
1444
|
+
//
|
|
1445
|
+
// These methods lower at their full JS arity: zero-arg defaults
|
|
1446
|
+
// (`.join()` → `,`, `.slice()` → full copy) and JS-ignored trailing
|
|
1447
|
+
// arguments (`.trim(1)`, `.at(i, extra)`, `.slice(s, e, extra)`) are all
|
|
1448
|
+
// accepted. The only forms still refused are the ones whose EXTRA
|
|
1449
|
+
// argument changes the result and isn't lowered yet — the `fromIndex` of
|
|
1450
|
+
// `.includes`/`.indexOf`/`.lastIndexOf` and the variadic `.concat(a, b)`
|
|
1451
|
+
// — because silently dropping those would make SSR differ from the
|
|
1452
|
+
// client (worse than a build error).
|
|
1453
|
+
describe('expression-parser — array-method full-arity lowering (#1448)', () => {
|
|
1454
|
+
const supported: Array<[string, string]> = [
|
|
1455
|
+
// base forms
|
|
1456
|
+
['join(sep)', 'arr.join("-")'],
|
|
1457
|
+
['includes(x)', 'arr.includes(x)'],
|
|
1458
|
+
['indexOf(x)', 'arr.indexOf(x)'],
|
|
1459
|
+
['at(i)', 'arr.at(1)'],
|
|
1460
|
+
['concat(other)', 'arr.concat(b)'],
|
|
1461
|
+
['slice(start)', 'arr.slice(1)'],
|
|
1462
|
+
['slice(start, end)', 'arr.slice(1, 2)'],
|
|
1463
|
+
['trim()', 's.trim()'],
|
|
1464
|
+
// zero-arg defaults (every one of these escaping both its arm AND
|
|
1465
|
+
// the guard is the footgun the relaxation must NOT reintroduce)
|
|
1466
|
+
['join() → default ","', 'arr.join()'],
|
|
1467
|
+
['slice() → full copy', 'arr.slice()'],
|
|
1468
|
+
['at() → at(0)', 'arr.at()'],
|
|
1469
|
+
['concat() → shallow copy', 'arr.concat()'],
|
|
1470
|
+
['reverse() base', 'arr.reverse()'],
|
|
1471
|
+
['toReversed() base', 'arr.toReversed()'],
|
|
1472
|
+
['toLowerCase() base', 's.toLowerCase()'],
|
|
1473
|
+
['toUpperCase() base', 's.toUpperCase()'],
|
|
1474
|
+
['lastIndexOf(x) base', 'arr.lastIndexOf(x)'],
|
|
1475
|
+
// JS-ignored trailing arguments
|
|
1476
|
+
['slice(s, e, extra)', 'arr.slice(1, 2, 3)'],
|
|
1477
|
+
['at(i, extra)', 'arr.at(1, 2)'],
|
|
1478
|
+
['reverse(extra)', 'arr.reverse(1)'],
|
|
1479
|
+
['toReversed(extra)', 'arr.toReversed(1)'],
|
|
1480
|
+
['toLowerCase(extra)', 's.toLowerCase("x")'],
|
|
1481
|
+
['toUpperCase(extra)', 's.toUpperCase("x")'],
|
|
1482
|
+
['trim(extra)', 's.trim(1)'],
|
|
1483
|
+
]
|
|
1484
|
+
for (const [label, expr] of supported) {
|
|
1485
|
+
test(`${label} — lowers to array-method`, () => {
|
|
1486
|
+
expect(parseExpression(expr).kind).toBe('array-method')
|
|
1487
|
+
})
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
// Still refused (the extra argument is meaningful and not yet
|
|
1491
|
+
// lowered), plus the degenerate zero-arg search forms (`includes()`
|
|
1492
|
+
// searches for `undefined` — refused rather than guessed).
|
|
1493
|
+
const refused: Array<[string, string]> = [
|
|
1494
|
+
['includes(x, fromIndex)', 'arr.includes(x, 1)'],
|
|
1495
|
+
['indexOf(x, fromIndex)', 'arr.indexOf(x, 1)'],
|
|
1496
|
+
['lastIndexOf(x, fromIndex)', 'arr.lastIndexOf(x, 1)'],
|
|
1497
|
+
['concat(a, b) variadic', 'arr.concat(a, b)'],
|
|
1498
|
+
['includes() zero-arg', 'arr.includes()'],
|
|
1499
|
+
['indexOf() zero-arg', 'arr.indexOf()'],
|
|
1500
|
+
]
|
|
1501
|
+
for (const [label, expr] of refused) {
|
|
1502
|
+
test(`${label} — refuses (meaningful extra arg, not yet lowered)`, () => {
|
|
1503
|
+
const result = parseExpression(expr)
|
|
1504
|
+
expect(result.kind).toBe('unsupported')
|
|
1505
|
+
if (result.kind === 'unsupported') {
|
|
1506
|
+
// Must NOT push `@client` (wrong remedy; doesn't work in
|
|
1507
|
+
// attribute / condition position), and must explain it's a
|
|
1508
|
+
// not-yet-lowered argument.
|
|
1509
|
+
expect(result.reason).not.toContain('@client')
|
|
1510
|
+
expect(result.reason).toContain('not yet lowered')
|
|
1511
|
+
}
|
|
1512
|
+
})
|
|
1513
|
+
}
|
|
1514
|
+
})
|
|
1515
|
+
|
|
1516
|
+
describe('expression-parser — .flat(depth?) lowering (#1448 Tier C)', () => {
|
|
1517
|
+
// Depth literals normalise into a structured `flatDepth` at parse time.
|
|
1518
|
+
const depths: Array<[string, string, number | 'infinity']> = [
|
|
1519
|
+
['.flat() → depth 1', 'arr.flat()', 1],
|
|
1520
|
+
['.flat(2) → depth 2', 'arr.flat(2)', 2],
|
|
1521
|
+
['.flat(Infinity) → "infinity"', 'arr.flat(Infinity)', 'infinity'],
|
|
1522
|
+
['.flat(0) → depth 0 (shallow copy)', 'arr.flat(0)', 0],
|
|
1523
|
+
['.flat(-1) → normalised to 0 (JS clamps)', 'arr.flat(-1)', 0],
|
|
1524
|
+
['.flat(1.9) → truncated to 1', 'arr.flat(1.9)', 1],
|
|
1525
|
+
]
|
|
1526
|
+
for (const [label, expr, expected] of depths) {
|
|
1527
|
+
test(label, () => {
|
|
1528
|
+
const result = parseExpression(expr)
|
|
1529
|
+
expect(result.kind).toBe('array-method')
|
|
1530
|
+
if (result.kind === 'array-method' && result.method === 'flat') {
|
|
1531
|
+
expect(result.flatDepth).toBe(expected)
|
|
1532
|
+
} else {
|
|
1533
|
+
throw new Error(`expected a flat array-method, got ${result.kind}`)
|
|
1534
|
+
}
|
|
1535
|
+
})
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
test('non-literal depth refuses (must be resolvable at template time)', () => {
|
|
1539
|
+
const result = parseExpression('arr.flat(n)')
|
|
1540
|
+
expect(result.kind).toBe('unsupported')
|
|
1541
|
+
if (result.kind === 'unsupported') {
|
|
1542
|
+
// Wrong remedy `@client` must not be suggested (doesn't work in
|
|
1543
|
+
// attribute / condition position).
|
|
1544
|
+
expect(result.reason).not.toContain('@client')
|
|
1545
|
+
expect(result.reason).toContain('literal')
|
|
1546
|
+
}
|
|
1547
|
+
})
|
|
1548
|
+
|
|
1549
|
+
// exprToString (diagnostics / debug output) must preserve the normalised
|
|
1550
|
+
// depth, not collapse every form to `.flat()`.
|
|
1551
|
+
test('exprToString round-trips the normalised depth', () => {
|
|
1552
|
+
expect(exprToString(parseExpression('arr.flat()'))).toBe('arr.flat()')
|
|
1553
|
+
expect(exprToString(parseExpression('arr.flat(2)'))).toBe('arr.flat(2)')
|
|
1554
|
+
expect(exprToString(parseExpression('arr.flat(Infinity)'))).toBe('arr.flat(Infinity)')
|
|
1555
|
+
expect(exprToString(parseExpression('arr.flat(0)'))).toBe('arr.flat(0)')
|
|
1556
|
+
})
|
|
1557
|
+
})
|
|
1558
|
+
|
|
1559
|
+
describe('expression-parser — .flatMap(fn) projection (#1448 Tier C)', () => {
|
|
1560
|
+
// Accepted catalogue: self, single field, and array-literal tuples of
|
|
1561
|
+
// self / field leaves.
|
|
1562
|
+
type Proj = { kind: 'self' } | { kind: 'field'; field: string } | { kind: 'tuple'; elements: unknown[] }
|
|
1563
|
+
const accepted: Array<[string, string, Proj]> = [
|
|
1564
|
+
['self (i => i)', 'arr.flatMap(i => i)', { kind: 'self' }],
|
|
1565
|
+
['field (i => i.tags)', 'arr.flatMap(i => i.tags)', { kind: 'field', field: 'tags' }],
|
|
1566
|
+
['single-return block body', 'arr.flatMap(i => { return i.tags })', { kind: 'field', field: 'tags' }],
|
|
1567
|
+
['tuple of fields', 'arr.flatMap(i => [i.a, i.b])', { kind: 'tuple', elements: [{ kind: 'field', field: 'a' }, { kind: 'field', field: 'b' }] }],
|
|
1568
|
+
['tuple self + field', 'arr.flatMap(i => [i, i.tags])', { kind: 'tuple', elements: [{ kind: 'self' }, { kind: 'field', field: 'tags' }] }],
|
|
1569
|
+
]
|
|
1570
|
+
for (const [label, expr, projection] of accepted) {
|
|
1571
|
+
test(`${label} — lowers to a flatMap array-method`, () => {
|
|
1572
|
+
const result = parseExpression(expr)
|
|
1573
|
+
expect(result.kind).toBe('array-method')
|
|
1574
|
+
if (result.kind === 'array-method' && result.method === 'flatMap') {
|
|
1575
|
+
expect(result.flatMapOp.projection).toEqual(projection)
|
|
1576
|
+
} else {
|
|
1577
|
+
throw new Error(`expected a flatMap array-method, got ${result.kind}`)
|
|
1578
|
+
}
|
|
1579
|
+
})
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
// Out of catalogue → refused (BF101 + @client hint).
|
|
1583
|
+
const refused = [
|
|
1584
|
+
['deep field access', 'arr.flatMap(i => i.a.b)'],
|
|
1585
|
+
['index/array callback params', 'arr.flatMap((i, idx) => i.tags)'],
|
|
1586
|
+
// Tuple with a non-leaf element (arithmetic / literal / deep access).
|
|
1587
|
+
['tuple with arithmetic element', 'arr.flatMap(i => [i.a, i.b + 1])'],
|
|
1588
|
+
['tuple with literal element', 'arr.flatMap(i => [i.a, "x"])'],
|
|
1589
|
+
['tuple with deep access', 'arr.flatMap(i => [i.a, i.b.c])'],
|
|
1590
|
+
['tuple with spread', 'arr.flatMap(i => [...i.a])'],
|
|
1591
|
+
// Empty tuple is a degenerate no-op — refused so emitters never
|
|
1592
|
+
// produce a zero-arg `flat_map_tuple` call.
|
|
1593
|
+
['empty tuple', 'arr.flatMap(i => [])'],
|
|
1594
|
+
// Wrong-arity forms are intercepted by the same arm (not the generic
|
|
1595
|
+
// "flatMap has no template lowering" gate) so the reason stays tailored.
|
|
1596
|
+
['2-arg flatMap(fn, thisArg)', 'arr.flatMap(i => i.tags, ctx)'],
|
|
1597
|
+
]
|
|
1598
|
+
for (const [label, expr] of refused) {
|
|
1599
|
+
test(`${label} — refuses`, () => {
|
|
1600
|
+
const result = parseExpression(expr)
|
|
1601
|
+
expect(result.kind).toBe('unsupported')
|
|
1602
|
+
if (result.kind === 'unsupported') {
|
|
1603
|
+
expect(result.reason).toContain('flatMap shape not supported')
|
|
1604
|
+
}
|
|
1605
|
+
})
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
test('exprToString / stringify round-trip the callback', () => {
|
|
1609
|
+
// Scalar projections, plus the array-literal tuple — the round-trip
|
|
1610
|
+
// relies on the callback `raw`, so a regression in raw capture would
|
|
1611
|
+
// surface here for every projection shape.
|
|
1612
|
+
for (const src of [
|
|
1613
|
+
'arr.flatMap(i => i.tags)',
|
|
1614
|
+
'arr.flatMap(t => t)',
|
|
1615
|
+
'arr.flatMap(i => [i.a, i.b])',
|
|
1616
|
+
'arr.flatMap(i => [i, i.tags])',
|
|
1617
|
+
]) {
|
|
1618
|
+
expect(exprToString(parseExpression(src))).toBe(src)
|
|
1619
|
+
expect(stringifyParsedExpr(parseExpression(src))).toBe(src)
|
|
1620
|
+
}
|
|
1621
|
+
})
|
|
1622
|
+
})
|