@zenithbuild/cli 0.6.2 → 0.6.3
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/build.js +617 -38
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -200,11 +200,31 @@ function stripStyleBlocks(source) {
|
|
|
200
200
|
* @param {string} compPath
|
|
201
201
|
* @param {string} componentSource
|
|
202
202
|
* @param {object} compIr
|
|
203
|
-
* @returns {{
|
|
203
|
+
* @returns {{
|
|
204
|
+
* map: Map<string, string>,
|
|
205
|
+
* bindings: Map<string, {
|
|
206
|
+
* compiled_expr: string | null,
|
|
207
|
+
* signal_index: number | null,
|
|
208
|
+
* signal_indices: number[],
|
|
209
|
+
* state_index: number | null,
|
|
210
|
+
* component_instance: string | null,
|
|
211
|
+
* component_binding: string | null
|
|
212
|
+
* }>,
|
|
213
|
+
* signals: Array<{ id?: number, kind?: string, state_index?: number }>,
|
|
214
|
+
* stateBindings: Array<{ key?: string, value?: string }>,
|
|
215
|
+
* ambiguous: Set<string>
|
|
216
|
+
* }}
|
|
204
217
|
*/
|
|
205
218
|
function buildComponentExpressionRewrite(compPath, componentSource, compIr, compilerOpts) {
|
|
206
|
-
const out = {
|
|
219
|
+
const out = {
|
|
220
|
+
map: new Map(),
|
|
221
|
+
bindings: new Map(),
|
|
222
|
+
signals: Array.isArray(compIr?.signals) ? compIr.signals : [],
|
|
223
|
+
stateBindings: Array.isArray(compIr?.hoisted?.state) ? compIr.hoisted.state : [],
|
|
224
|
+
ambiguous: new Set()
|
|
225
|
+
};
|
|
207
226
|
const rewrittenExpressions = Array.isArray(compIr?.expressions) ? compIr.expressions : [];
|
|
227
|
+
const rewrittenBindings = Array.isArray(compIr?.expression_bindings) ? compIr.expression_bindings : [];
|
|
208
228
|
if (rewrittenExpressions.length === 0) {
|
|
209
229
|
return out;
|
|
210
230
|
}
|
|
@@ -229,34 +249,243 @@ function buildComponentExpressionRewrite(compPath, componentSource, compIr, comp
|
|
|
229
249
|
if (typeof raw !== 'string' || typeof rewritten !== 'string') {
|
|
230
250
|
continue;
|
|
231
251
|
}
|
|
232
|
-
|
|
233
|
-
|
|
252
|
+
|
|
253
|
+
const binding = rewrittenBindings[i];
|
|
254
|
+
const normalizedBinding = binding && typeof binding === 'object'
|
|
255
|
+
? {
|
|
256
|
+
compiled_expr: typeof binding.compiled_expr === 'string' ? binding.compiled_expr : null,
|
|
257
|
+
signal_index: Number.isInteger(binding.signal_index) ? binding.signal_index : null,
|
|
258
|
+
signal_indices: Array.isArray(binding.signal_indices)
|
|
259
|
+
? binding.signal_indices.filter((value) => Number.isInteger(value))
|
|
260
|
+
: [],
|
|
261
|
+
state_index: Number.isInteger(binding.state_index) ? binding.state_index : null,
|
|
262
|
+
component_instance: typeof binding.component_instance === 'string' ? binding.component_instance : null,
|
|
263
|
+
component_binding: typeof binding.component_binding === 'string' ? binding.component_binding : null
|
|
264
|
+
}
|
|
265
|
+
: null;
|
|
266
|
+
|
|
267
|
+
if (!out.ambiguous.has(raw) && normalizedBinding) {
|
|
268
|
+
const existingBinding = out.bindings.get(raw);
|
|
269
|
+
if (existingBinding) {
|
|
270
|
+
if (JSON.stringify(existingBinding) !== JSON.stringify(normalizedBinding)) {
|
|
271
|
+
out.bindings.delete(raw);
|
|
272
|
+
out.map.delete(raw);
|
|
273
|
+
out.ambiguous.add(raw);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
} else {
|
|
277
|
+
out.bindings.set(raw, normalizedBinding);
|
|
278
|
+
}
|
|
234
279
|
}
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
out.map.
|
|
238
|
-
|
|
280
|
+
|
|
281
|
+
if (raw !== rewritten) {
|
|
282
|
+
const existing = out.map.get(raw);
|
|
283
|
+
if (existing && existing !== rewritten) {
|
|
284
|
+
out.bindings.delete(raw);
|
|
285
|
+
out.map.delete(raw);
|
|
286
|
+
out.ambiguous.add(raw);
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (!out.ambiguous.has(raw)) {
|
|
290
|
+
out.map.set(raw, rewritten);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return out;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function remapCompiledExpressionSignals(compiledExpr, componentSignals, componentStateBindings, pageSignalIndexByStateKey) {
|
|
299
|
+
if (typeof compiledExpr !== 'string' || compiledExpr.length === 0) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return compiledExpr.replace(/signalMap\.get\((\d+)\)/g, (full, rawIndex) => {
|
|
304
|
+
const localIndex = Number.parseInt(rawIndex, 10);
|
|
305
|
+
if (!Number.isInteger(localIndex)) {
|
|
306
|
+
return full;
|
|
307
|
+
}
|
|
308
|
+
const signal = componentSignals[localIndex];
|
|
309
|
+
if (!signal || !Number.isInteger(signal.state_index)) {
|
|
310
|
+
return full;
|
|
311
|
+
}
|
|
312
|
+
const stateKey = componentStateBindings[signal.state_index]?.key;
|
|
313
|
+
if (typeof stateKey !== 'string' || stateKey.length === 0) {
|
|
314
|
+
return full;
|
|
315
|
+
}
|
|
316
|
+
const pageIndex = pageSignalIndexByStateKey.get(stateKey);
|
|
317
|
+
if (!Number.isInteger(pageIndex)) {
|
|
318
|
+
return full;
|
|
319
|
+
}
|
|
320
|
+
return `signalMap.get(${pageIndex})`;
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function resolveRewrittenBindingMetadata(pageIr, componentRewrite, binding) {
|
|
325
|
+
if (!binding || typeof binding !== 'object') {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const pageStateBindings = Array.isArray(pageIr?.hoisted?.state) ? pageIr.hoisted.state : [];
|
|
330
|
+
const pageSignals = Array.isArray(pageIr?.hoisted?.signals) ? pageIr.hoisted.signals : [];
|
|
331
|
+
const pageStateIndexByKey = new Map();
|
|
332
|
+
const pageSignalIndexByStateKey = new Map();
|
|
333
|
+
|
|
334
|
+
for (let index = 0; index < pageStateBindings.length; index++) {
|
|
335
|
+
const key = pageStateBindings[index]?.key;
|
|
336
|
+
if (typeof key === 'string' && key.length > 0 && !pageStateIndexByKey.has(key)) {
|
|
337
|
+
pageStateIndexByKey.set(key, index);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
for (let index = 0; index < pageSignals.length; index++) {
|
|
342
|
+
const stateIndex = pageSignals[index]?.state_index;
|
|
343
|
+
if (!Number.isInteger(stateIndex)) {
|
|
239
344
|
continue;
|
|
240
345
|
}
|
|
241
|
-
|
|
242
|
-
|
|
346
|
+
const stateKey = pageStateBindings[stateIndex]?.key;
|
|
347
|
+
if (typeof stateKey === 'string' && stateKey.length > 0 && !pageSignalIndexByStateKey.has(stateKey)) {
|
|
348
|
+
pageSignalIndexByStateKey.set(stateKey, index);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const componentSignals = Array.isArray(componentRewrite?.signals) ? componentRewrite.signals : [];
|
|
353
|
+
const componentStateBindings = Array.isArray(componentRewrite?.stateBindings) ? componentRewrite.stateBindings : [];
|
|
354
|
+
|
|
355
|
+
let signalIndices = Array.isArray(binding.signal_indices)
|
|
356
|
+
? [...new Set(
|
|
357
|
+
binding.signal_indices
|
|
358
|
+
.map((signalIndex) => {
|
|
359
|
+
if (!Number.isInteger(signalIndex)) {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
const signal = componentSignals[signalIndex];
|
|
363
|
+
if (!signal || !Number.isInteger(signal.state_index)) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
const stateKey = componentStateBindings[signal.state_index]?.key;
|
|
367
|
+
if (typeof stateKey !== 'string' || stateKey.length === 0) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
const pageIndex = pageSignalIndexByStateKey.get(stateKey);
|
|
371
|
+
return Number.isInteger(pageIndex) ? pageIndex : null;
|
|
372
|
+
})
|
|
373
|
+
.filter((value) => Number.isInteger(value))
|
|
374
|
+
)].sort((a, b) => a - b)
|
|
375
|
+
: [];
|
|
376
|
+
|
|
377
|
+
let signalIndex = null;
|
|
378
|
+
if (Number.isInteger(binding.signal_index)) {
|
|
379
|
+
const signal = componentSignals[binding.signal_index];
|
|
380
|
+
const stateKey = signal && Number.isInteger(signal.state_index)
|
|
381
|
+
? componentStateBindings[signal.state_index]?.key
|
|
382
|
+
: null;
|
|
383
|
+
const pageIndex = typeof stateKey === 'string' ? pageSignalIndexByStateKey.get(stateKey) : null;
|
|
384
|
+
signalIndex = Number.isInteger(pageIndex) ? pageIndex : null;
|
|
385
|
+
}
|
|
386
|
+
if (signalIndex === null && signalIndices.length === 1) {
|
|
387
|
+
signalIndex = signalIndices[0];
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
let stateIndex = null;
|
|
391
|
+
if (Number.isInteger(binding.state_index)) {
|
|
392
|
+
const stateKey = componentStateBindings[binding.state_index]?.key;
|
|
393
|
+
const pageIndex = typeof stateKey === 'string' ? pageStateIndexByKey.get(stateKey) : null;
|
|
394
|
+
stateIndex = Number.isInteger(pageIndex) ? pageIndex : null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (Number.isInteger(stateIndex)) {
|
|
398
|
+
const fallbackSignalIndices = pageSignals
|
|
399
|
+
.map((signal, index) => signal?.state_index === stateIndex ? index : null)
|
|
400
|
+
.filter((value) => Number.isInteger(value));
|
|
401
|
+
const signalIndicesMatchState = signalIndices.every(
|
|
402
|
+
(index) => pageSignals[index]?.state_index === stateIndex
|
|
403
|
+
);
|
|
404
|
+
if ((!signalIndicesMatchState || signalIndices.length === 0) && fallbackSignalIndices.length > 0) {
|
|
405
|
+
signalIndices = fallbackSignalIndices;
|
|
406
|
+
}
|
|
407
|
+
if (
|
|
408
|
+
(signalIndex === null || pageSignals[signalIndex]?.state_index !== stateIndex) &&
|
|
409
|
+
fallbackSignalIndices.length === 1
|
|
410
|
+
) {
|
|
411
|
+
signalIndex = fallbackSignalIndices[0];
|
|
243
412
|
}
|
|
244
413
|
}
|
|
245
414
|
|
|
246
|
-
|
|
415
|
+
let compiledExpr = remapCompiledExpressionSignals(
|
|
416
|
+
binding.compiled_expr,
|
|
417
|
+
componentSignals,
|
|
418
|
+
componentStateBindings,
|
|
419
|
+
pageSignalIndexByStateKey
|
|
420
|
+
);
|
|
421
|
+
if (
|
|
422
|
+
typeof compiledExpr === 'string' &&
|
|
423
|
+
signalIndices.length === 1 &&
|
|
424
|
+
Array.isArray(binding.signal_indices) &&
|
|
425
|
+
binding.signal_indices.length <= 1
|
|
426
|
+
) {
|
|
427
|
+
compiledExpr = compiledExpr.replace(/signalMap\.get\(\d+\)/g, `signalMap.get(${signalIndices[0]})`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return {
|
|
431
|
+
compiled_expr: compiledExpr,
|
|
432
|
+
signal_index: signalIndex,
|
|
433
|
+
signal_indices: signalIndices,
|
|
434
|
+
state_index: stateIndex,
|
|
435
|
+
component_instance: typeof binding.component_instance === 'string' ? binding.component_instance : null,
|
|
436
|
+
component_binding: typeof binding.component_binding === 'string' ? binding.component_binding : null
|
|
437
|
+
};
|
|
247
438
|
}
|
|
248
439
|
|
|
249
440
|
/**
|
|
250
441
|
* Merge a per-component rewrite table into the page-level rewrite table.
|
|
251
442
|
*
|
|
252
443
|
* @param {Map<string, string>} pageMap
|
|
444
|
+
* @param {Map<string, {
|
|
445
|
+
* compiled_expr: string | null,
|
|
446
|
+
* signal_index: number | null,
|
|
447
|
+
* signal_indices: number[],
|
|
448
|
+
* state_index: number | null,
|
|
449
|
+
* component_instance: string | null,
|
|
450
|
+
* component_binding: string | null
|
|
451
|
+
* }>} pageBindingMap
|
|
253
452
|
* @param {Set<string>} pageAmbiguous
|
|
254
|
-
* @param {{
|
|
453
|
+
* @param {{
|
|
454
|
+
* map: Map<string, string>,
|
|
455
|
+
* bindings: Map<string, {
|
|
456
|
+
* compiled_expr: string | null,
|
|
457
|
+
* signal_index: number | null,
|
|
458
|
+
* signal_indices: number[],
|
|
459
|
+
* state_index: number | null,
|
|
460
|
+
* component_instance: string | null,
|
|
461
|
+
* component_binding: string | null
|
|
462
|
+
* }>,
|
|
463
|
+
* signals: Array<{ id?: number, kind?: string, state_index?: number }>,
|
|
464
|
+
* stateBindings: Array<{ key?: string, value?: string }>,
|
|
465
|
+
* ambiguous: Set<string>
|
|
466
|
+
* }} componentRewrite
|
|
467
|
+
* @param {object} pageIr
|
|
255
468
|
*/
|
|
256
|
-
function mergeExpressionRewriteMaps(pageMap, pageAmbiguous, componentRewrite) {
|
|
469
|
+
function mergeExpressionRewriteMaps(pageMap, pageBindingMap, pageAmbiguous, componentRewrite, pageIr) {
|
|
257
470
|
for (const raw of componentRewrite.ambiguous) {
|
|
258
471
|
pageAmbiguous.add(raw);
|
|
259
472
|
pageMap.delete(raw);
|
|
473
|
+
pageBindingMap.delete(raw);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
for (const [raw, binding] of componentRewrite.bindings.entries()) {
|
|
477
|
+
if (pageAmbiguous.has(raw)) {
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
const resolved = resolveRewrittenBindingMetadata(pageIr, componentRewrite, binding);
|
|
481
|
+
const existing = pageBindingMap.get(raw);
|
|
482
|
+
if (existing && JSON.stringify(existing) !== JSON.stringify(resolved)) {
|
|
483
|
+
pageAmbiguous.add(raw);
|
|
484
|
+
pageMap.delete(raw);
|
|
485
|
+
pageBindingMap.delete(raw);
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
pageBindingMap.set(raw, resolved);
|
|
260
489
|
}
|
|
261
490
|
|
|
262
491
|
for (const [raw, rewritten] of componentRewrite.map.entries()) {
|
|
@@ -267,6 +496,7 @@ function mergeExpressionRewriteMaps(pageMap, pageAmbiguous, componentRewrite) {
|
|
|
267
496
|
if (existing && existing !== rewritten) {
|
|
268
497
|
pageAmbiguous.add(raw);
|
|
269
498
|
pageMap.delete(raw);
|
|
499
|
+
pageBindingMap.delete(raw);
|
|
270
500
|
continue;
|
|
271
501
|
}
|
|
272
502
|
pageMap.set(raw, rewritten);
|
|
@@ -329,9 +559,17 @@ function rewriteRefBindingIdentifiers(pageIr, preferredKeys = null) {
|
|
|
329
559
|
*
|
|
330
560
|
* @param {object} pageIr
|
|
331
561
|
* @param {Map<string, string>} expressionMap
|
|
562
|
+
* @param {Map<string, {
|
|
563
|
+
* compiled_expr: string | null,
|
|
564
|
+
* signal_index: number | null,
|
|
565
|
+
* signal_indices: number[],
|
|
566
|
+
* state_index: number | null,
|
|
567
|
+
* component_instance: string | null,
|
|
568
|
+
* component_binding: string | null
|
|
569
|
+
* }>} bindingMap
|
|
332
570
|
* @param {Set<string>} ambiguous
|
|
333
571
|
*/
|
|
334
|
-
function applyExpressionRewrites(pageIr, expressionMap, ambiguous) {
|
|
572
|
+
function applyExpressionRewrites(pageIr, expressionMap, bindingMap, ambiguous) {
|
|
335
573
|
if (!Array.isArray(pageIr?.expressions) || pageIr.expressions.length === 0) {
|
|
336
574
|
return;
|
|
337
575
|
}
|
|
@@ -345,21 +583,109 @@ function applyExpressionRewrites(pageIr, expressionMap, ambiguous) {
|
|
|
345
583
|
if (ambiguous.has(current)) {
|
|
346
584
|
continue;
|
|
347
585
|
}
|
|
586
|
+
|
|
348
587
|
const rewritten = expressionMap.get(current);
|
|
349
|
-
|
|
588
|
+
const rewrittenBinding = bindingMap.get(current);
|
|
589
|
+
if (rewritten && rewritten !== current) {
|
|
590
|
+
pageIr.expressions[index] = rewritten;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (!bindings[index] || typeof bindings[index] !== 'object') {
|
|
350
594
|
continue;
|
|
351
595
|
}
|
|
352
|
-
|
|
596
|
+
|
|
597
|
+
if (rewritten && rewritten !== current && bindings[index].literal === current) {
|
|
598
|
+
bindings[index].literal = rewritten;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (rewrittenBinding) {
|
|
602
|
+
bindings[index].compiled_expr = rewrittenBinding.compiled_expr;
|
|
603
|
+
bindings[index].signal_index = rewrittenBinding.signal_index;
|
|
604
|
+
bindings[index].signal_indices = rewrittenBinding.signal_indices;
|
|
605
|
+
bindings[index].state_index = rewrittenBinding.state_index;
|
|
606
|
+
bindings[index].component_instance = rewrittenBinding.component_instance;
|
|
607
|
+
bindings[index].component_binding = rewrittenBinding.component_binding;
|
|
608
|
+
} else if (rewritten && rewritten !== current && bindings[index].compiled_expr === current) {
|
|
609
|
+
bindings[index].compiled_expr = rewritten;
|
|
610
|
+
}
|
|
611
|
+
|
|
353
612
|
if (
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
bindings[index].literal === current
|
|
613
|
+
!rewrittenBinding &&
|
|
614
|
+
(!rewritten || rewritten === current) &&
|
|
615
|
+
bindings[index].literal === current &&
|
|
616
|
+
bindings[index].compiled_expr === current
|
|
357
617
|
) {
|
|
358
|
-
bindings[index].
|
|
359
|
-
|
|
360
|
-
|
|
618
|
+
bindings[index].compiled_expr = current;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
function normalizeExpressionBindingDependencies(pageIr) {
|
|
624
|
+
if (!Array.isArray(pageIr?.expression_bindings) || pageIr.expression_bindings.length === 0) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const signals = Array.isArray(pageIr.signals) ? pageIr.signals : [];
|
|
629
|
+
const dependencyRe = /signalMap\.get\((\d+)\)/g;
|
|
630
|
+
|
|
631
|
+
for (const binding of pageIr.expression_bindings) {
|
|
632
|
+
if (!binding || typeof binding !== 'object' || typeof binding.compiled_expr !== 'string') {
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
const indices = [];
|
|
637
|
+
dependencyRe.lastIndex = 0;
|
|
638
|
+
let match;
|
|
639
|
+
while ((match = dependencyRe.exec(binding.compiled_expr)) !== null) {
|
|
640
|
+
const index = Number.parseInt(match[1], 10);
|
|
641
|
+
if (Number.isInteger(index)) {
|
|
642
|
+
indices.push(index);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (indices.length === 0) {
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
let signalIndices = [...new Set(indices)].sort((a, b) => a - b);
|
|
651
|
+
if (Number.isInteger(binding.state_index)) {
|
|
652
|
+
const owningSignalIndices = signals
|
|
653
|
+
.map((signal, index) => signal?.state_index === binding.state_index ? index : null)
|
|
654
|
+
.filter((value) => Number.isInteger(value));
|
|
655
|
+
const extractedMatchState =
|
|
656
|
+
signalIndices.length > 0 &&
|
|
657
|
+
signalIndices.every((index) => signals[index]?.state_index === binding.state_index);
|
|
658
|
+
if (owningSignalIndices.length > 0 && !extractedMatchState) {
|
|
659
|
+
signalIndices = owningSignalIndices;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (
|
|
664
|
+
!Array.isArray(binding.signal_indices) ||
|
|
665
|
+
binding.signal_indices.length === 0 ||
|
|
666
|
+
binding.signal_indices.some((index) => signals[index]?.state_index !== binding.state_index)
|
|
667
|
+
) {
|
|
668
|
+
binding.signal_indices = signalIndices;
|
|
669
|
+
}
|
|
670
|
+
if (
|
|
671
|
+
(!Number.isInteger(binding.signal_index) ||
|
|
672
|
+
signals[binding.signal_index]?.state_index !== binding.state_index) &&
|
|
673
|
+
signalIndices.length === 1
|
|
674
|
+
) {
|
|
675
|
+
binding.signal_index = signalIndices[0];
|
|
676
|
+
}
|
|
677
|
+
if (!Number.isInteger(binding.state_index) && Number.isInteger(binding.signal_index)) {
|
|
678
|
+
const stateIndex = signals[binding.signal_index]?.state_index;
|
|
679
|
+
if (Number.isInteger(stateIndex)) {
|
|
680
|
+
binding.state_index = stateIndex;
|
|
361
681
|
}
|
|
362
682
|
}
|
|
683
|
+
if (signalIndices.length === 1) {
|
|
684
|
+
binding.compiled_expr = binding.compiled_expr.replace(
|
|
685
|
+
/signalMap\.get\(\d+\)/g,
|
|
686
|
+
`signalMap.get(${signalIndices[0]})`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
363
689
|
}
|
|
364
690
|
}
|
|
365
691
|
|
|
@@ -798,9 +1124,10 @@ const OPEN_COMPONENT_TAG_RE = /<([A-Z][a-zA-Z0-9]*)(\s[^<>]*?)?\s*(\/?)>/g;
|
|
|
798
1124
|
*
|
|
799
1125
|
* @param {string} source
|
|
800
1126
|
* @param {Map<string, string>} registry
|
|
801
|
-
* @
|
|
1127
|
+
* @param {string | null} ownerPath
|
|
1128
|
+
* @returns {Map<string, Array<{ attrs: string, ownerPath: string | null }>>}
|
|
802
1129
|
*/
|
|
803
|
-
function collectComponentUsageAttrs(source, registry) {
|
|
1130
|
+
function collectComponentUsageAttrs(source, registry, ownerPath = null) {
|
|
804
1131
|
const out = new Map();
|
|
805
1132
|
OPEN_COMPONENT_TAG_RE.lastIndex = 0;
|
|
806
1133
|
let match;
|
|
@@ -813,8 +1140,44 @@ function collectComponentUsageAttrs(source, registry) {
|
|
|
813
1140
|
if (!out.has(name)) {
|
|
814
1141
|
out.set(name, []);
|
|
815
1142
|
}
|
|
816
|
-
out.get(name).push(attrs);
|
|
1143
|
+
out.get(name).push({ attrs, ownerPath });
|
|
1144
|
+
}
|
|
1145
|
+
return out;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/**
|
|
1149
|
+
* Collect component usage attrs recursively so nested component callsites
|
|
1150
|
+
* receive deterministic props preludes during page-hoist merging.
|
|
1151
|
+
*
|
|
1152
|
+
* Current Zenith architecture still resolves one attrs set per component type.
|
|
1153
|
+
* This helper preserves that model while ensuring nested usages are not lost.
|
|
1154
|
+
*
|
|
1155
|
+
* @param {string} source
|
|
1156
|
+
* @param {Map<string, string>} registry
|
|
1157
|
+
* @param {string | null} ownerPath
|
|
1158
|
+
* @param {Set<string>} visitedFiles
|
|
1159
|
+
* @param {Map<string, Array<{ attrs: string, ownerPath: string | null }>>} out
|
|
1160
|
+
* @returns {Map<string, Array<{ attrs: string, ownerPath: string | null }>>}
|
|
1161
|
+
*/
|
|
1162
|
+
function collectRecursiveComponentUsageAttrs(source, registry, ownerPath = null, visitedFiles = new Set(), out = new Map()) {
|
|
1163
|
+
const local = collectComponentUsageAttrs(source, registry, ownerPath);
|
|
1164
|
+
for (const [name, attrsList] of local.entries()) {
|
|
1165
|
+
if (!out.has(name)) {
|
|
1166
|
+
out.set(name, []);
|
|
1167
|
+
}
|
|
1168
|
+
out.get(name).push(...attrsList);
|
|
817
1169
|
}
|
|
1170
|
+
|
|
1171
|
+
for (const name of local.keys()) {
|
|
1172
|
+
const compPath = registry.get(name);
|
|
1173
|
+
if (!compPath || visitedFiles.has(compPath)) {
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
visitedFiles.add(compPath);
|
|
1177
|
+
const componentSource = readFileSync(compPath, 'utf8');
|
|
1178
|
+
collectRecursiveComponentUsageAttrs(componentSource, registry, compPath, visitedFiles, out);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
818
1181
|
return out;
|
|
819
1182
|
}
|
|
820
1183
|
|
|
@@ -828,7 +1191,16 @@ function collectComponentUsageAttrs(source, registry) {
|
|
|
828
1191
|
* @param {object} compIr — the component's compiled IR
|
|
829
1192
|
* @param {string} compPath — component file path
|
|
830
1193
|
* @param {string} pageFile — page file path
|
|
831
|
-
* @param {{
|
|
1194
|
+
* @param {{
|
|
1195
|
+
* includeCode: boolean,
|
|
1196
|
+
* cssImportsOnly: boolean,
|
|
1197
|
+
* documentMode?: boolean,
|
|
1198
|
+
* componentAttrs?: string,
|
|
1199
|
+
* componentAttrsRewrite?: {
|
|
1200
|
+
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
1201
|
+
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
1202
|
+
* } | null
|
|
1203
|
+
* }} options
|
|
832
1204
|
* @param {Set<string>} seenStaticImports
|
|
833
1205
|
*/
|
|
834
1206
|
function mergeComponentIr(pageIr, compIr, compPath, pageFile, options, seenStaticImports, knownRefKeys = null) {
|
|
@@ -920,6 +1292,41 @@ function mergeComponentIr(pageIr, compIr, compPath, pageFile, options, seenStati
|
|
|
920
1292
|
}
|
|
921
1293
|
}
|
|
922
1294
|
|
|
1295
|
+
if (options.includeCode && Array.isArray(compIr.signals)) {
|
|
1296
|
+
pageIr.signals = Array.isArray(pageIr.signals) ? pageIr.signals : [];
|
|
1297
|
+
const existingSignalStateKeys = new Set(
|
|
1298
|
+
pageIr.signals
|
|
1299
|
+
.map((signal) => {
|
|
1300
|
+
const stateIndex = signal?.state_index;
|
|
1301
|
+
return Number.isInteger(stateIndex) ? pageIr.hoisted.state?.[stateIndex]?.key : null;
|
|
1302
|
+
})
|
|
1303
|
+
.filter(Boolean)
|
|
1304
|
+
);
|
|
1305
|
+
|
|
1306
|
+
for (const signal of compIr.signals) {
|
|
1307
|
+
if (!signal || !Number.isInteger(signal.state_index)) {
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1310
|
+
const stateKey = compIr.hoisted?.state?.[signal.state_index]?.key;
|
|
1311
|
+
if (typeof stateKey !== 'string' || stateKey.length === 0) {
|
|
1312
|
+
continue;
|
|
1313
|
+
}
|
|
1314
|
+
const pageStateIndex = pageIr.hoisted.state.findIndex((entry) => entry?.key === stateKey);
|
|
1315
|
+
if (!Number.isInteger(pageStateIndex) || pageStateIndex < 0) {
|
|
1316
|
+
continue;
|
|
1317
|
+
}
|
|
1318
|
+
if (existingSignalStateKeys.has(stateKey)) {
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
existingSignalStateKeys.add(stateKey);
|
|
1322
|
+
pageIr.signals.push({
|
|
1323
|
+
id: pageIr.signals.length,
|
|
1324
|
+
kind: typeof signal.kind === 'string' && signal.kind.length > 0 ? signal.kind : 'signal',
|
|
1325
|
+
state_index: pageStateIndex
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
|
|
923
1330
|
// Merge hoisted code blocks (rebased to the page file path)
|
|
924
1331
|
if (options.includeCode && compIr.hoisted?.code?.length) {
|
|
925
1332
|
for (const block of compIr.hoisted.code) {
|
|
@@ -927,7 +1334,11 @@ function mergeComponentIr(pageIr, compIr, compPath, pageFile, options, seenStati
|
|
|
927
1334
|
const filteredImports = options.cssImportsOnly
|
|
928
1335
|
? stripNonCssStaticImportsInSource(rebased)
|
|
929
1336
|
: rebased;
|
|
930
|
-
const withPropsPrelude = injectPropsPrelude(
|
|
1337
|
+
const withPropsPrelude = injectPropsPrelude(
|
|
1338
|
+
filteredImports,
|
|
1339
|
+
options.componentAttrs || '',
|
|
1340
|
+
options.componentAttrsRewrite || null
|
|
1341
|
+
);
|
|
931
1342
|
const transpiled = transpileTypeScriptToJs(withPropsPrelude, compPath);
|
|
932
1343
|
const deduped = dedupeStaticImportsInSource(transpiled, seenStaticImports);
|
|
933
1344
|
const deferred = deferComponentRuntimeBlock(deduped);
|
|
@@ -1228,11 +1639,123 @@ function renderObjectKey(key) {
|
|
|
1228
1639
|
return JSON.stringify(key);
|
|
1229
1640
|
}
|
|
1230
1641
|
|
|
1642
|
+
/**
|
|
1643
|
+
* @param {string} value
|
|
1644
|
+
* @returns {string | null}
|
|
1645
|
+
*/
|
|
1646
|
+
function deriveScopedIdentifierAlias(value) {
|
|
1647
|
+
const ident = String(value || '').trim();
|
|
1648
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(ident)) {
|
|
1649
|
+
return null;
|
|
1650
|
+
}
|
|
1651
|
+
const parts = ident.split('_').filter(Boolean);
|
|
1652
|
+
const candidate = parts.length > 1 ? parts[parts.length - 1] : ident;
|
|
1653
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(candidate) ? candidate : ident;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/**
|
|
1657
|
+
* @param {Map<string, string>} map
|
|
1658
|
+
* @param {Set<string>} ambiguous
|
|
1659
|
+
* @param {string | null} raw
|
|
1660
|
+
* @param {string | null} rewritten
|
|
1661
|
+
*/
|
|
1662
|
+
function recordScopedIdentifierRewrite(map, ambiguous, raw, rewritten) {
|
|
1663
|
+
if (typeof raw !== 'string' || raw.length === 0 || typeof rewritten !== 'string' || rewritten.length === 0) {
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
const existing = map.get(raw);
|
|
1667
|
+
if (existing && existing !== rewritten) {
|
|
1668
|
+
map.delete(raw);
|
|
1669
|
+
ambiguous.add(raw);
|
|
1670
|
+
return;
|
|
1671
|
+
}
|
|
1672
|
+
if (!ambiguous.has(raw)) {
|
|
1673
|
+
map.set(raw, rewritten);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
/**
|
|
1678
|
+
* @param {object | null | undefined} ir
|
|
1679
|
+
* @returns {{ map: Map<string, string>, ambiguous: Set<string> }}
|
|
1680
|
+
*/
|
|
1681
|
+
function buildScopedIdentifierRewrite(ir) {
|
|
1682
|
+
const out = { map: new Map(), ambiguous: new Set() };
|
|
1683
|
+
if (!ir || typeof ir !== 'object') {
|
|
1684
|
+
return out;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
const stateBindings = Array.isArray(ir?.hoisted?.state) ? ir.hoisted.state : [];
|
|
1688
|
+
for (const stateEntry of stateBindings) {
|
|
1689
|
+
const key = typeof stateEntry?.key === 'string' ? stateEntry.key : null;
|
|
1690
|
+
recordScopedIdentifierRewrite(out.map, out.ambiguous, deriveScopedIdentifierAlias(key), key);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
const functionBindings = Array.isArray(ir?.hoisted?.functions) ? ir.hoisted.functions : [];
|
|
1694
|
+
for (const fnName of functionBindings) {
|
|
1695
|
+
if (typeof fnName !== 'string') {
|
|
1696
|
+
continue;
|
|
1697
|
+
}
|
|
1698
|
+
recordScopedIdentifierRewrite(out.map, out.ambiguous, deriveScopedIdentifierAlias(fnName), fnName);
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
return out;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* @param {string} expr
|
|
1706
|
+
* @param {{
|
|
1707
|
+
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
1708
|
+
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
1709
|
+
* } | null} rewriteContext
|
|
1710
|
+
* @returns {string}
|
|
1711
|
+
*/
|
|
1712
|
+
function rewritePropsExpression(expr, rewriteContext = null) {
|
|
1713
|
+
const trimmed = String(expr || '').trim();
|
|
1714
|
+
if (!trimmed) {
|
|
1715
|
+
return trimmed;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
const expressionMap = rewriteContext?.expressionRewrite?.map;
|
|
1719
|
+
const expressionAmbiguous = rewriteContext?.expressionRewrite?.ambiguous;
|
|
1720
|
+
if (
|
|
1721
|
+
expressionMap instanceof Map &&
|
|
1722
|
+
!(expressionAmbiguous instanceof Set && expressionAmbiguous.has(trimmed))
|
|
1723
|
+
) {
|
|
1724
|
+
const exact = expressionMap.get(trimmed);
|
|
1725
|
+
if (typeof exact === 'string' && exact.length > 0) {
|
|
1726
|
+
return exact;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
const scopeMap = rewriteContext?.scopeRewrite?.map;
|
|
1731
|
+
const scopeAmbiguous = rewriteContext?.scopeRewrite?.ambiguous;
|
|
1732
|
+
const rootMatch = trimmed.match(/^([A-Za-z_$][A-Za-z0-9_$]*)([\s\S]*)$/);
|
|
1733
|
+
if (!rootMatch || !(scopeMap instanceof Map)) {
|
|
1734
|
+
return trimmed;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
const root = rootMatch[1];
|
|
1738
|
+
if (scopeAmbiguous instanceof Set && scopeAmbiguous.has(root)) {
|
|
1739
|
+
return trimmed;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
const rewrittenRoot = scopeMap.get(root);
|
|
1743
|
+
if (typeof rewrittenRoot !== 'string' || rewrittenRoot.length === 0 || rewrittenRoot === root) {
|
|
1744
|
+
return trimmed;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
return `${rewrittenRoot}${rootMatch[2]}`;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1231
1750
|
/**
|
|
1232
1751
|
* @param {string} attrs
|
|
1752
|
+
* @param {{
|
|
1753
|
+
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
1754
|
+
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
1755
|
+
* } | null} rewriteContext
|
|
1233
1756
|
* @returns {string}
|
|
1234
1757
|
*/
|
|
1235
|
-
function renderPropsLiteralFromAttrs(attrs) {
|
|
1758
|
+
function renderPropsLiteralFromAttrs(attrs, rewriteContext = null) {
|
|
1236
1759
|
const src = String(attrs || '').trim();
|
|
1237
1760
|
if (!src) {
|
|
1238
1761
|
return '{}';
|
|
@@ -1257,7 +1780,7 @@ function renderPropsLiteralFromAttrs(attrs) {
|
|
|
1257
1780
|
valueCode = JSON.stringify(singleQuoted);
|
|
1258
1781
|
} else if (expressionValue !== undefined) {
|
|
1259
1782
|
const trimmed = String(expressionValue).trim();
|
|
1260
|
-
valueCode = trimmed.length > 0 ? trimmed : 'undefined';
|
|
1783
|
+
valueCode = trimmed.length > 0 ? rewritePropsExpression(trimmed, rewriteContext) : 'undefined';
|
|
1261
1784
|
}
|
|
1262
1785
|
|
|
1263
1786
|
entries.push(`${renderObjectKey(rawName)}: ${valueCode}`);
|
|
@@ -1273,9 +1796,13 @@ function renderPropsLiteralFromAttrs(attrs) {
|
|
|
1273
1796
|
/**
|
|
1274
1797
|
* @param {string} source
|
|
1275
1798
|
* @param {string} attrs
|
|
1799
|
+
* @param {{
|
|
1800
|
+
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
1801
|
+
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
1802
|
+
* } | null} rewriteContext
|
|
1276
1803
|
* @returns {string}
|
|
1277
1804
|
*/
|
|
1278
|
-
function injectPropsPrelude(source, attrs) {
|
|
1805
|
+
function injectPropsPrelude(source, attrs, rewriteContext = null) {
|
|
1279
1806
|
if (typeof source !== 'string' || source.trim().length === 0) {
|
|
1280
1807
|
return source;
|
|
1281
1808
|
}
|
|
@@ -1286,7 +1813,7 @@ function injectPropsPrelude(source, attrs) {
|
|
|
1286
1813
|
return source;
|
|
1287
1814
|
}
|
|
1288
1815
|
|
|
1289
|
-
const propsLiteral = renderPropsLiteralFromAttrs(attrs);
|
|
1816
|
+
const propsLiteral = renderPropsLiteralFromAttrs(attrs, rewriteContext);
|
|
1290
1817
|
return `var props = ${propsLiteral};\n${source}`;
|
|
1291
1818
|
}
|
|
1292
1819
|
|
|
@@ -1488,7 +2015,7 @@ export async function build(options) {
|
|
|
1488
2015
|
for (const entry of manifest) {
|
|
1489
2016
|
const sourceFile = join(pagesDir, entry.file);
|
|
1490
2017
|
const rawSource = readFileSync(sourceFile, 'utf8');
|
|
1491
|
-
const componentUsageAttrs =
|
|
2018
|
+
const componentUsageAttrs = collectRecursiveComponentUsageAttrs(rawSource, registry, sourceFile);
|
|
1492
2019
|
|
|
1493
2020
|
const baseName = sourceFile.slice(0, -extname(sourceFile).length);
|
|
1494
2021
|
let adjacentGuard = null;
|
|
@@ -1541,6 +2068,7 @@ export async function build(options) {
|
|
|
1541
2068
|
// Ensure IR has required array fields for merging
|
|
1542
2069
|
pageIr.components_scripts = pageIr.components_scripts || {};
|
|
1543
2070
|
pageIr.component_instances = pageIr.component_instances || [];
|
|
2071
|
+
pageIr.signals = Array.isArray(pageIr.signals) ? pageIr.signals : [];
|
|
1544
2072
|
pageIr.hoisted = pageIr.hoisted || { imports: [], declarations: [], functions: [], signals: [], state: [], code: [] };
|
|
1545
2073
|
pageIr.hoisted.imports = pageIr.hoisted.imports || [];
|
|
1546
2074
|
pageIr.hoisted.declarations = pageIr.hoisted.declarations || [];
|
|
@@ -1550,8 +2078,12 @@ export async function build(options) {
|
|
|
1550
2078
|
pageIr.hoisted.code = pageIr.hoisted.code || [];
|
|
1551
2079
|
const seenStaticImports = new Set();
|
|
1552
2080
|
const pageExpressionRewriteMap = new Map();
|
|
2081
|
+
const pageExpressionBindingMap = new Map();
|
|
1553
2082
|
const pageAmbiguousExpressionMap = new Set();
|
|
1554
2083
|
const knownRefKeys = new Set();
|
|
2084
|
+
const pageScopeRewrite = buildScopedIdentifierRewrite(pageIr);
|
|
2085
|
+
const pageSelfExpressionRewrite = buildComponentExpressionRewrite(sourceFile, compileSource, pageIr, compilerOpts);
|
|
2086
|
+
const componentScopeRewriteCache = new Map();
|
|
1555
2087
|
|
|
1556
2088
|
// 2c. Compile each used component separately for its script IR
|
|
1557
2089
|
for (const compName of usedComponents) {
|
|
@@ -1584,11 +2116,44 @@ export async function build(options) {
|
|
|
1584
2116
|
expressionRewrite = buildComponentExpressionRewrite(compPath, componentSource, compIr, compilerOpts);
|
|
1585
2117
|
componentExpressionRewriteCache.set(compPath, expressionRewrite);
|
|
1586
2118
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
2119
|
+
|
|
2120
|
+
let usageEntry = (componentUsageAttrs.get(compName) || [])[0] || { attrs: '', ownerPath: sourceFile };
|
|
2121
|
+
if (!usageEntry || typeof usageEntry !== 'object') {
|
|
2122
|
+
usageEntry = { attrs: '', ownerPath: sourceFile };
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
let attrExpressionRewrite = pageSelfExpressionRewrite;
|
|
2126
|
+
let attrScopeRewrite = pageScopeRewrite;
|
|
2127
|
+
const ownerPath = typeof usageEntry.ownerPath === 'string' && usageEntry.ownerPath.length > 0
|
|
2128
|
+
? usageEntry.ownerPath
|
|
2129
|
+
: sourceFile;
|
|
2130
|
+
|
|
2131
|
+
if (ownerPath !== sourceFile) {
|
|
2132
|
+
let ownerIr = componentIrCache.get(ownerPath);
|
|
2133
|
+
if (!ownerIr) {
|
|
2134
|
+
const ownerSource = readFileSync(ownerPath, 'utf8');
|
|
2135
|
+
ownerIr = runCompiler(
|
|
2136
|
+
ownerPath,
|
|
2137
|
+
stripStyleBlocks(ownerSource),
|
|
2138
|
+
compilerOpts,
|
|
2139
|
+
{ onWarning: emitCompilerWarning }
|
|
2140
|
+
);
|
|
2141
|
+
componentIrCache.set(ownerPath, ownerIr);
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
attrExpressionRewrite = componentExpressionRewriteCache.get(ownerPath);
|
|
2145
|
+
if (!attrExpressionRewrite) {
|
|
2146
|
+
const ownerSource = readFileSync(ownerPath, 'utf8');
|
|
2147
|
+
attrExpressionRewrite = buildComponentExpressionRewrite(ownerPath, ownerSource, ownerIr, compilerOpts);
|
|
2148
|
+
componentExpressionRewriteCache.set(ownerPath, attrExpressionRewrite);
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
attrScopeRewrite = componentScopeRewriteCache.get(ownerPath);
|
|
2152
|
+
if (!attrScopeRewrite) {
|
|
2153
|
+
attrScopeRewrite = buildScopedIdentifierRewrite(ownerIr);
|
|
2154
|
+
componentScopeRewriteCache.set(ownerPath, attrScopeRewrite);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
1592
2157
|
|
|
1593
2158
|
// 2d. Merge component IR into page IR
|
|
1594
2159
|
mergeComponentIr(
|
|
@@ -1600,18 +2165,32 @@ export async function build(options) {
|
|
|
1600
2165
|
includeCode: true,
|
|
1601
2166
|
cssImportsOnly: isDocMode,
|
|
1602
2167
|
documentMode: isDocMode,
|
|
1603
|
-
componentAttrs:
|
|
2168
|
+
componentAttrs: typeof usageEntry.attrs === 'string' ? usageEntry.attrs : '',
|
|
2169
|
+
componentAttrsRewrite: {
|
|
2170
|
+
expressionRewrite: attrExpressionRewrite,
|
|
2171
|
+
scopeRewrite: attrScopeRewrite
|
|
2172
|
+
}
|
|
1604
2173
|
},
|
|
1605
2174
|
seenStaticImports,
|
|
1606
2175
|
knownRefKeys
|
|
1607
2176
|
);
|
|
2177
|
+
|
|
2178
|
+
mergeExpressionRewriteMaps(
|
|
2179
|
+
pageExpressionRewriteMap,
|
|
2180
|
+
pageExpressionBindingMap,
|
|
2181
|
+
pageAmbiguousExpressionMap,
|
|
2182
|
+
expressionRewrite,
|
|
2183
|
+
pageIr
|
|
2184
|
+
);
|
|
1608
2185
|
}
|
|
1609
2186
|
|
|
1610
2187
|
applyExpressionRewrites(
|
|
1611
2188
|
pageIr,
|
|
1612
2189
|
pageExpressionRewriteMap,
|
|
2190
|
+
pageExpressionBindingMap,
|
|
1613
2191
|
pageAmbiguousExpressionMap
|
|
1614
2192
|
);
|
|
2193
|
+
normalizeExpressionBindingDependencies(pageIr);
|
|
1615
2194
|
|
|
1616
2195
|
rewriteLegacyMarkupIdentifiers(pageIr);
|
|
1617
2196
|
rewriteRefBindingIdentifiers(pageIr, knownRefKeys);
|