@barefootjs/rust 0.31.3 → 0.31.5

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/vite.js CHANGED
@@ -5,7 +5,7 @@ import { barefoot as coreBarefoot } from "@barefootjs/vite";
5
5
  import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPosixRelative } from "@barefootjs/vite";
6
6
 
7
7
  // ../jsx/src/compiler.ts
8
- import ts23 from "typescript";
8
+ import ts24 from "typescript";
9
9
 
10
10
  // ../jsx/src/analyzer.ts
11
11
  import ts9 from "typescript";
@@ -2000,6 +2000,20 @@ function templatePartsToJsExpr(parts, opts) {
2000
2000
  return result;
2001
2001
  }
2002
2002
 
2003
+ // ../jsx/src/identifier-pattern.ts
2004
+ function withUnicodeFlag(flags) {
2005
+ return flags.includes("u") ? flags : `${flags}u`;
2006
+ }
2007
+ function escapeIdentifierForRegex(name) {
2008
+ return name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2009
+ }
2010
+ var ID_BOUNDARY_BEFORE = "(?<![\\p{ID_Continue}$])";
2011
+ var ID_BOUNDARY_AFTER = "(?![\\p{ID_Continue}$])";
2012
+ function identifierPattern(name, flags = "") {
2013
+ const esc = escapeIdentifierForRegex(name);
2014
+ return new RegExp(`${ID_BOUNDARY_BEFORE}${esc}${ID_BOUNDARY_AFTER}`, withUnicodeFlag(flags));
2015
+ }
2016
+
2003
2017
  // ../jsx/src/scanner/js-scanner.ts
2004
2018
  import ts2 from "typescript";
2005
2019
 
@@ -2117,6 +2131,83 @@ function derivesScopeFromSlot(comp) {
2117
2131
  return comp.slotId != null && comp.loopItemRoot !== true;
2118
2132
  }
2119
2133
 
2134
+ // ../jsx/src/scope/binding-scope.ts
2135
+ class BindingScope {
2136
+ frames;
2137
+ static EMPTY = new BindingScope([]);
2138
+ constructor(frames) {
2139
+ this.frames = frames;
2140
+ }
2141
+ enterLoopRow(loop) {
2142
+ const bindings = new Map;
2143
+ if (loop.paramBindings && loop.paramBindings.length > 0) {
2144
+ for (const b of loop.paramBindings)
2145
+ bindings.set(b.name, { source: "destructure" });
2146
+ } else {
2147
+ bindings.set(loop.param, { source: "item" });
2148
+ }
2149
+ if (loop.index != null)
2150
+ bindings.set(loop.index, { source: "index" });
2151
+ for (const name of loop.preamble?.declaredNames ?? [])
2152
+ bindings.set(name, { source: "preamble" });
2153
+ const frame = { kind: "loop-row", bindings };
2154
+ return new BindingScope([frame, ...this.frames]);
2155
+ }
2156
+ enterCallback(params) {
2157
+ const bindings = new Map;
2158
+ for (const name of params)
2159
+ bindings.set(name, { source: "param" });
2160
+ const frame = { kind: "callback", bindings };
2161
+ return new BindingScope([frame, ...this.frames]);
2162
+ }
2163
+ isBound(name) {
2164
+ for (const frame of this.frames) {
2165
+ if (frame.bindings.has(name))
2166
+ return true;
2167
+ }
2168
+ return false;
2169
+ }
2170
+ lookup(name) {
2171
+ for (let depth = 0;depth < this.frames.length; depth++) {
2172
+ const frame = this.frames[depth];
2173
+ const binding = frame.bindings.get(name);
2174
+ if (binding)
2175
+ return { depth, frame, binding };
2176
+ }
2177
+ return null;
2178
+ }
2179
+ boundNames() {
2180
+ if (this.boundNamesCache)
2181
+ return this.boundNamesCache;
2182
+ const names = new Set;
2183
+ for (const frame of this.frames) {
2184
+ for (const name of frame.bindings.keys())
2185
+ names.add(name);
2186
+ }
2187
+ this.boundNamesCache = names;
2188
+ return names;
2189
+ }
2190
+ boundNamesCache;
2191
+ valueBoundNamesCache;
2192
+ valueBoundNames() {
2193
+ if (this.valueBoundNamesCache)
2194
+ return this.valueBoundNamesCache;
2195
+ const names = new Set;
2196
+ for (const frame of this.frames) {
2197
+ for (const [name, binding] of frame.bindings) {
2198
+ if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
2199
+ names.add(name);
2200
+ }
2201
+ }
2202
+ }
2203
+ this.valueBoundNamesCache = names;
2204
+ return names;
2205
+ }
2206
+ asShadowPredicate() {
2207
+ return (name) => this.isBound(name);
2208
+ }
2209
+ }
2210
+
2120
2211
  // ../jsx/src/ir-to-client-js/html-template.ts
2121
2212
  var VOID_ELEMENTS = new Set([
2122
2213
  "area",
@@ -2488,7 +2579,7 @@ var REACTIVE_PRIMITIVES = new Set([
2488
2579
  ]);
2489
2580
 
2490
2581
  // ../jsx/src/jsx-to-ir.ts
2491
- import ts12 from "typescript";
2582
+ import ts13 from "typescript";
2492
2583
 
2493
2584
  // ../jsx/src/types.ts
2494
2585
  var SCOPE_FORBIDDEN = {
@@ -2538,6 +2629,7 @@ function preambleAnalysisTemplateText(p) {
2538
2629
  }
2539
2630
 
2540
2631
  // ../jsx/src/module-exports.ts
2632
+ import ts10 from "typescript";
2541
2633
  function formatParamWithType(p) {
2542
2634
  const rest = p.isRest ? "..." : "";
2543
2635
  const optional = p.optional ? "?" : "";
@@ -2551,7 +2643,7 @@ function findReachableNames(primaryRefs, declarations) {
2551
2643
  const reachable = new Set;
2552
2644
  const queue = [];
2553
2645
  for (const name of allNames) {
2554
- if (new RegExp(`\\b${name}\\b`).test(primaryRefs)) {
2646
+ if (identifierPattern(name).test(primaryRefs)) {
2555
2647
  reachable.add(name);
2556
2648
  queue.push(name);
2557
2649
  }
@@ -2560,7 +2652,7 @@ function findReachableNames(primaryRefs, declarations) {
2560
2652
  const current = queue.shift();
2561
2653
  const body = bodyMap.get(current) || "";
2562
2654
  for (const name of allNames) {
2563
- if (!reachable.has(name) && new RegExp(`\\b${name}\\b`).test(body)) {
2655
+ if (!reachable.has(name) && identifierPattern(name).test(body)) {
2564
2656
  reachable.add(name);
2565
2657
  queue.push(name);
2566
2658
  }
@@ -2568,12 +2660,55 @@ function findReachableNames(primaryRefs, declarations) {
2568
2660
  }
2569
2661
  return reachable;
2570
2662
  }
2663
+ function findAssignedNames(bodyText, candidates) {
2664
+ const assigned = new Set;
2665
+ if (candidates.size === 0)
2666
+ return assigned;
2667
+ const sf = ts10.createSourceFile("bf-assignment-scan.tsx", bodyText, ts10.ScriptTarget.Latest, false, ts10.ScriptKind.TSX);
2668
+ const record = (target) => {
2669
+ if (ts10.isIdentifier(target) && candidates.has(target.text)) {
2670
+ assigned.add(target.text);
2671
+ }
2672
+ };
2673
+ const visit = (node) => {
2674
+ if (ts10.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
2675
+ record(node.left);
2676
+ } else if ((ts10.isPrefixUnaryExpression(node) || ts10.isPostfixUnaryExpression(node)) && (node.operator === ts10.SyntaxKind.PlusPlusToken || node.operator === ts10.SyntaxKind.MinusMinusToken)) {
2677
+ record(node.operand);
2678
+ }
2679
+ ts10.forEachChild(node, visit);
2680
+ };
2681
+ ts10.forEachChild(sf, visit);
2682
+ return assigned;
2683
+ }
2684
+ function closeOverWritersOfMutableBindings(primaryRefs, declarations, mutableNames) {
2685
+ let reachable = findReachableNames(primaryRefs, declarations);
2686
+ if (mutableNames.size === 0)
2687
+ return reachable;
2688
+ let seedText = primaryRefs;
2689
+ for (let round = 0;round <= declarations.length; round++) {
2690
+ const survivingMutables = new Set([...reachable].filter((name) => mutableNames.has(name)));
2691
+ if (survivingMutables.size === 0)
2692
+ return reachable;
2693
+ const added = declarations.filter((d) => !reachable.has(d.name)).filter((d) => findAssignedNames(d.body, survivingMutables).size > 0).map((d) => d.name);
2694
+ if (added.length === 0)
2695
+ return reachable;
2696
+ seedText += `
2697
+ ` + added.join(`
2698
+ `);
2699
+ reachable = findReachableNames(seedText, declarations);
2700
+ }
2701
+ return reachable;
2702
+ }
2703
+ function isAssignmentOperator(kind) {
2704
+ return kind >= ts10.SyntaxKind.FirstAssignment && kind <= ts10.SyntaxKind.LastAssignment;
2705
+ }
2571
2706
 
2572
2707
  // ../jsx/src/reactivity-checker.ts
2573
- import ts10 from "typescript";
2708
+ import ts11 from "typescript";
2574
2709
 
2575
2710
  // ../jsx/src/free-refs.ts
2576
- import ts11 from "typescript";
2711
+ import ts12 from "typescript";
2577
2712
  var _bindingMapCache = new WeakMap;
2578
2713
 
2579
2714
  // ../jsx/src/to-locale-date-lowering.ts
@@ -2891,83 +3026,6 @@ var toLocaleDatePlugin = {
2891
3026
  }
2892
3027
  };
2893
3028
 
2894
- // ../jsx/src/scope/binding-scope.ts
2895
- class BindingScope {
2896
- frames;
2897
- static EMPTY = new BindingScope([]);
2898
- constructor(frames) {
2899
- this.frames = frames;
2900
- }
2901
- enterLoopRow(loop) {
2902
- const bindings = new Map;
2903
- if (loop.paramBindings && loop.paramBindings.length > 0) {
2904
- for (const b of loop.paramBindings)
2905
- bindings.set(b.name, { source: "destructure" });
2906
- } else {
2907
- bindings.set(loop.param, { source: "item" });
2908
- }
2909
- if (loop.index != null)
2910
- bindings.set(loop.index, { source: "index" });
2911
- for (const name of loop.preamble?.declaredNames ?? [])
2912
- bindings.set(name, { source: "preamble" });
2913
- const frame = { kind: "loop-row", bindings };
2914
- return new BindingScope([frame, ...this.frames]);
2915
- }
2916
- enterCallback(params) {
2917
- const bindings = new Map;
2918
- for (const name of params)
2919
- bindings.set(name, { source: "param" });
2920
- const frame = { kind: "callback", bindings };
2921
- return new BindingScope([frame, ...this.frames]);
2922
- }
2923
- isBound(name) {
2924
- for (const frame of this.frames) {
2925
- if (frame.bindings.has(name))
2926
- return true;
2927
- }
2928
- return false;
2929
- }
2930
- lookup(name) {
2931
- for (let depth = 0;depth < this.frames.length; depth++) {
2932
- const frame = this.frames[depth];
2933
- const binding = frame.bindings.get(name);
2934
- if (binding)
2935
- return { depth, frame, binding };
2936
- }
2937
- return null;
2938
- }
2939
- boundNames() {
2940
- if (this.boundNamesCache)
2941
- return this.boundNamesCache;
2942
- const names = new Set;
2943
- for (const frame of this.frames) {
2944
- for (const name of frame.bindings.keys())
2945
- names.add(name);
2946
- }
2947
- this.boundNamesCache = names;
2948
- return names;
2949
- }
2950
- boundNamesCache;
2951
- valueBoundNamesCache;
2952
- valueBoundNames() {
2953
- if (this.valueBoundNamesCache)
2954
- return this.valueBoundNamesCache;
2955
- const names = new Set;
2956
- for (const frame of this.frames) {
2957
- for (const [name, binding] of frame.bindings) {
2958
- if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
2959
- names.add(name);
2960
- }
2961
- }
2962
- }
2963
- this.valueBoundNamesCache = names;
2964
- return names;
2965
- }
2966
- asShadowPredicate() {
2967
- return (name) => this.isBound(name);
2968
- }
2969
- }
2970
-
2971
3029
  // ../jsx/src/jsx-to-ir.ts
2972
3030
  var EMPTY_BOUND = new Set;
2973
3031
  var constInitializerCache = new WeakMap;
@@ -3064,13 +3122,13 @@ var KEYWORDS_AND_GLOBALS = new Set([
3064
3122
  ]);
3065
3123
 
3066
3124
  // ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
3067
- import ts13 from "typescript";
3125
+ import ts14 from "typescript";
3068
3126
 
3069
3127
  // ../jsx/src/value-references.ts
3070
- import ts14 from "typescript";
3128
+ import ts15 from "typescript";
3071
3129
 
3072
3130
  // ../jsx/src/relocate.ts
3073
- import ts15 from "typescript";
3131
+ import ts16 from "typescript";
3074
3132
 
3075
3133
  // ../jsx/src/lowering-registry.ts
3076
3134
  var plugins = [];
@@ -3287,10 +3345,10 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
3287
3345
  }
3288
3346
 
3289
3347
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
3290
- import ts16 from "typescript";
3348
+ import ts17 from "typescript";
3291
3349
 
3292
3350
  // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3293
- import ts17 from "typescript";
3351
+ import ts18 from "typescript";
3294
3352
  var NO_PREAMBLE = {
3295
3353
  lazySafe: true,
3296
3354
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -3340,7 +3398,7 @@ var INERT_BINDING_GLOBALS = new Set([
3340
3398
  ]);
3341
3399
 
3342
3400
  // ../jsx/src/ir-to-client-js/emit-reactive.ts
3343
- import ts18 from "typescript";
3401
+ import ts19 from "typescript";
3344
3402
 
3345
3403
  // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
3346
3404
  var NON_BUBBLING_EVENTS = new Set([
@@ -3355,7 +3413,7 @@ var NON_BUBBLING_EVENTS = new Set([
3355
3413
  ]);
3356
3414
 
3357
3415
  // ../jsx/src/ir-to-client-js/rewrite-props-object.ts
3358
- import ts19 from "typescript";
3416
+ import ts20 from "typescript";
3359
3417
 
3360
3418
  // ../jsx/src/ir-to-client-js/source-map.ts
3361
3419
  var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -3446,15 +3504,15 @@ class SourceMapGenerator {
3446
3504
  }
3447
3505
 
3448
3506
  // ../jsx/src/preprocess-inline-jsx-callbacks.ts
3449
- import ts20 from "typescript";
3507
+ import ts21 from "typescript";
3450
3508
 
3451
3509
  // ../jsx/src/ssr-defaults.ts
3452
- import ts21 from "typescript";
3510
+ import ts22 from "typescript";
3453
3511
  var UNRESOLVED = Symbol("unresolved");
3454
3512
  var NO_RETURN = Symbol("no-return");
3455
3513
 
3456
3514
  // ../jsx/src/augment-inherited-props.ts
3457
- import ts22 from "typescript";
3515
+ import ts23 from "typescript";
3458
3516
  function collectContextConsumers(metadata) {
3459
3517
  const constants = metadata.localConstants ?? [];
3460
3518
  const contextDefaults = new Map;
@@ -3486,47 +3544,47 @@ function collectContextConsumers(metadata) {
3486
3544
  }
3487
3545
  function parseUseContextArg(source) {
3488
3546
  const expr = parseSingleExpression(source);
3489
- if (!expr || !ts22.isCallExpression(expr))
3547
+ if (!expr || !ts23.isCallExpression(expr))
3490
3548
  return null;
3491
- if (!ts22.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3549
+ if (!ts23.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
3492
3550
  return null;
3493
3551
  if (expr.arguments.length !== 1)
3494
3552
  return null;
3495
3553
  const arg = expr.arguments[0];
3496
- return ts22.isIdentifier(arg) ? arg.text : null;
3554
+ return ts23.isIdentifier(arg) ? arg.text : null;
3497
3555
  }
3498
3556
  function parseCreateContextDefault(source) {
3499
3557
  const expr = parseSingleExpression(source);
3500
- if (!expr || !ts22.isCallExpression(expr))
3558
+ if (!expr || !ts23.isCallExpression(expr))
3501
3559
  return null;
3502
3560
  if (expr.arguments.length === 0)
3503
3561
  return null;
3504
3562
  const arg = expr.arguments[0];
3505
- if (ts22.isStringLiteral(arg) || ts22.isNoSubstitutionTemplateLiteral(arg))
3563
+ if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3506
3564
  return arg.text;
3507
- if (ts22.isNumericLiteral(arg))
3565
+ if (ts23.isNumericLiteral(arg))
3508
3566
  return Number(arg.text);
3509
- if (arg.kind === ts22.SyntaxKind.TrueKeyword)
3567
+ if (arg.kind === ts23.SyntaxKind.TrueKeyword)
3510
3568
  return true;
3511
- if (arg.kind === ts22.SyntaxKind.FalseKeyword)
3569
+ if (arg.kind === ts23.SyntaxKind.FalseKeyword)
3512
3570
  return false;
3513
3571
  return null;
3514
3572
  }
3515
3573
  function isObjectLiteralCreateContextDefault(source) {
3516
3574
  const expr = parseSingleExpression(source);
3517
- if (!expr || !ts22.isCallExpression(expr))
3575
+ if (!expr || !ts23.isCallExpression(expr))
3518
3576
  return false;
3519
3577
  if (expr.arguments.length === 0)
3520
3578
  return false;
3521
- return ts22.isObjectLiteralExpression(expr.arguments[0]);
3579
+ return ts23.isObjectLiteralExpression(expr.arguments[0]);
3522
3580
  }
3523
3581
  function parseSingleExpression(source) {
3524
- const sf = ts22.createSourceFile("__ctx.ts", `(${source})`, ts22.ScriptTarget.Latest, false);
3582
+ const sf = ts23.createSourceFile("__ctx.ts", `(${source})`, ts23.ScriptTarget.Latest, false);
3525
3583
  const stmt = sf.statements[0];
3526
- if (!stmt || !ts22.isExpressionStatement(stmt))
3584
+ if (!stmt || !ts23.isExpressionStatement(stmt))
3527
3585
  return null;
3528
3586
  let e = stmt.expression;
3529
- while (ts22.isParenthesizedExpression(e))
3587
+ while (ts23.isParenthesizedExpression(e))
3530
3588
  e = e.expression;
3531
3589
  return e;
3532
3590
  }
@@ -3551,25 +3609,25 @@ function augmentInheritedPropAccesses(ir) {
3551
3609
  const pinCoalesceLiterals = (s) => {
3552
3610
  if (!s || !s.includes(propsObj))
3553
3611
  return;
3554
- const sf = ts22.createSourceFile("__aug.ts", `(${s})`, ts22.ScriptTarget.Latest, false);
3612
+ const sf = ts23.createSourceFile("__aug.ts", `(${s})`, ts23.ScriptTarget.Latest, false);
3555
3613
  const visit = (n) => {
3556
- if (ts22.isBinaryExpression(n) && (n.operatorToken.kind === ts22.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts22.SyntaxKind.BarBarToken)) {
3614
+ if (ts23.isBinaryExpression(n) && (n.operatorToken.kind === ts23.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts23.SyntaxKind.BarBarToken)) {
3557
3615
  let left = n.left;
3558
- while (ts22.isParenthesizedExpression(left))
3616
+ while (ts23.isParenthesizedExpression(left))
3559
3617
  left = left.expression;
3560
- if (ts22.isPropertyAccessExpression(left) && ts22.isIdentifier(left.expression) && left.expression.text === propsObj) {
3618
+ if (ts23.isPropertyAccessExpression(left) && ts23.isIdentifier(left.expression) && left.expression.text === propsObj) {
3561
3619
  const name = left.name.text;
3562
3620
  let right = n.right;
3563
- while (ts22.isParenthesizedExpression(right))
3621
+ while (ts23.isParenthesizedExpression(right))
3564
3622
  right = right.expression;
3565
- if (ts22.isPrefixUnaryExpression(right))
3623
+ if (ts23.isPrefixUnaryExpression(right))
3566
3624
  right = right.operand;
3567
- const kind = ts22.isNumericLiteral(right) ? "number" : right.kind === ts22.SyntaxKind.TrueKeyword || right.kind === ts22.SyntaxKind.FalseKeyword ? "boolean" : ts22.isStringLiteralLike(right) ? "string" : null;
3625
+ const kind = ts23.isNumericLiteral(right) ? "number" : right.kind === ts23.SyntaxKind.TrueKeyword || right.kind === ts23.SyntaxKind.FalseKeyword ? "boolean" : ts23.isStringLiteralLike(right) ? "string" : null;
3568
3626
  if (kind && !coalesceLiteralTypes.has(name))
3569
3627
  coalesceLiteralTypes.set(name, kind);
3570
3628
  }
3571
3629
  }
3572
- ts22.forEachChild(n, visit);
3630
+ ts23.forEachChild(n, visit);
3573
3631
  };
3574
3632
  visit(sf);
3575
3633
  };
@@ -3680,33 +3738,33 @@ function augmentInheritedPropAccesses(ir) {
3680
3738
  }
3681
3739
  }
3682
3740
  function parseStaticStringConst(source) {
3683
- const sf = ts22.createSourceFile("__const.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3741
+ const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3684
3742
  const stmt = sf.statements[0];
3685
- if (!stmt || !ts22.isVariableStatement(stmt))
3743
+ if (!stmt || !ts23.isVariableStatement(stmt))
3686
3744
  return null;
3687
3745
  let init = stmt.declarationList.declarations[0]?.initializer;
3688
- while (init && ts22.isParenthesizedExpression(init))
3746
+ while (init && ts23.isParenthesizedExpression(init))
3689
3747
  init = init.expression;
3690
3748
  if (!init)
3691
3749
  return null;
3692
- if (ts22.isStringLiteral(init) || ts22.isNoSubstitutionTemplateLiteral(init)) {
3750
+ if (ts23.isStringLiteral(init) || ts23.isNoSubstitutionTemplateLiteral(init)) {
3693
3751
  return init.text;
3694
3752
  }
3695
3753
  return evalStringArrayJoin(source);
3696
3754
  }
3697
3755
  function evalTemplateOfStringConsts(source, resolved) {
3698
- const sf = ts22.createSourceFile("__const.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3756
+ const sf = ts23.createSourceFile("__const.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3699
3757
  const stmt = sf.statements[0];
3700
- if (!stmt || !ts22.isVariableStatement(stmt))
3758
+ if (!stmt || !ts23.isVariableStatement(stmt))
3701
3759
  return null;
3702
3760
  let init = stmt.declarationList.declarations[0]?.initializer;
3703
- while (init && ts22.isParenthesizedExpression(init))
3761
+ while (init && ts23.isParenthesizedExpression(init))
3704
3762
  init = init.expression;
3705
- if (!init || !ts22.isTemplateExpression(init))
3763
+ if (!init || !ts23.isTemplateExpression(init))
3706
3764
  return null;
3707
3765
  let out = init.head.text;
3708
3766
  for (const span of init.templateSpans) {
3709
- if (!ts22.isIdentifier(span.expression))
3767
+ if (!ts23.isIdentifier(span.expression))
3710
3768
  return null;
3711
3769
  const value = resolved.get(span.expression.text);
3712
3770
  if (value === undefined)
@@ -3733,34 +3791,36 @@ function collectModuleStringConsts(constants) {
3733
3791
  }
3734
3792
  return map;
3735
3793
  }
3736
- function lookupStaticRecordLiteral(objectName, key, constants) {
3794
+ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
3795
+ if (isShadowed(objectName))
3796
+ return null;
3737
3797
  const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
3738
3798
  if (constInfo?.value === undefined)
3739
3799
  return null;
3740
- const sf = ts22.createSourceFile("__rec.ts", `(${constInfo.value})`, ts22.ScriptTarget.Latest, true);
3800
+ const sf = ts23.createSourceFile("__rec.ts", `(${constInfo.value})`, ts23.ScriptTarget.Latest, true);
3741
3801
  if (sf.statements.length !== 1)
3742
3802
  return null;
3743
3803
  const stmt = sf.statements[0];
3744
- if (!ts22.isExpressionStatement(stmt))
3804
+ if (!ts23.isExpressionStatement(stmt))
3745
3805
  return null;
3746
3806
  let parsed = stmt.expression;
3747
- while (ts22.isParenthesizedExpression(parsed))
3807
+ while (ts23.isParenthesizedExpression(parsed))
3748
3808
  parsed = parsed.expression;
3749
- if (!ts22.isObjectLiteralExpression(parsed))
3809
+ if (!ts23.isObjectLiteralExpression(parsed))
3750
3810
  return null;
3751
3811
  for (const prop of parsed.properties) {
3752
- if (!ts22.isPropertyAssignment(prop))
3812
+ if (!ts23.isPropertyAssignment(prop))
3753
3813
  continue;
3754
3814
  const name = prop.name;
3755
- const propKey = ts22.isIdentifier(name) || ts22.isStringLiteral(name) || ts22.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3815
+ const propKey = ts23.isIdentifier(name) || ts23.isStringLiteral(name) || ts23.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
3756
3816
  if (propKey !== key)
3757
3817
  continue;
3758
3818
  let v = prop.initializer;
3759
- while (ts22.isParenthesizedExpression(v))
3819
+ while (ts23.isParenthesizedExpression(v))
3760
3820
  v = v.expression;
3761
- if (ts22.isNumericLiteral(v))
3821
+ if (ts23.isNumericLiteral(v))
3762
3822
  return { kind: "number", text: v.text };
3763
- if (ts22.isStringLiteral(v) || ts22.isNoSubstitutionTemplateLiteral(v)) {
3823
+ if (ts23.isStringLiteral(v) || ts23.isNoSubstitutionTemplateLiteral(v)) {
3764
3824
  return { kind: "string", text: v.text };
3765
3825
  }
3766
3826
  return null;
@@ -3768,28 +3828,28 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
3768
3828
  return null;
3769
3829
  }
3770
3830
  function evalStringArrayJoin(source) {
3771
- const sf = ts22.createSourceFile("__join.ts", `const __x = (${source});`, ts22.ScriptTarget.Latest, false);
3831
+ const sf = ts23.createSourceFile("__join.ts", `const __x = (${source});`, ts23.ScriptTarget.Latest, false);
3772
3832
  const stmt = sf.statements[0];
3773
- if (!stmt || !ts22.isVariableStatement(stmt))
3833
+ if (!stmt || !ts23.isVariableStatement(stmt))
3774
3834
  return null;
3775
3835
  let node = stmt.declarationList.declarations[0]?.initializer;
3776
- while (node && ts22.isParenthesizedExpression(node))
3836
+ while (node && ts23.isParenthesizedExpression(node))
3777
3837
  node = node.expression;
3778
- if (!node || !ts22.isCallExpression(node))
3838
+ if (!node || !ts23.isCallExpression(node))
3779
3839
  return null;
3780
3840
  const callee = node.expression;
3781
- if (!ts22.isPropertyAccessExpression(callee))
3841
+ if (!ts23.isPropertyAccessExpression(callee))
3782
3842
  return null;
3783
3843
  if (callee.name.text !== "join")
3784
3844
  return null;
3785
3845
  let recv = callee.expression;
3786
- while (ts22.isParenthesizedExpression(recv))
3846
+ while (ts23.isParenthesizedExpression(recv))
3787
3847
  recv = recv.expression;
3788
- if (!ts22.isArrayLiteralExpression(recv))
3848
+ if (!ts23.isArrayLiteralExpression(recv))
3789
3849
  return null;
3790
3850
  const parts = [];
3791
3851
  for (const el of recv.elements) {
3792
- if (ts22.isStringLiteral(el) || ts22.isNoSubstitutionTemplateLiteral(el)) {
3852
+ if (ts23.isStringLiteral(el) || ts23.isNoSubstitutionTemplateLiteral(el)) {
3793
3853
  parts.push(el.text);
3794
3854
  } else {
3795
3855
  return null;
@@ -3798,7 +3858,7 @@ function evalStringArrayJoin(source) {
3798
3858
  let sep = ",";
3799
3859
  if (node.arguments.length >= 1) {
3800
3860
  const arg = node.arguments[0];
3801
- if (ts22.isStringLiteral(arg) || ts22.isNoSubstitutionTemplateLiteral(arg))
3861
+ if (ts23.isStringLiteral(arg) || ts23.isNoSubstitutionTemplateLiteral(arg))
3802
3862
  sep = arg.text;
3803
3863
  else
3804
3864
  return null;
@@ -3806,11 +3866,11 @@ function evalStringArrayJoin(source) {
3806
3866
  return parts.join(sep);
3807
3867
  }
3808
3868
  function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3809
- if (!ts22.isElementAccessExpression(val))
3869
+ if (!ts23.isElementAccessExpression(val))
3810
3870
  return null;
3811
3871
  const obj = val.expression;
3812
3872
  const arg = val.argumentExpression;
3813
- if (!ts22.isIdentifier(obj) || !ts22.isIdentifier(arg))
3873
+ if (!ts23.isIdentifier(obj) || !ts23.isIdentifier(arg))
3814
3874
  return null;
3815
3875
  let indexPropName;
3816
3876
  let defaultKey;
@@ -3826,35 +3886,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3826
3886
  const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
3827
3887
  if (constInfo?.value === undefined)
3828
3888
  return null;
3829
- const sf = ts22.createSourceFile("__rec.ts", `(${constInfo.value})`, ts22.ScriptTarget.Latest, true);
3889
+ const sf = ts23.createSourceFile("__rec.ts", `(${constInfo.value})`, ts23.ScriptTarget.Latest, true);
3830
3890
  if (sf.statements.length !== 1)
3831
3891
  return null;
3832
3892
  const stmt = sf.statements[0];
3833
- if (!ts22.isExpressionStatement(stmt))
3893
+ if (!ts23.isExpressionStatement(stmt))
3834
3894
  return null;
3835
3895
  let parsed = stmt.expression;
3836
- while (ts22.isParenthesizedExpression(parsed))
3896
+ while (ts23.isParenthesizedExpression(parsed))
3837
3897
  parsed = parsed.expression;
3838
- if (!ts22.isObjectLiteralExpression(parsed))
3898
+ if (!ts23.isObjectLiteralExpression(parsed))
3839
3899
  return null;
3840
3900
  const entries = [];
3841
3901
  for (const prop of parsed.properties) {
3842
- if (!ts22.isPropertyAssignment(prop))
3902
+ if (!ts23.isPropertyAssignment(prop))
3843
3903
  return null;
3844
3904
  let key;
3845
- if (ts22.isIdentifier(prop.name)) {
3905
+ if (ts23.isIdentifier(prop.name)) {
3846
3906
  key = prop.name.text;
3847
- } else if (ts22.isStringLiteral(prop.name) || ts22.isNoSubstitutionTemplateLiteral(prop.name)) {
3907
+ } else if (ts23.isStringLiteral(prop.name) || ts23.isNoSubstitutionTemplateLiteral(prop.name)) {
3848
3908
  key = prop.name.text;
3849
3909
  } else {
3850
3910
  return null;
3851
3911
  }
3852
3912
  let v = prop.initializer;
3853
- while (ts22.isParenthesizedExpression(v))
3913
+ while (ts23.isParenthesizedExpression(v))
3854
3914
  v = v.expression;
3855
- if (ts22.isNumericLiteral(v)) {
3915
+ if (ts23.isNumericLiteral(v)) {
3856
3916
  entries.push({ key, value: { kind: "number", text: v.text } });
3857
- } else if (ts22.isStringLiteral(v) || ts22.isNoSubstitutionTemplateLiteral(v)) {
3917
+ } else if (ts23.isStringLiteral(v) || ts23.isNoSubstitutionTemplateLiteral(v)) {
3858
3918
  entries.push({ key, value: { kind: "string", text: v.text } });
3859
3919
  } else {
3860
3920
  return null;
@@ -3910,7 +3970,7 @@ function computeSsrSeedPlan(metadata) {
3910
3970
  // ../jsx/src/rich-type-refusal.ts
3911
3971
  var EMPTY_BINDINGS2 = new Map;
3912
3972
  // ../jsx/src/shared-program.ts
3913
- import ts24 from "typescript";
3973
+ import ts25 from "typescript";
3914
3974
  // ../jsx/src/adapters/interface.ts
3915
3975
  class BaseAdapter {
3916
3976
  renderChildren(children) {
@@ -3963,7 +4023,7 @@ class JsxAdapter extends BaseAdapter {
3963
4023
  ...localFunctions.map((f) => ({ name: f.name, body: f.body })),
3964
4024
  ...localConstants.map((c) => ({ name: c.name, body: c.value }))
3965
4025
  ];
3966
- const reachable = findReachableNames(primaryRefText, declarations);
4026
+ const reachable = closeOverWritersOfMutableBindings(primaryRefText, declarations, new Set(ir.metadata.localConstants.filter((c) => (c.declarationKind ?? "const") !== "const").map((c) => c.name)));
3967
4027
  const reachableBodies = [...reachable].map((name) => {
3968
4028
  const func = localFunctions.find((f) => f.name === name);
3969
4029
  if (func)
@@ -3993,9 +4053,10 @@ class JsxAdapter extends BaseAdapter {
3993
4053
  lines.push(` const ${signal.getter} = () => ${initialValue}`);
3994
4054
  }
3995
4055
  if (signal.setter) {
3996
- const setterUsed = new RegExp(`\\b${signal.setter}\\b`).test(setterRefText);
4056
+ const setterUsed = identifierPattern(signal.setter).test(setterRefText);
3997
4057
  if (setterUsed) {
3998
- lines.push(` const ${signal.setter} = (..._args: any[]) => {}`);
4058
+ const setterType = preserveTypes && signal.type.kind !== "unknown" ? `(valueOrFn: ${signal.type.raw} | ((prev: ${signal.type.raw}) => ${signal.type.raw})) => void` : null;
4059
+ lines.push(setterType ? ` const ${signal.setter}: ${setterType} = () => {}` : ` const ${signal.setter} = (..._args: any[]) => {}`);
3999
4060
  }
4000
4061
  }
4001
4062
  }
@@ -4191,6 +4252,7 @@ class JsxAdapter extends BaseAdapter {
4191
4252
  }
4192
4253
 
4193
4254
  // ../jsx/src/adapters/template-imports.ts
4255
+ import ts26 from "typescript";
4194
4256
  var CLIENT_PACKAGE_SOURCES = new Set([
4195
4257
  "@barefootjs/client",
4196
4258
  "@barefootjs/client/runtime"
@@ -4329,7 +4391,8 @@ export default ${this.componentName}` : "";
4329
4391
  const noArgDefault = hasRequiredProps ? "" : ` = {} as ${propsTypeExpr}`;
4330
4392
  const lines = [];
4331
4393
  const exportPrefix = ir.metadata.isExported === false ? "" : "export ";
4332
- lines.push(`${exportPrefix}function ${name}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
4394
+ const typeParameters = ir.metadata.typeParameters ?? "";
4395
+ lines.push(`${exportPrefix}function ${name}${typeParameters}(${fullPropsDestructure}${typeAnnotation}${noArgDefault}) {`);
4333
4396
  if (hasClientInteractivity) {
4334
4397
  lines.push(` const __scopeId = (/_s\\d/.test(__bfScope || '') ? __bfScope : null) || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
4335
4398
  } else {
@@ -4546,72 +4609,6 @@ function emitParsedExpr(expr, emitter) {
4546
4609
  }
4547
4610
  }
4548
4611
  }
4549
- // ../jsx/src/adapters/loop-bound-names.ts
4550
- function collectLoopBoundNames(ir) {
4551
- const names = new Set;
4552
- const visit = (node) => {
4553
- if (!node)
4554
- return;
4555
- switch (node.type) {
4556
- case "element":
4557
- case "component":
4558
- case "fragment":
4559
- case "provider":
4560
- for (const child of node.children)
4561
- visit(child);
4562
- break;
4563
- case "async":
4564
- visit(node.fallback);
4565
- for (const child of node.children)
4566
- visit(child);
4567
- break;
4568
- case "loop":
4569
- names.add(node.param);
4570
- if (node.index)
4571
- names.add(node.index);
4572
- for (const binding of node.paramBindings ?? [])
4573
- names.add(binding.name);
4574
- if (node.filterPredicate)
4575
- names.add(node.filterPredicate.param);
4576
- for (const name of node.preamble?.declaredNames ?? [])
4577
- names.add(name);
4578
- for (const child of node.children)
4579
- visit(child);
4580
- if (node.childComponent) {
4581
- for (const child of node.childComponent.children)
4582
- visit(child);
4583
- }
4584
- for (const nested of node.nestedComponents ?? []) {
4585
- for (const child of nested.children)
4586
- visit(child);
4587
- }
4588
- for (const seg of node.flatMapCallback?.segments ?? []) {
4589
- if (seg.kind === "jsx")
4590
- visit(seg.ir);
4591
- }
4592
- for (const seg of node.preamble?.segments ?? []) {
4593
- if (seg.kind === "jsx")
4594
- visit(seg.ir);
4595
- }
4596
- break;
4597
- case "conditional":
4598
- visit(node.whenTrue);
4599
- visit(node.whenFalse);
4600
- break;
4601
- case "if-statement":
4602
- visit(node.consequent);
4603
- if (node.alternate)
4604
- visit(node.alternate);
4605
- break;
4606
- case "text":
4607
- case "expression":
4608
- case "slot":
4609
- break;
4610
- }
4611
- };
4612
- visit(ir.root);
4613
- return names;
4614
- }
4615
4612
  // ../jsx/src/static-literal.ts
4616
4613
  function evaluateStaticLiteral(expr, bindings) {
4617
4614
  switch (expr.kind) {
@@ -4933,7 +4930,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
4933
4930
  };
4934
4931
  }
4935
4932
  // ../jsx/src/combine-client-js.ts
4936
- import ts25 from "typescript";
4933
+ import ts27 from "typescript";
4937
4934
  // ../jsx/src/loop-destructure.ts
4938
4935
  function isLowerableLoopDestructure(loop) {
4939
4936
  const bindings = loop.paramBindings;
@@ -5073,9 +5070,9 @@ function escapeRe(s) {
5073
5070
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5074
5071
  }
5075
5072
  // ../jsx/src/debug.ts
5076
- import ts26 from "typescript";
5073
+ import ts28 from "typescript";
5077
5074
  // ../jsx/src/profiler.ts
5078
- import ts27 from "typescript";
5075
+ import ts29 from "typescript";
5079
5076
 
5080
5077
  // ../jsx/src/index.ts
5081
5078
  registerBuiltinLoweringPlugins();
@@ -5888,7 +5885,7 @@ function collectImportedLoopChildComponentErrors(ir, componentName) {
5888
5885
  }
5889
5886
 
5890
5887
  // src/adapter/spread/spread-codegen.ts
5891
- import ts28 from "typescript";
5888
+ import ts30 from "typescript";
5892
5889
  function conditionalSpreadToJinja(ctx, expr) {
5893
5890
  if (!expr || expr.kind !== "conditional")
5894
5891
  return null;
@@ -5943,7 +5940,7 @@ function recordIndexAccessToJinja(ctx, val) {
5943
5940
  if (val.kind !== "index-access" || val.object.kind !== "identifier" || val.index.kind !== "identifier") {
5944
5941
  return null;
5945
5942
  }
5946
- const tsVal = ts28.factory.createElementAccessExpression(ts28.factory.createIdentifier(val.object.name), ts28.factory.createIdentifier(val.index.name));
5943
+ const tsVal = ts30.factory.createElementAccessExpression(ts30.factory.createIdentifier(val.object.name), ts30.factory.createIdentifier(val.index.name));
5947
5944
  const parsed = parseRecordIndexAccess(tsVal, ctx.localConstants ?? [], ctx.propsParams);
5948
5945
  if (!parsed)
5949
5946
  return null;
@@ -6056,8 +6053,7 @@ class MinijinjaAdapter extends BaseAdapter {
6056
6053
  _searchParamsLocals = new Set;
6057
6054
  _loweringMatchers = [];
6058
6055
  localConstants = [];
6059
- staticLoopSourceBoundNames = new Set;
6060
- loopBoundNames = new Map;
6056
+ scope = BindingScope.EMPTY;
6061
6057
  nullableOptionalProps = new Set;
6062
6058
  constructor(options = {}) {
6063
6059
  super();
@@ -6073,8 +6069,7 @@ class MinijinjaAdapter extends BaseAdapter {
6073
6069
  this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
6074
6070
  this.booleanTypedProps = collectBooleanTypedProps(ir);
6075
6071
  this.localConstants = ir.metadata.localConstants ?? [];
6076
- this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
6077
- this.loopBoundNames.clear();
6072
+ this.scope = BindingScope.EMPTY;
6078
6073
  this.nullableOptionalProps = collectNullableOptionalProps(ir);
6079
6074
  this.stringValueNames = collectStringValueNames(ir);
6080
6075
  this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
@@ -6368,7 +6363,7 @@ ${whenTrue}
6368
6363
  });
6369
6364
  }
6370
6365
  const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
6371
- isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
6366
+ isNameShadowed: this.scope.asShadowPredicate()
6372
6367
  });
6373
6368
  const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
6374
6369
  const arrayName = loop.array.trim();
@@ -6422,42 +6417,15 @@ ${whenTrue}
6422
6417
  this.inLoop = true;
6423
6418
  const prevLoopKeyDepth = this.currentLoopKeyDepth;
6424
6419
  this.currentLoopKeyDepth = loop.depth;
6420
+ const prevScope = this.scope;
6421
+ this.scope = prevScope.enterLoopRow(loop);
6425
6422
  const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${minijinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
6426
- const loopBound = [];
6427
- if (loop.objectIteration === "entries") {
6428
- loopBound.push(loop.index ?? param, param);
6429
- } else if (loop.objectIteration === "keys") {
6430
- loopBound.push(param, "__bf_v");
6431
- } else if (loop.objectIteration === "values") {
6432
- loopBound.push("__bf_k", param);
6433
- } else if (loop.iterationShape === "keys") {
6434
- loopBound.push("__bf_item", param);
6435
- } else if (supportableDestructure) {
6436
- loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
6437
- if (loop.index)
6438
- loopBound.push(loop.index);
6439
- } else {
6440
- loopBound.push(param);
6441
- if (loop.index)
6442
- loopBound.push(loop.index);
6443
- }
6444
- for (const d of loop.preamble?.declarations ?? [])
6445
- loopBound.push(d.name);
6446
- for (const n of loopBound) {
6447
- this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
6448
- }
6449
6423
  const childrenUnderLoop = this.renderChildren(loop.children);
6450
- for (const n of loopBound) {
6451
- const c = (this.loopBoundNames.get(n) ?? 1) - 1;
6452
- if (c <= 0)
6453
- this.loopBoundNames.delete(n);
6454
- else
6455
- this.loopBoundNames.set(n, c);
6456
- }
6457
6424
  this.currentLoopKeyDepth = prevLoopKeyDepth;
6458
6425
  this.inLoop = prevInLoop;
6459
6426
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
6460
6427
  ${childrenUnderLoop}` : childrenUnderLoop;
6428
+ this.scope = prevScope;
6461
6429
  const lines = [];
6462
6430
  lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
6463
6431
  const forHeader = loop.objectIteration === "entries" ? `{% for ${minijinjaIdent(loop.index ?? param)}, ${minijinjaIdent(param)} in ${array}|items %}` : loop.objectIteration === "keys" ? `{% for ${minijinjaIdent(param)}, __bf_v in ${array}|items %}` : loop.objectIteration === "values" ? `{% for __bf_k, ${minijinjaIdent(param)} in ${array}|items %}` : `{% for ${minijinjaIdent(loopVar)} in ${array} %}`;
@@ -6689,7 +6657,7 @@ ${name}="{{ bf.string(${val}) }}"
6689
6657
  if (ternaryDict !== null) {
6690
6658
  return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
6691
6659
  }
6692
- if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.loopBoundNames.has(trimmed)) {
6660
+ if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
6693
6661
  const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
6694
6662
  if (localConst?.value !== undefined) {
6695
6663
  const initTrimmed = localConst.value.trim();
@@ -6924,7 +6892,7 @@ Options:
6924
6892
  return this.booleanTypedProps.has(bare);
6925
6893
  }
6926
6894
  isLoopBoundName(name) {
6927
- return this.loopBoundNames.has(name);
6895
+ return this.scope.isBound(name);
6928
6896
  }
6929
6897
  shouldBoolStr(expr, name) {
6930
6898
  if (isExplicitStringCall(expr))
@@ -6932,7 +6900,7 @@ Options:
6932
6900
  return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
6933
6901
  }
6934
6902
  _resolveLiteralConst(name) {
6935
- if (this.staticLoopSourceBoundNames.has(name))
6903
+ if (this.scope.isBound(name))
6936
6904
  return null;
6937
6905
  const c = (this.localConstants ?? []).find((lc) => lc.name === name);
6938
6906
  if (c?.value === undefined)
@@ -6946,9 +6914,7 @@ Options:
6946
6914
  return null;
6947
6915
  }
6948
6916
  _resolveStaticRecordLiteral(objectName, key) {
6949
- if (this.staticLoopSourceBoundNames.has(objectName))
6950
- return null;
6951
- const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
6917
+ const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
6952
6918
  if (!hit)
6953
6919
  return null;
6954
6920
  return hit.kind === "number" ? hit.text : `'${escapeMinijinjaSingleQuoted(hit.text)}'`;