Kaynağa Gözat

test(extraction): cover the tsx/JSX value-ref read path

tsx is in VALUE_REF_LANGS and was exercised at scale by the excalidraw sweep
(tablerIconProps lives in icons.tsx), but those readers were normal expressions.
Add a unit test for the one tsx-specific path — a const read ONLY inside JSX
(`<Foo x={CONST}/>`), which depends on the reader-scan descending into the JSX
subtree — so it's locked against regression. Passes; no code change needed.
Note in the design doc that tsx needs no separate repo sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Colby McHenry 1 hafta önce
ebeveyn
işleme
4ca424785b

+ 19 - 0
__tests__/value-reference-edges.test.ts

@@ -98,6 +98,25 @@ describe('value-reference edges', () => {
     expect(valueRefReaders(cg, 'Module')).toEqual([]);
     expect(valueRefReaders(cg, 'Module')).toEqual([]);
   });
   });
 
 
+  it('edges readers that use the const only inside JSX (.tsx)', async () => {
+    // The tsx-specific path: the const is read ONLY inside JSX expressions, so
+    // the reader-scan must descend into the JSX subtree to find it.
+    fs.writeFileSync(
+      path.join(dir, 'widget.tsx'),
+      [
+        'export const THEME_TOKENS = { color: "red", size: 12 };',
+        'export function Label() {',
+        '  return <span style={{ color: THEME_TOKENS.color }}>hi</span>;',
+        '}',
+        'export const Box = () => <div data-size={THEME_TOKENS.size} />;',
+      ].join('\n'),
+    );
+    cg = index();
+    await cg.indexAll();
+
+    expect(valueRefReaders(cg, 'THEME_TOKENS')).toEqual(expect.arrayContaining(['Label', 'Box']));
+  });
+
   it('emits nothing when CODEGRAPH_VALUE_REFS=0', async () => {
   it('emits nothing when CODEGRAPH_VALUE_REFS=0', async () => {
     const prev = process.env.CODEGRAPH_VALUE_REFS;
     const prev = process.env.CODEGRAPH_VALUE_REFS;
     process.env.CODEGRAPH_VALUE_REFS = '0';
     process.env.CODEGRAPH_VALUE_REFS = '0';

+ 6 - 0
docs/design/value-reference-edges.md

@@ -68,6 +68,12 @@ Across S/M/L on both languages: node count never moved, the precision guards hel
 without value-refs. The only false positives ever seen were excalidraw's 23 (one bundled
 without value-refs. The only false positives ever seen were excalidraw's 23 (one bundled
 file, fixed by the shadow prune); no new FP class surfaced in JS.
 file, fixed by the shadow prune); no new FP class surfaced in JS.
 
 
+**`tsx` is covered by the TS rows** — excalidraw is a React/.tsx codebase, so the headline
+`tablerIconProps` (1→170) and most of its targets live in `.tsx` files. The one
+tsx-specific path — a const read *only* inside JSX (`<Foo x={CONST}/>`) — relies on the
+reader-scan descending into the JSX subtree; it's locked by a unit test
+(`value-reference-edges.test.ts`), so no separate tsx repo sweep is needed.
+
 **JavaScript note — CommonJS `require` bindings are targets, and that's correct.** JS edge
 **JavaScript note — CommonJS `require` bindings are targets, and that's correct.** JS edge
 growth (~4–5%) runs higher than TS (~0.7–1.6%) because `var x = require('…')` bindings and
 growth (~4–5%) runs higher than TS (~0.7–1.6%) because `var x = require('…')` bindings and
 module-level `var` state pass the distinctive-name gate and are read by same-file functions.
 module-level `var` state pass the distinctive-name gate and are read by same-file functions.