diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts index ab5ac590d905..30d665227159 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts @@ -279,17 +279,20 @@ function runWithEnvironment( validateNoSetStateInRender(hir).unwrap(); } - if (env.config.validateNoDerivedComputationsInEffects_exp) { + if ( + env.config.validateNoDerivedComputationsInEffects_exp && + env.outputMode === 'lint' + ) { env.logErrors(validateNoDerivedComputationsInEffects_exp(hir)); } else if (env.config.validateNoDerivedComputationsInEffects) { validateNoDerivedComputationsInEffects(hir); } - if (env.config.validateNoSetStateInEffects) { + if (env.config.validateNoSetStateInEffects && env.outputMode === 'lint') { env.logErrors(validateNoSetStateInEffects(hir, env)); } - if (env.config.validateNoJSXInTryStatements) { + if (env.config.validateNoJSXInTryStatements && env.outputMode === 'lint') { env.logErrors(validateNoJSXInTryStatement(hir)); } @@ -320,7 +323,11 @@ function runWithEnvironment( value: hir, }); - if (env.enableValidations && env.config.validateStaticComponents) { + if ( + env.enableValidations && + env.config.validateStaticComponents && + env.outputMode === 'lint' + ) { env.logErrors(validateStaticComponents(hir)); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index f6872da1117e..4a170cdbdf3e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -4026,6 +4026,7 @@ function lowerAssignment( pattern: { kind: 'ArrayPattern', items, + loc: lvalue.node.loc ?? GeneratedSource, }, }, value, @@ -4203,6 +4204,7 @@ function lowerAssignment( pattern: { kind: 'ObjectPattern', properties, + loc: lvalue.node.loc ?? GeneratedSource, }, }, value, diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index fe850f9a5381..c396f6b08813 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -694,11 +694,13 @@ export type SpreadPattern = { export type ArrayPattern = { kind: 'ArrayPattern'; items: Array; + loc: SourceLocation; }; export type ObjectPattern = { kind: 'ObjectPattern'; properties: Array; + loc: SourceLocation; }; export type ObjectPropertyKey = diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts index 5c98997953d0..a38256896b1a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts @@ -515,6 +515,7 @@ function emitDestructureProps( pattern: { kind: 'ObjectPattern', properties, + loc: GeneratedSource, }, kind: InstructionKind.Let, }, diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 0ab7934a1a6e..123a69afc21b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -702,7 +702,7 @@ function codegenReactiveScope( outputComments.push(name.name); if (!cx.hasDeclared(identifier)) { statements.push( - t.variableDeclaration('let', [t.variableDeclarator(name)]), + t.variableDeclaration('let', [createVariableDeclarator(name, null)]), ); } cacheLoads.push({name, index, value: wrapCacheDep(cx, name)}); @@ -1387,7 +1387,7 @@ function codegenInstructionNullable( suggestions: null, }); return createVariableDeclaration(instr.loc, 'const', [ - t.variableDeclarator(codegenLValue(cx, lvalue), value), + createVariableDeclarator(codegenLValue(cx, lvalue), value), ]); } case InstructionKind.Function: { @@ -1451,7 +1451,7 @@ function codegenInstructionNullable( suggestions: null, }); return createVariableDeclaration(instr.loc, 'let', [ - t.variableDeclarator(codegenLValue(cx, lvalue), value), + createVariableDeclarator(codegenLValue(cx, lvalue), value), ]); } case InstructionKind.Reassign: { @@ -1691,6 +1691,9 @@ function withLoc) => t.Node>( }; } +const createIdentifier = withLoc(t.identifier); +const createArrayPattern = withLoc(t.arrayPattern); +const createObjectPattern = withLoc(t.objectPattern); const createBinaryExpression = withLoc(t.binaryExpression); const createExpressionStatement = withLoc(t.expressionStatement); const _createLabelledStatement = withLoc(t.labeledStatement); @@ -1722,6 +1725,31 @@ const createTryStatement = withLoc(t.tryStatement); const createBreakStatement = withLoc(t.breakStatement); const createContinueStatement = withLoc(t.continueStatement); +function createVariableDeclarator( + id: t.LVal, + init?: t.Expression | null, +): t.VariableDeclarator { + const node = t.variableDeclarator(id, init); + + /* + * The variable declarator location is not preserved in HIR, however, we can use the + * start location of the id and the end location of the init to recreate the + * exact original variable declarator location. + * + * Or if init is null, we likely have a declaration without an initializer, so we can use the id.loc.end as the end location. + */ + if (id.loc && (init === null || init?.loc)) { + node.loc = { + start: id.loc.start, + end: init?.loc?.end ?? id.loc.end, + filename: id.loc.filename, + identifierName: undefined, + }; + } + + return node; +} + function createHookGuard( guard: ExternalFunction, context: ProgramContext, @@ -1829,7 +1857,7 @@ function codegenInstruction( ); } else { return createVariableDeclaration(instr.loc, 'const', [ - t.variableDeclarator( + createVariableDeclarator( convertIdentifier(instr.lvalue.identifier), expressionValue, ), @@ -2756,7 +2784,7 @@ function codegenArrayPattern( ): t.ArrayPattern { const hasHoles = !pattern.items.every(e => e.kind !== 'Hole'); if (hasHoles) { - const result = t.arrayPattern([]); + const result = createArrayPattern(pattern.loc, []); /* * Older versions of babel have a validation bug fixed by * https://github.com/babel/babel/pull/10917 @@ -2777,7 +2805,8 @@ function codegenArrayPattern( } return result; } else { - return t.arrayPattern( + return createArrayPattern( + pattern.loc, pattern.items.map(item => { if (item.kind === 'Hole') { return null; @@ -2797,7 +2826,8 @@ function codegenLValue( return codegenArrayPattern(cx, pattern); } case 'ObjectPattern': { - return t.objectPattern( + return createObjectPattern( + pattern.loc, pattern.properties.map(property => { if (property.kind === 'ObjectProperty') { const key = codegenObjectPropertyKey(cx, property.key); @@ -2916,7 +2946,7 @@ function convertIdentifier(identifier: Identifier): t.Identifier { suggestions: null, }, ); - return t.identifier(identifier.name.value); + return createIdentifier(identifier.loc, identifier.name.value); } function compareScopeDependency( diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateSourceLocations.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateSourceLocations.ts index d18902370937..cd357af70f66 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateSourceLocations.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateSourceLocations.ts @@ -27,7 +27,11 @@ import {Result} from '../Utils/Result'; /** * Some common node types that are important for coverage tracking. - * Based on istanbul-lib-instrument + * Based on istanbul-lib-instrument + some other common nodes we expect to be present in the generated AST. + * + * Note: For VariableDeclaration, VariableDeclarator, and Identifier, we enforce stricter validation + * that requires both the source location AND node type to match in the generated AST. This ensures + * that variable declarations maintain their structural integrity through compilation. */ const IMPORTANT_INSTRUMENTED_TYPES = new Set([ 'ArrowFunctionExpression', @@ -54,6 +58,14 @@ const IMPORTANT_INSTRUMENTED_TYPES = new Set([ 'LabeledStatement', 'ConditionalExpression', 'LogicalExpression', + + /** + * Note: these aren't important for coverage tracking, + * but we still want to track them to ensure we aren't regressing them when + * we fix the source location tracking for other nodes. + */ + 'VariableDeclaration', + 'Identifier', ]); /** @@ -114,10 +126,13 @@ export function validateSourceLocations( ): Result { const errors = new CompilerError(); - // Step 1: Collect important locations from the original source + /* + * Step 1: Collect important locations from the original source + * Note: Multiple node types can share the same location (e.g. VariableDeclarator and Identifier) + */ const importantOriginalLocations = new Map< string, - {loc: t.SourceLocation; nodeType: string} + {loc: t.SourceLocation; nodeTypes: Set} >(); func.traverse({ @@ -137,20 +152,31 @@ export function validateSourceLocations( // Collect the location if it exists if (node.loc) { const key = locationKey(node.loc); - importantOriginalLocations.set(key, { - loc: node.loc, - nodeType: node.type, - }); + const existing = importantOriginalLocations.get(key); + if (existing) { + existing.nodeTypes.add(node.type); + } else { + importantOriginalLocations.set(key, { + loc: node.loc, + nodeTypes: new Set([node.type]), + }); + } } }, }); - // Step 2: Collect all locations from the generated AST - const generatedLocations = new Set(); + // Step 2: Collect all locations from the generated AST with their node types + const generatedLocations = new Map>(); function collectGeneratedLocations(node: t.Node): void { if (node.loc) { - generatedLocations.add(locationKey(node.loc)); + const key = locationKey(node.loc); + const nodeTypes = generatedLocations.get(key); + if (nodeTypes) { + nodeTypes.add(node.type); + } else { + generatedLocations.set(key, new Set([node.type])); + } } // Use Babel's VISITOR_KEYS to traverse only actual node properties @@ -183,22 +209,86 @@ export function validateSourceLocations( collectGeneratedLocations(outlined.fn.body); } - // Step 3: Validate that all important locations are preserved - for (const [key, {loc, nodeType}] of importantOriginalLocations) { - if (!generatedLocations.has(key)) { - errors.pushDiagnostic( - CompilerDiagnostic.create({ - category: ErrorCategory.Todo, - reason: 'Important source location missing in generated code', - description: - `Source location for ${nodeType} is missing in the generated output. This can cause coverage instrumentation ` + - `to fail to track this code properly, resulting in inaccurate coverage reports.`, - }).withDetails({ - kind: 'error', - loc, - message: null, - }), - ); + /* + * Step 3: Validate that all important locations are preserved + * For certain node types, also validate that the node type matches + */ + const strictNodeTypes = new Set([ + 'VariableDeclaration', + 'VariableDeclarator', + 'Identifier', + ]); + + const reportMissingLocation = ( + loc: t.SourceLocation, + nodeType: string, + ): void => { + errors.pushDiagnostic( + CompilerDiagnostic.create({ + category: ErrorCategory.Todo, + reason: 'Important source location missing in generated code', + description: + `Source location for ${nodeType} is missing in the generated output. This can cause coverage instrumentation ` + + `to fail to track this code properly, resulting in inaccurate coverage reports.`, + }).withDetails({ + kind: 'error', + loc, + message: null, + }), + ); + }; + + const reportWrongNodeType = ( + loc: t.SourceLocation, + expectedType: string, + actualTypes: Set, + ): void => { + errors.pushDiagnostic( + CompilerDiagnostic.create({ + category: ErrorCategory.Todo, + reason: + 'Important source location has wrong node type in generated code', + description: + `Source location for ${expectedType} exists in the generated output but with wrong node type(s): ${Array.from(actualTypes).join(', ')}. ` + + `This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.`, + }).withDetails({ + kind: 'error', + loc, + message: null, + }), + ); + }; + + for (const [key, {loc, nodeTypes}] of importantOriginalLocations) { + const generatedNodeTypes = generatedLocations.get(key); + + if (!generatedNodeTypes) { + // Location is completely missing + reportMissingLocation(loc, Array.from(nodeTypes).join(', ')); + } else { + // Location exists, check each node type + for (const nodeType of nodeTypes) { + if ( + strictNodeTypes.has(nodeType) && + !generatedNodeTypes.has(nodeType) + ) { + /* + * For strict node types, the specific node type must be present + * Check if any generated node type is also an important original node type + */ + const hasValidNodeType = Array.from(generatedNodeTypes).some( + genType => nodeTypes.has(genType), + ); + + if (hasValidNodeType) { + // At least one generated node type is valid (also in original), so this is just missing + reportMissingLocation(loc, nodeType); + } else { + // None of the generated node types are in original - this is wrong node type + reportWrongNodeType(loc, nodeType, generatedNodeTypes); + } + } + } } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver-and-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver-and-mutate.expect.md index 0b03ac997895..eb2d451c564c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver-and-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver-and-mutate.expect.md @@ -35,10 +35,8 @@ function Component() { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const a = makeObject_Primitives(); - const x = []; x.push(a); - mutate(x); t0 = [x, a]; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver.expect.md index 2b9efc0f4a69..b7b89dc1a1da 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/alias-capture-in-method-receiver.expect.md @@ -33,7 +33,6 @@ function Component() { if ($[1] === Symbol.for("react.memo_cache_sentinel")) { const x = []; x.push(a); - t1 = [x, a]; $[1] = t1; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-fn-expr.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-fn-expr.expect.md index b30ee7e0d681..e91766e79c5c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-fn-expr.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-fn-expr.expect.md @@ -85,14 +85,10 @@ function Component(t0) { let t1; if ($[0] !== prop) { const obj = shallowCopy(prop); - const aliasedObj = identity(obj); - const getId = () => obj.id; - mutate(aliasedObj); setPropertyByKey(aliasedObj, "id", prop.id + 1); - t1 = ; $[0] = prop; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md index 12c7b4d5eab9..a44c3a1a5dea 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md @@ -181,12 +181,9 @@ function Component(t0) { if ($[0] !== prop) { const obj = shallowCopy(prop); const aliasedObj = identity(obj); - const id = [obj.id]; - mutate(aliasedObj); setPropertyByKey(aliasedObj, "id", prop.id + 1); - t1 = ; $[0] = prop; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/align-scopes-within-nested-valueblock-in-array.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/align-scopes-within-nested-valueblock-in-array.expect.md index 97b3bb13d701..aff7a2e7b999 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/align-scopes-within-nested-valueblock-in-array.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/align-scopes-within-nested-valueblock-in-array.expect.md @@ -54,7 +54,6 @@ function Foo(t0) { let t1; if ($[0] !== cond1 || $[1] !== cond2) { const arr = makeArray({ a: 2 }, 2, []); - t1 = cond1 ? ( <>
{identity("foo")}
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-in-callback-passed-to-jsx-indirect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-in-callback-passed-to-jsx-indirect.expect.md index 70320c376274..b39077c9535f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-in-callback-passed-to-jsx-indirect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-in-callback-passed-to-jsx-indirect.expect.md @@ -49,7 +49,6 @@ function Component() { ref.current = ""; } }; - t0 = () => { setRef(); }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-property-in-callback-passed-to-jsx-indirect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-property-in-callback-passed-to-jsx-indirect.expect.md index 4c979728f685..37407b5cd0be 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-property-in-callback-passed-to-jsx-indirect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-mutating-ref-property-in-callback-passed-to-jsx-indirect.expect.md @@ -49,7 +49,6 @@ function Component() { ref.current.value = ""; } }; - t0 = () => { setRef(); }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-access-in-event-handler-wrapper.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-access-in-event-handler-wrapper.expect.md index d40a1e080ad3..5a2727965879 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-access-in-event-handler-wrapper.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-access-in-event-handler-wrapper.expect.md @@ -74,7 +74,6 @@ function Component() { console.log(ref.current.value); } }; - t0 = ( <> diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.expect.md index 56e3039f63ce..ee7a71e8f8a9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.expect.md @@ -36,7 +36,6 @@ function useArrayOfRef() { const callback = (value) => { ref.current = value; }; - t0 = [callback]; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-at-closure.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-at-closure.expect.md index 810f1a3f5e4e..cd782c3f791b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-at-closure.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-at-closure.expect.md @@ -35,7 +35,6 @@ function Component(props) { const arr = [...bar(props)]; return arr.at(x); }; - t1 = fn(); $[2] = props; $[3] = x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-spread-mutable-iterator.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-spread-mutable-iterator.expect.md index 25499af1b020..7aa0702d470b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-spread-mutable-iterator.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-spread-mutable-iterator.expect.md @@ -61,7 +61,6 @@ function useBar(t0) { if ($[0] !== arg) { const s = new Set([1, 5, 4]); const mutableIterator = s.values(); - t1 = [arg, ...mutableIterator]; $[0] = arg; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/call.expect.md index b0bd96c2bf26..4482eab8e6a2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/call.expect.md @@ -28,7 +28,6 @@ function Component(props) { const a = []; const b = {}; foo(a, b); - foo(b); t0 =
; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capture-ref-for-later-mutation.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capture-ref-for-later-mutation.expect.md index 223823621d0b..158d31faca27 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capture-ref-for-later-mutation.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capture-ref-for-later-mutation.expect.md @@ -45,7 +45,6 @@ function useKeyCommand() { const nextPosition = direction === "left" ? addOne(position) : position; currentPosition.current = nextPosition; }; - const moveLeft = { handler: handleKey("left") }; const moveRight = { handler: handleKey("right") }; t0 = [moveLeft, moveRight]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-func-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-func-mutate.expect.md index fcde7d675c84..03c0db7e971c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-func-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-func-mutate.expect.md @@ -45,7 +45,6 @@ function Component(t0) { z.a = 2; mutate(y.b); }; - x(); t1 = [y, z]; $[0] = a; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-emit-make-read-only.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-emit-make-read-only.expect.md index ba9e39e691b0..602e49672e26 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-emit-make-read-only.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-emit-make-read-only.expect.md @@ -29,7 +29,6 @@ function MyComponentName(props) { const x = {}; foo(x, props.a); foo(x, props.b); - y = []; y.push(x); $[0] = props.a; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-reassign.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-reassign.expect.md index b7288a854ffe..0778152f341d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-reassign.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-reassign.expect.md @@ -34,7 +34,6 @@ function useTest() { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { let w = {}; - const t1 = (w = 42); const t2 = w; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-storeprop.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-storeprop.expect.md index 85a66bb204cb..7310e0fcd26a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-storeprop.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/codegen-inline-iife-storeprop.expect.md @@ -34,7 +34,6 @@ function useTest() { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const w = {}; - const t1 = (w.x = 42); const t2 = w.x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/conditional-on-mutable.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/conditional-on-mutable.expect.md index f855f2231d03..0bcaf60a8e67 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/conditional-on-mutable.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/conditional-on-mutable.expect.md @@ -44,11 +44,9 @@ function ComponentA(props) { if (b) { a.push(props.p0); } - if (props.p1) { b.push(props.p2); } - t0 = ; $[0] = props.p0; $[1] = props.p1; @@ -69,11 +67,9 @@ function ComponentB(props) { if (mayMutate(b)) { a.push(props.p0); } - if (props.p1) { b.push(props.p2); } - t0 = ; $[0] = props.p0; $[1] = props.p1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constructor.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constructor.expect.md index 6a01460e009b..bfa6c8307128 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constructor.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constructor.expect.md @@ -28,7 +28,6 @@ function Component(props) { const a = []; const b = {}; new Foo(a, b); - new Foo(b); t0 =
; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-reassigned-outside-of-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-reassigned-outside-of-lambda.expect.md index 2edb60a5a2b2..08b92e940fcb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-reassigned-outside-of-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-reassigned-outside-of-lambda.expect.md @@ -34,7 +34,6 @@ function Component(props) { const callback = () => { console.log(x); }; - x = {}; t0 = ; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md index 17dd0f835942..3a8f9e84cac1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md @@ -75,7 +75,6 @@ function Component(props) { let t0; if ($[0] !== post) { const allUrls = []; - const { media: t1, comments: t2, urls: t3 } = post; const media = t1 === undefined ? null : t1; let t4; @@ -102,7 +101,6 @@ function Component(props) { if (!comments.length) { return; } - console.log(comments.length); }; $[6] = comments.length; @@ -111,7 +109,6 @@ function Component(props) { t6 = $[7]; } const onClick = t6; - allUrls.push(...urls); t0 = ; $[0] = post; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md index f69149aba417..fbb6e50871dc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md @@ -53,7 +53,6 @@ function Component(props) { let t0; if ($[0] !== post) { const allUrls = []; - const { media, comments, urls } = post; let t1; if ($[2] !== comments.length) { @@ -61,7 +60,6 @@ function Component(props) { if (!comments.length) { return; } - console.log(comments.length); }; $[2] = comments.length; @@ -70,7 +68,6 @@ function Component(props) { t1 = $[3]; } const onClick = t1; - allUrls.push(...urls); t0 = ; $[0] = post; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-if-dep-is-inner-declaration-of-previous-scope.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-if-dep-is-inner-declaration-of-previous-scope.expect.md index 58013c156084..ce5bfda64406 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-if-dep-is-inner-declaration-of-previous-scope.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-if-dep-is-inner-declaration-of-previous-scope.expect.md @@ -57,7 +57,6 @@ function Component(t0) { let y; if ($[0] !== a || $[1] !== b || $[2] !== c) { x = []; - if (a) { let t1; if ($[5] !== b) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.expect.md index 756a219e645a..fa5ae370e67e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({value, enabled}) { @@ -29,43 +29,21 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(6); - const { value, enabled } = t0; +function Component({ value, enabled }) { const [localValue, setLocalValue] = useState(""); - let t1; - let t2; - if ($[0] !== enabled || $[1] !== value) { - t1 = () => { - if (enabled) { - setLocalValue(value); - } else { - setLocalValue("disabled"); - } - }; - - t2 = [value, enabled]; - $[0] = enabled; - $[1] = value; - $[2] = t1; - $[3] = t2; - } else { - t1 = $[2]; - t2 = $[3]; - } - useEffect(t1, t2); - let t3; - if ($[4] !== localValue) { - t3 =
{localValue}
; - $[4] = localValue; - $[5] = t3; - } else { - t3 = $[5]; - } - return t3; + + useEffect(() => { + if (enabled) { + setLocalValue(value); + } else { + setLocalValue("disabled"); + } + }, [value, enabled]); + + return
{localValue}
; } export const FIXTURE_ENTRYPOINT = { @@ -78,8 +56,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [value]\n\nData Flow Tree:\n└── value (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":6,"index":244},"end":{"line":9,"column":19,"index":257},"filename":"derived-state-conditionally-in-effect.ts","identifierName":"setLocalValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":16,"column":1,"index":378},"filename":"derived-state-conditionally-in-effect.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [value]\n\nData Flow Tree:\n└── value (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":6,"index":263},"end":{"line":9,"column":19,"index":276},"filename":"derived-state-conditionally-in-effect.ts","identifierName":"setLocalValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":16,"column":1,"index":397},"filename":"derived-state-conditionally-in-effect.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.js index fb65cbfeb82b..4cdcb53bb236 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-conditionally-in-effect.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({value, enabled}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.expect.md index 2f3a3d0e6160..4db10f4df4cf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component({input = 'empty'}) { @@ -26,38 +26,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -export default function Component(t0) { - const $ = _c(5); - const { input: t1 } = t0; - const input = t1 === undefined ? "empty" : t1; +export default function Component({ input = "empty" }) { const [currInput, setCurrInput] = useState(input); - let t2; - let t3; - if ($[0] !== input) { - t2 = () => { - setCurrInput(input + "local const"); - }; - t3 = [input, "local const"]; - $[0] = input; - $[1] = t2; - $[2] = t3; - } else { - t2 = $[1]; - t3 = $[2]; - } - useEffect(t2, t3); - let t4; - if ($[3] !== currInput) { - t4 =
{currInput}
; - $[3] = currInput; - $[4] = t4; - } else { - t4 = $[4]; - } - return t4; + const localConst = "local const"; + + useEffect(() => { + setCurrInput(input + localConst); + }, [input, localConst]); + + return
{currInput}
; } export const FIXTURE_ENTRYPOINT = { @@ -70,8 +50,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [input]\n\nData Flow Tree:\n└── input (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":4,"index":276},"end":{"line":9,"column":16,"index":288},"filename":"derived-state-from-default-props.ts","identifierName":"setCurrInput"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":122},"end":{"line":13,"column":1,"index":372},"filename":"derived-state-from-default-props.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [input]\n\nData Flow Tree:\n└── input (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":4,"index":295},"end":{"line":9,"column":16,"index":307},"filename":"derived-state-from-default-props.ts","identifierName":"setCurrInput"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":141},"end":{"line":13,"column":1,"index":391},"filename":"derived-state-from-default-props.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.js index 1de911c9b379..9d559946bead 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-default-props.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component({input = 'empty'}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.expect.md index 37458dcea06c..afddca39e9a7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; @@ -23,45 +23,20 @@ function Component({shouldChange}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(7); - const { shouldChange } = t0; +function Component({ shouldChange }) { const [count, setCount] = useState(0); - let t1; - if ($[0] !== count || $[1] !== shouldChange) { - t1 = () => { - if (shouldChange) { - setCount(count + 1); - } - }; - $[0] = count; - $[1] = shouldChange; - $[2] = t1; - } else { - t1 = $[2]; - } - let t2; - if ($[3] !== count) { - t2 = [count]; - $[3] = count; - $[4] = t2; - } else { - t2 = $[4]; - } - useEffect(t1, t2); - let t3; - if ($[5] !== count) { - t3 =
{count}
; - $[5] = count; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + + useEffect(() => { + if (shouldChange) { + setCount(count + 1); + } + }, [count]); + + return
{count}
; } ``` @@ -69,8 +44,8 @@ function Component(t0) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [count]\n\nData Flow Tree:\n└── count (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":10,"column":6,"index":237},"end":{"line":10,"column":14,"index":245},"filename":"derived-state-from-local-state-in-effect.ts","identifierName":"setCount"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":108},"end":{"line":15,"column":1,"index":310},"filename":"derived-state-from-local-state-in-effect.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [count]\n\nData Flow Tree:\n└── count (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":10,"column":6,"index":256},"end":{"line":10,"column":14,"index":264},"filename":"derived-state-from-local-state-in-effect.ts","identifierName":"setCount"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":127},"end":{"line":15,"column":1,"index":329},"filename":"derived-state-from-local-state-in-effect.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.js index 79e65e4849a9..db84ab8be45f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-local-state-in-effect.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.expect.md index fdcbccd3de5b..e1c33a6c73f4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({firstName}) { @@ -33,68 +33,25 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(12); - const { firstName } = t0; +function Component({ firstName }) { const [lastName, setLastName] = useState("Doe"); const [fullName, setFullName] = useState("John"); - let t1; - let t2; - if ($[0] !== firstName || $[1] !== lastName) { - t1 = () => { - setFullName(firstName + " " + "D." + " " + lastName); - }; - t2 = [firstName, "D.", lastName]; - $[0] = firstName; - $[1] = lastName; - $[2] = t1; - $[3] = t2; - } else { - t1 = $[2]; - t2 = $[3]; - } - useEffect(t1, t2); - let t3; - if ($[4] === Symbol.for("react.memo_cache_sentinel")) { - t3 = (e) => setLastName(e.target.value); - $[4] = t3; - } else { - t3 = $[4]; - } - let t4; - if ($[5] !== lastName) { - t4 = ; - $[5] = lastName; - $[6] = t4; - } else { - t4 = $[6]; - } - let t5; - if ($[7] !== fullName) { - t5 =
{fullName}
; - $[7] = fullName; - $[8] = t5; - } else { - t5 = $[8]; - } - let t6; - if ($[9] !== t4 || $[10] !== t5) { - t6 = ( -
- {t4} - {t5} -
- ); - $[9] = t4; - $[10] = t5; - $[11] = t6; - } else { - t6 = $[11]; - } - return t6; + + const middleName = "D."; + + useEffect(() => { + setFullName(firstName + " " + middleName + " " + lastName); + }, [firstName, middleName, lastName]); + + return ( +
+ setLastName(e.target.value)} /> +
{fullName}
+
+ ); } export const FIXTURE_ENTRYPOINT = { @@ -107,8 +64,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [firstName]\nState: [lastName]\n\nData Flow Tree:\n├── firstName (Prop)\n└── lastName (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":11,"column":4,"index":297},"end":{"line":11,"column":15,"index":308},"filename":"derived-state-from-prop-local-state-and-component-scope.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":20,"column":1,"index":542},"filename":"derived-state-from-prop-local-state-and-component-scope.ts"},"fnName":"Component","memoSlots":12,"memoBlocks":5,"memoValues":6,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [firstName]\nState: [lastName]\n\nData Flow Tree:\n├── firstName (Prop)\n└── lastName (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":11,"column":4,"index":316},"end":{"line":11,"column":15,"index":327},"filename":"derived-state-from-prop-local-state-and-component-scope.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":20,"column":1,"index":561},"filename":"derived-state-from-prop-local-state-and-component-scope.ts"},"fnName":"Component","memoSlots":12,"memoBlocks":5,"memoValues":6,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.js index f25e20863d33..31b77d148171 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-local-state-and-component-scope.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({firstName}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.expect.md index 698148254500..960cf987d4ee 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({initialName}) { @@ -29,48 +29,21 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(6); - const { initialName } = t0; +function Component({ initialName }) { const [name, setName] = useState(""); - let t1; - let t2; - if ($[0] !== initialName) { - t1 = () => { - setName(initialName); - }; - t2 = [initialName]; - $[0] = initialName; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t3 = (e) => setName(e.target.value); - $[3] = t3; - } else { - t3 = $[3]; - } - let t4; - if ($[4] !== name) { - t4 = ( -
- -
- ); - $[4] = name; - $[5] = t4; - } else { - t4 = $[5]; - } - return t4; + + useEffect(() => { + setName(initialName); + }, [initialName]); + + return ( +
+ setName(e.target.value)} /> +
+ ); } export const FIXTURE_ENTRYPOINT = { @@ -83,7 +56,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":16,"column":1,"index":359},"filename":"derived-state-from-prop-setter-call-outside-effect-no-error.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":3,"memoValues":4,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":16,"column":1,"index":378},"filename":"derived-state-from-prop-setter-call-outside-effect-no-error.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":3,"memoValues":4,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.js index 6df5f2eed6f9..e454caf2ec81 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-call-outside-effect-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({initialName}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.expect.md index 48811aa5a943..226a3938bd7d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp +// @validateNoDerivedComputationsInEffects_exp @outputMode:"lint" function Component({value}) { const [checked, setChecked] = useState(''); @@ -19,36 +19,16 @@ function Component({value}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp +// @validateNoDerivedComputationsInEffects_exp @outputMode:"lint" -function Component(t0) { - const $ = _c(5); - const { value } = t0; +function Component({ value }) { const [checked, setChecked] = useState(""); - let t1; - let t2; - if ($[0] !== value) { - t1 = () => { - setChecked(value === "" ? [] : value.split(",")); - }; - t2 = [value]; - $[0] = value; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== checked) { - t3 =
{checked}
; - $[3] = checked; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + + useEffect(() => { + setChecked(value === "" ? [] : value.split(",")); + }, [value]); + + return
{checked}
; } ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.js index afd198caa262..1c020d3015d1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-ternary.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp +// @validateNoDerivedComputationsInEffects_exp @outputMode:"lint" function Component({value}) { const [checked, setChecked] = useState(''); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.expect.md index b5100dc2a633..de184ede6394 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function MockComponent({onSet}) { @@ -28,50 +28,20 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function MockComponent(t0) { - const $ = _c(2); - const { onSet } = t0; - let t1; - if ($[0] !== onSet) { - t1 =
onSet("clicked")}>Mock Component
; - $[0] = onSet; - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; +function MockComponent({ onSet }) { + return
onSet("clicked")}>Mock Component
; } -function Component(t0) { - const $ = _c(4); - const { propValue } = t0; - const [, setValue] = useState(null); - let t1; - let t2; - if ($[0] !== propValue) { - t1 = () => { - setValue(propValue); - }; - t2 = [propValue]; - $[0] = propValue; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t3 = ; - $[3] = t3; - } else { - t3 = $[3]; - } - return t3; +function Component({ propValue }) { + const [value, setValue] = useState(null); + useEffect(() => { + setValue(propValue); + }, [propValue]); + + return ; } export const FIXTURE_ENTRYPOINT = { @@ -84,8 +54,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":6,"column":1,"index":211},"filename":"derived-state-from-prop-setter-used-outside-effect-no-error.ts"},"fnName":"MockComponent","memoSlots":2,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":8,"column":0,"index":213},"end":{"line":15,"column":1,"index":402},"filename":"derived-state-from-prop-setter-used-outside-effect-no-error.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":6,"column":1,"index":230},"filename":"derived-state-from-prop-setter-used-outside-effect-no-error.ts"},"fnName":"MockComponent","memoSlots":2,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":8,"column":0,"index":232},"end":{"line":15,"column":1,"index":421},"filename":"derived-state-from-prop-setter-used-outside-effect-no-error.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.js index 43b5a8c52ada..879d582c924d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-setter-used-outside-effect-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function MockComponent({onSet}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.expect.md index 0160fbbb4a71..fc4d86a3f292 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({value}) { @@ -26,38 +26,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(5); - const { value } = t0; +function Component({ value }) { const [localValue, setLocalValue] = useState(""); - let t1; - let t2; - if ($[0] !== value) { - t1 = () => { - setLocalValue(value); - document.title = `Value: ${value}`; - }; - t2 = [value]; - $[0] = value; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== localValue) { - t3 =
{localValue}
; - $[3] = localValue; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + + useEffect(() => { + setLocalValue(value); + document.title = `Value: ${value}`; + }, [value]); + + return
{localValue}
; } export const FIXTURE_ENTRYPOINT = { @@ -70,8 +50,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [value]\n\nData Flow Tree:\n└── value (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":8,"column":4,"index":214},"end":{"line":8,"column":17,"index":227},"filename":"derived-state-from-prop-with-side-effect.ts","identifierName":"setLocalValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":13,"column":1,"index":327},"filename":"derived-state-from-prop-with-side-effect.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [value]\n\nData Flow Tree:\n└── value (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":8,"column":4,"index":233},"end":{"line":8,"column":17,"index":246},"filename":"derived-state-from-prop-with-side-effect.ts","identifierName":"setLocalValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":13,"column":1,"index":346},"filename":"derived-state-from-prop-with-side-effect.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.js index 5bb963daac32..b6cebdb40807 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-prop-with-side-effect.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({value}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.expect.md index e88d5833a9a1..f11a4b26b533 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState, useRef} from 'react'; export default function Component({test}) { @@ -27,39 +27,19 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState, useRef } from "react"; -export default function Component(t0) { - const $ = _c(5); - const { test } = t0; +export default function Component({ test }) { const [local, setLocal] = useState(""); const myRef = useRef(null); - let t1; - let t2; - if ($[0] !== test) { - t1 = () => { - setLocal(myRef.current + test); - }; - t2 = [test]; - $[0] = test; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== local) { - t3 = <>{local}; - $[3] = local; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + + useEffect(() => { + setLocal(myRef.current + test); + }, [test]); + + return <>{local}; } export const FIXTURE_ENTRYPOINT = { @@ -72,7 +52,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":130},"end":{"line":14,"column":1,"index":328},"filename":"derived-state-from-ref-and-state-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":149},"end":{"line":14,"column":1,"index":347},"filename":"derived-state-from-ref-and-state-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.js index 18ad2bdca19f..9425aee24419 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/derived-state-from-ref-and-state-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState, useRef} from 'react'; export default function Component({test}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.expect.md index fdc7081f3758..080aa8e04dcd 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue}) { @@ -30,48 +30,22 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(6); - const { propValue } = t0; +function Component({ propValue }) { const [value, setValue] = useState(null); - let t1; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t1 = function localFunction() { - console.log("local function"); - }; - $[0] = t1; - } else { - t1 = $[0]; - } - const localFunction = t1; - let t2; - let t3; - if ($[1] !== propValue) { - t2 = () => { - setValue(propValue); - localFunction(); - }; - t3 = [propValue]; - $[1] = propValue; - $[2] = t2; - $[3] = t3; - } else { - t2 = $[2]; - t3 = $[3]; - } - useEffect(t2, t3); - let t4; - if ($[4] !== value) { - t4 =
{value}
; - $[4] = value; - $[5] = t4; - } else { - t4 = $[5]; + + function localFunction() { + console.log("local function"); } - return t4; + + useEffect(() => { + setValue(propValue); + localFunction(); + }, [propValue]); + + return
{value}
; } export const FIXTURE_ENTRYPOINT = { @@ -84,8 +58,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [propValue]\n\nData Flow Tree:\n└── propValue (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":12,"column":4,"index":279},"end":{"line":12,"column":12,"index":287},"filename":"effect-contains-local-function-call.ts","identifierName":"setValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":17,"column":1,"index":371},"filename":"effect-contains-local-function-call.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":3,"memoValues":4,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [propValue]\n\nData Flow Tree:\n└── propValue (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":12,"column":4,"index":298},"end":{"line":12,"column":12,"index":306},"filename":"effect-contains-local-function-call.ts","identifierName":"setValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":17,"column":1,"index":390},"filename":"effect-contains-local-function-call.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":3,"memoValues":4,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.js index a6442b36477f..3eabb40feeb6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-local-function-call.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md index 74391e86ad37..374877863dd3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue, onChange}) { @@ -25,43 +25,17 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(7); - const { propValue, onChange } = t0; +function Component({ propValue, onChange }) { const [value, setValue] = useState(null); - let t1; - if ($[0] !== onChange || $[1] !== propValue) { - t1 = () => { - setValue(propValue); - onChange(); - }; - $[0] = onChange; - $[1] = propValue; - $[2] = t1; - } else { - t1 = $[2]; - } - let t2; - if ($[3] !== propValue) { - t2 = [propValue]; - $[3] = propValue; - $[4] = t2; - } else { - t2 = $[4]; - } - useEffect(t1, t2); - let t3; - if ($[5] !== value) { - t3 =
{value}
; - $[5] = value; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + useEffect(() => { + setValue(propValue); + onChange(); + }, [propValue]); + + return
{value}
; } export const FIXTURE_ENTRYPOINT = { @@ -74,8 +48,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":12,"column":1,"index":306},"filename":"effect-contains-prop-function-call-no-error.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":16,"column":41,"index":402},"end":{"line":16,"column":49,"index":410},"filename":"effect-contains-prop-function-call-no-error.ts"},"fnName":null,"memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":12,"column":1,"index":325},"filename":"effect-contains-prop-function-call-no-error.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":16,"column":41,"index":421},"end":{"line":16,"column":49,"index":429},"filename":"effect-contains-prop-function-call-no-error.ts"},"fnName":null,"memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js index f19e9518d6fa..c9c9778ab844 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue, onChange}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.expect.md index 6a3593a3b27c..1bd8fa23faa7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component({prop}) { const [s, setS] = useState(0); @@ -18,36 +18,15 @@ function Component({prop}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly - -function Component(t0) { - const $ = _c(5); - const { prop } = t0; - const [, setS] = useState(0); - let t1; - let t2; - if ($[0] !== prop) { - t1 = () => { - setS(prop); - }; - t2 = [prop, setS]; - $[0] = prop; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== prop) { - t3 =
{prop}
; - $[3] = prop; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" + +function Component({ prop }) { + const [s, setS] = useState(0); + useEffect(() => { + setS(prop); + }, [prop, setS]); + + return
{prop}
; } ``` @@ -55,8 +34,8 @@ function Component(t0) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [prop]\n\nData Flow Tree:\n└── prop (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":6,"column":4,"index":150},"end":{"line":6,"column":8,"index":154},"filename":"effect-used-in-dep-array-still-errors.ts","identifierName":"setS"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":64},"end":{"line":10,"column":1,"index":212},"filename":"effect-used-in-dep-array-still-errors.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [prop]\n\nData Flow Tree:\n└── prop (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":6,"column":4,"index":169},"end":{"line":6,"column":8,"index":173},"filename":"effect-used-in-dep-array-still-errors.ts","identifierName":"setS"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":83},"end":{"line":10,"column":1,"index":231},"filename":"effect-used-in-dep-array-still-errors.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.js index 1df99a191dcf..bf48efbbc100 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-used-in-dep-array-still-errors.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component({prop}) { const [s, setS] = useState(0); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.expect.md index e84031591e07..ac72a4414844 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; @@ -29,39 +29,26 @@ function Component(file: File) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(file) { - const $ = _c(5); +function Component(file: File) { const [imageUrl, setImageUrl] = useState(null); - let t0; - let t1; - if ($[0] !== file) { - t0 = () => { - const imageUrlPrepared = URL.createObjectURL(file); - setImageUrl(imageUrlPrepared); - return () => URL.revokeObjectURL(imageUrlPrepared); - }; - t1 = [file]; - $[0] = file; - $[1] = t0; - $[2] = t1; - } else { - t0 = $[1]; - t1 = $[2]; - } - useEffect(t0, t1); - let t2; - if ($[3] !== imageUrl) { - t2 = ; - $[3] = imageUrl; - $[4] = t2; - } else { - t2 = $[4]; - } - return t2; + + /* + * Cleaning up the variable or a source of the variable used to setState + * inside the effect communicates that we always need to clean up something + * which is a valid use case for useEffect. In which case we want to + * avoid an throwing + */ + useEffect(() => { + const imageUrlPrepared = URL.createObjectURL(file); + setImageUrl(imageUrlPrepared); + return () => URL.revokeObjectURL(imageUrlPrepared); + }, [file]); + + return ; } ``` @@ -69,7 +56,7 @@ function Component(file) { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":108},"end":{"line":21,"column":1,"index":700},"filename":"effect-with-cleanup-function-depending-on-derived-computation-value.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":127},"end":{"line":21,"column":1,"index":719},"filename":"effect-with-cleanup-function-depending-on-derived-computation-value.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.js index e419583cc6dd..16e52562bd83 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-cleanup-function-depending-on-derived-computation-value.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.expect.md index e26643723d98..58328b2e9597 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue}) { @@ -25,38 +25,17 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -function Component(t0) { - const $ = _c(5); - const { propValue } = t0; +function Component({ propValue }) { const [value, setValue] = useState(null); - let t1; - let t2; - if ($[0] !== propValue) { - t1 = () => { - setValue(propValue); - globalCall(); - }; - t2 = [propValue]; - $[0] = propValue; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== value) { - t3 =
{value}
; - $[3] = value; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + useEffect(() => { + setValue(propValue); + globalCall(); + }, [propValue]); + + return
{value}
; } export const FIXTURE_ENTRYPOINT = { @@ -69,7 +48,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":12,"column":1,"index":298},"filename":"effect-with-global-function-call-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":12,"column":1,"index":317},"filename":"effect-with-global-function-call-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.js index ae7622d4d064..565e23bb0fe3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-with-global-function-call-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component({propValue}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.expect.md index f23f51d6cb8b..7ba22f518642 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly @outputMode:"lint" function Component({setParentState, prop}) { useEffect(() => { @@ -17,40 +17,14 @@ function Component({setParentState, prop}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly @outputMode:"lint" -function Component(t0) { - const $ = _c(7); - const { setParentState, prop } = t0; - let t1; - if ($[0] !== prop || $[1] !== setParentState) { - t1 = () => { - setParentState(prop); - }; - $[0] = prop; - $[1] = setParentState; - $[2] = t1; - } else { - t1 = $[2]; - } - let t2; - if ($[3] !== prop) { - t2 = [prop]; - $[3] = prop; - $[4] = t2; - } else { - t2 = $[4]; - } - useEffect(t1, t2); - let t3; - if ($[5] !== prop) { - t3 =
{prop}
; - $[5] = prop; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; +function Component({ setParentState, prop }) { + useEffect(() => { + setParentState(prop); + }, [prop]); + + return
{prop}
; } ``` @@ -58,7 +32,7 @@ function Component(t0) { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":105},"end":{"line":9,"column":1,"index":240},"filename":"from-props-setstate-in-effect-no-error.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":124},"end":{"line":9,"column":1,"index":259},"filename":"from-props-setstate-in-effect-no-error.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.js index 4075975b3254..1754209d8371 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/from-props-setstate-in-effect-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @enableTreatSetIdentifiersAsStateSetters @loggerTestOnly @outputMode:"lint" function Component({setParentState, prop}) { useEffect(() => { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.expect.md index 4e0ff4e2394d..c1b99a95ab89 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component() { const [foo, setFoo] = useState({}); @@ -40,66 +40,37 @@ function Component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component() { - const $ = _c(9); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = {}; - $[0] = t0; - } else { - t0 = $[0]; - } - const [foo, setFoo] = useState(t0); - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = new Set(); - $[1] = t1; - } else { - t1 = $[1]; - } - const [bar] = useState(t1); - let t2; - let t3; - if ($[2] !== bar || $[3] !== foo) { - t2 = () => { - let isChanged = false; - - const newData = foo.map((val) => { - bar.someMethod(val); - isChanged = true; - }); - - if (isChanged) { - setFoo(newData); - } - }; - - t3 = [foo, bar]; - $[2] = bar; - $[3] = foo; - $[4] = t2; - $[5] = t3; - } else { - t2 = $[4]; - t3 = $[5]; - } - useEffect(t2, t3); - let t4; - if ($[6] !== bar || $[7] !== foo) { - t4 = ( -
- {foo}, {bar} -
- ); - $[6] = bar; - $[7] = foo; - $[8] = t4; - } else { - t4 = $[8]; - } - return t4; + const [foo, setFoo] = useState({}); + const [bar, setBar] = useState(new Set()); + + /* + * isChanged is considered context of the effect's function expression, + * if we don't bail out of effect mutation derivation tracking, isChanged + * will inherit the sources of the effect's function expression. + * + * This is innacurate and with the multiple passes ends up causing an infinite loop. + */ + useEffect(() => { + let isChanged = false; + + const newData = foo.map((val) => { + bar.someMethod(val); + isChanged = true; + }); + + if (isChanged) { + setFoo(newData); + } + }, [foo, bar]); + + return ( +
+ {foo}, {bar} +
+ ); } ``` @@ -107,8 +78,8 @@ function Component() { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [foo, bar]\n\nData Flow Tree:\n└── newData\n ├── foo (State)\n └── bar (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":23,"column":6,"index":663},"end":{"line":23,"column":12,"index":669},"filename":"function-expression-mutation-edge-case.ts","identifierName":"setFoo"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":64},"end":{"line":32,"column":1,"index":762},"filename":"function-expression-mutation-edge-case.ts"},"fnName":"Component","memoSlots":9,"memoBlocks":4,"memoValues":5,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [foo, bar]\n\nData Flow Tree:\n└── newData\n ├── foo (State)\n └── bar (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":23,"column":6,"index":682},"end":{"line":23,"column":12,"index":688},"filename":"function-expression-mutation-edge-case.ts","identifierName":"setFoo"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":83},"end":{"line":32,"column":1,"index":781},"filename":"function-expression-mutation-edge-case.ts"},"fnName":"Component","memoSlots":9,"memoBlocks":4,"memoValues":5,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.js index ab0bd70f363f..856209928d1c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/function-expression-mutation-edge-case.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component() { const [foo, setFoo] = useState({}); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.expect.md index 29dea440b463..928b7e9f7129 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { @@ -28,38 +28,20 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; function Component() { - const $ = _c(5); - const [firstName] = useState("Taylor"); + const [firstName, setFirstName] = useState("Taylor"); + const lastName = "Swift"; + // 🔴 Avoid: redundant state and unnecessary Effect const [fullName, setFullName] = useState(""); - let t0; - let t1; - if ($[0] !== firstName) { - t0 = () => { - setFullName(firstName + " " + "Swift"); - }; - t1 = [firstName, "Swift"]; - $[0] = firstName; - $[1] = t0; - $[2] = t1; - } else { - t0 = $[1]; - t1 = $[2]; - } - useEffect(t0, t1); - let t2; - if ($[3] !== fullName) { - t2 =
{fullName}
; - $[3] = fullName; - $[4] = t2; - } else { - t2 = $[4]; - } - return t2; + useEffect(() => { + setFullName(firstName + " " + lastName); + }, [firstName, lastName]); + + return
{fullName}
; } export const FIXTURE_ENTRYPOINT = { @@ -72,8 +54,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [firstName]\n\nData Flow Tree:\n└── firstName (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":11,"column":4,"index":341},"end":{"line":11,"column":15,"index":352},"filename":"invalid-derived-computation-in-effect.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":107},"end":{"line":15,"column":1,"index":445},"filename":"invalid-derived-computation-in-effect.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [firstName]\n\nData Flow Tree:\n└── firstName (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":11,"column":4,"index":360},"end":{"line":11,"column":15,"index":371},"filename":"invalid-derived-computation-in-effect.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":126},"end":{"line":15,"column":1,"index":464},"filename":"invalid-derived-computation-in-effect.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.js index e29ece67bd57..6cd45831215a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-computation-in-effect.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.expect.md index c7199d95480f..c627b583b25b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component(props) { @@ -26,39 +26,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; export default function Component(props) { - const $ = _c(7); const [displayValue, setDisplayValue] = useState(""); - let t0; - let t1; - if ($[0] !== props.prefix || $[1] !== props.suffix || $[2] !== props.value) { - t0 = () => { - const computed = props.prefix + props.value + props.suffix; - setDisplayValue(computed); - }; - t1 = [props.prefix, props.value, props.suffix]; - $[0] = props.prefix; - $[1] = props.suffix; - $[2] = props.value; - $[3] = t0; - $[4] = t1; - } else { - t0 = $[3]; - t1 = $[4]; - } - useEffect(t0, t1); - let t2; - if ($[5] !== displayValue) { - t2 =
{displayValue}
; - $[5] = displayValue; - $[6] = t2; - } else { - t2 = $[6]; - } - return t2; + + useEffect(() => { + const computed = props.prefix + props.value + props.suffix; + setDisplayValue(computed); + }, [props.prefix, props.value, props.suffix]); + + return
{displayValue}
; } export const FIXTURE_ENTRYPOINT = { @@ -71,8 +50,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [props]\n\nData Flow Tree:\n└── computed\n └── props (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":4,"index":295},"end":{"line":9,"column":19,"index":310},"filename":"invalid-derived-state-from-computed-props.ts","identifierName":"setDisplayValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":122},"end":{"line":13,"column":1,"index":409},"filename":"invalid-derived-state-from-computed-props.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [props]\n\nData Flow Tree:\n└── computed\n └── props (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":9,"column":4,"index":314},"end":{"line":9,"column":19,"index":329},"filename":"invalid-derived-state-from-computed-props.ts","identifierName":"setDisplayValue"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":141},"end":{"line":13,"column":1,"index":428},"filename":"invalid-derived-state-from-computed-props.ts"},"fnName":"Component","memoSlots":7,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.js index 39648ef8d5ee..4243834c2f6c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-computed-props.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.expect.md index 5a6af555408e..858daba50230 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component({props}) { @@ -27,40 +27,19 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState } from "react"; -export default function Component(t0) { - const $ = _c(6); - const { props } = t0; +export default function Component({ props }) { const [fullName, setFullName] = useState( props.firstName + " " + props.lastName, ); - let t1; - let t2; - if ($[0] !== props.firstName || $[1] !== props.lastName) { - t1 = () => { - setFullName(props.firstName + " " + props.lastName); - }; - t2 = [props.firstName, props.lastName]; - $[0] = props.firstName; - $[1] = props.lastName; - $[2] = t1; - $[3] = t2; - } else { - t1 = $[2]; - t2 = $[3]; - } - useEffect(t1, t2); - let t3; - if ($[4] !== fullName) { - t3 =
{fullName}
; - $[4] = fullName; - $[5] = t3; - } else { - t3 = $[5]; - } - return t3; + + useEffect(() => { + setFullName(props.firstName + " " + props.lastName); + }, [props.firstName, props.lastName]); + + return
{fullName}
; } export const FIXTURE_ENTRYPOINT = { @@ -73,8 +52,8 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [props]\n\nData Flow Tree:\n└── props (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":10,"column":4,"index":269},"end":{"line":10,"column":15,"index":280},"filename":"invalid-derived-state-from-destructured-props.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":122},"end":{"line":14,"column":1,"index":397},"filename":"invalid-derived-state-from-destructured-props.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nProps: [props]\n\nData Flow Tree:\n└── props (Prop)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":10,"column":4,"index":288},"end":{"line":10,"column":15,"index":299},"filename":"invalid-derived-state-from-destructured-props.ts","identifierName":"setFullName"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":141},"end":{"line":14,"column":1,"index":416},"filename":"invalid-derived-state-from-destructured-props.ts"},"fnName":"Component","memoSlots":6,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.js index 3f662f13f71c..abb1643e6921 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/invalid-derived-state-from-destructured-props.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState} from 'react'; export default function Component({props}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.expect.md index 9a843d1883c3..70174794dc78 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState, useRef} from 'react'; export default function Component({test}) { @@ -31,44 +31,23 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import { useEffect, useState, useRef } from "react"; -export default function Component(t0) { - const $ = _c(5); - const { test } = t0; +export default function Component({ test }) { const [local, setLocal] = useState(0); const myRef = useRef(null); - let t1; - let t2; - if ($[0] !== test) { - t1 = () => { - if (myRef.current) { - setLocal(test); - } else { - setLocal(test + test); - } - }; - - t2 = [test]; - $[0] = test; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== local) { - t3 = <>{local}; - $[3] = local; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + + useEffect(() => { + if (myRef.current) { + setLocal(test); + } else { + setLocal(test + test); + } + }, [test]); + + return <>{local}; } export const FIXTURE_ENTRYPOINT = { @@ -81,7 +60,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":130},"end":{"line":18,"column":1,"index":386},"filename":"ref-conditional-in-effect-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":15,"index":149},"end":{"line":18,"column":1,"index":405},"filename":"ref-conditional-in-effect-no-error.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.js index 3594deaa02e9..a5424ab03b2d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/ref-conditional-in-effect-no-error.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" import {useEffect, useState, useRef} from 'react'; export default function Component({test}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.expect.md index 87cf7722da35..690574e4429b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component({prop}) { const [s, setS] = useState(); @@ -26,37 +26,23 @@ function Component({prop}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" -function Component(t0) { - const $ = _c(5); - const { prop } = t0; +function Component({ prop }) { const [s, setS] = useState(); - const [second] = useState(prop); - let t1; - let t2; - if ($[0] !== second) { - t1 = () => { - setS(second); - }; - t2 = [second]; - $[0] = second; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); - let t3; - if ($[3] !== s) { - t3 =
{s}
; - $[3] = s; - $[4] = t3; - } else { - t3 = $[4]; - } - return t3; + const [second, setSecond] = useState(prop); + + /* + * `second` is a source of state. It will inherit the value of `prop` in + * the first render, but after that it will no longer be updated when + * `prop` changes. So we shouldn't consider `second` as being derived from + * `prop` + */ + useEffect(() => { + setS(second); + }, [second]); + + return
{s}
; } ``` @@ -64,8 +50,8 @@ function Component(t0) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [second]\n\nData Flow Tree:\n└── second (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":14,"column":4,"index":443},"end":{"line":14,"column":8,"index":447},"filename":"usestate-derived-from-prop-no-show-in-data-flow-tree.ts","identifierName":"setS"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":64},"end":{"line":18,"column":1,"index":500},"filename":"usestate-derived-from-prop-no-show-in-data-flow-tree.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"description":"Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user\n\nThis setState call is setting a derived value that depends on the following reactive sources:\n\nState: [second]\n\nData Flow Tree:\n└── second (State)\n\nSee: https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state","category":"EffectDerivationsOfState","reason":"You might not need an effect. Derive values in render, not effects.","details":[{"kind":"error","loc":{"start":{"line":14,"column":4,"index":462},"end":{"line":14,"column":8,"index":466},"filename":"usestate-derived-from-prop-no-show-in-data-flow-tree.ts","identifierName":"setS"},"message":"This should be computed during render, not in an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":3,"column":0,"index":83},"end":{"line":18,"column":1,"index":519},"filename":"usestate-derived-from-prop-no-show-in-data-flow-tree.ts"},"fnName":"Component","memoSlots":5,"memoBlocks":2,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.js index 5a7a693d50b0..3be4e88a07ad 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/usestate-derived-from-prop-no-show-in-data-flow-tree.js @@ -1,4 +1,4 @@ -// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly +// @validateNoDerivedComputationsInEffects_exp @loggerTestOnly @outputMode:"lint" function Component({prop}) { const [s, setS] = useState(); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md index d82575b8c354..b5c079f5423b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoJSXInTryStatements +// @validateNoJSXInTryStatements @outputMode:"lint" import {identity} from 'shared-runtime'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js index 9db091a2fb7e..fbc0d292ce65 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js @@ -1,4 +1,4 @@ -// @validateNoJSXInTryStatements +// @validateNoJSXInTryStatements @outputMode:"lint" import {identity} from 'shared-runtime'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md index e8a29205647e..79ae59e64c11 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoJSXInTryStatements +// @validateNoJSXInTryStatements @outputMode:"lint" function Component(props) { let el; try { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js index f0a17391c0ee..da1682772144 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js @@ -1,4 +1,4 @@ -// @validateNoJSXInTryStatements +// @validateNoJSXInTryStatements @outputMode:"lint" function Component(props) { let el; try { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.expect.md index a6199bb7147c..54af8a114788 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.expect.md @@ -10,14 +10,28 @@ function Component({prop1, prop2}) { const y = x * 2; const arr = [x, y]; const obj = {x, y}; + let destA, destB; + if (y > 5) { + [destA, destB] = arr; + } + const [a, b] = arr; const {x: c, y: d} = obj; + let sound; + + if (y > 10) { + sound = 'woof'; + } else { + sound = 'meow'; + } useEffect(() => { if (a > 10) { console.log(a); + console.log(sound); + console.log(destA, destB); } - }, [a]); + }, [a, sound, destA, destB]); const foo = useCallback(() => { return a + b; @@ -38,187 +52,343 @@ function Component({prop1, prop2}) { ## Error ``` -Found 13 errors: +Found 25 errors: Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:5:8 +error.todo-missing-source-locations.ts:4:9 + 2 | import {useEffect, useCallback} from 'react'; 3 | - 4 | function Component({prop1, prop2}) { -> 5 | const x = prop1 + prop2; - | ^^^^^^^^^^^^^^^^^ +> 4 | function Component({prop1, prop2}) { + | ^^^^^^^^^ + 5 | const x = prop1 + prop2; 6 | const y = x * 2; 7 | const arr = [x, y]; - 8 | const obj = {x, y}; Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for VariableDeclaration is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:6:8 - 4 | function Component({prop1, prop2}) { - 5 | const x = prop1 + prop2; -> 6 | const y = x * 2; - | ^^^^^^^^^ - 7 | const arr = [x, y]; - 8 | const obj = {x, y}; - 9 | const [a, b] = arr; +error.todo-missing-source-locations.ts:9:2 + 7 | const arr = [x, y]; + 8 | const obj = {x, y}; +> 9 | let destA, destB; + | ^^^^^^^^^^^^^^^^^ + 10 | if (y > 5) { + 11 | [destA, destB] = arr; + 12 | } Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:7:8 - 5 | const x = prop1 + prop2; - 6 | const y = x * 2; -> 7 | const arr = [x, y]; - | ^^^^^^^^^^^^ - 8 | const obj = {x, y}; - 9 | const [a, b] = arr; - 10 | const {x: c, y: d} = obj; +error.todo-missing-source-locations.ts:11:4 + 9 | let destA, destB; + 10 | if (y > 5) { +> 11 | [destA, destB] = arr; + | ^^^^^^^^^^^^^^^^^^^^^ + 12 | } + 13 | + 14 | const [a, b] = arr; Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:8:8 - 6 | const y = x * 2; - 7 | const arr = [x, y]; -> 8 | const obj = {x, y}; - | ^^^^^^^^^^^^ - 9 | const [a, b] = arr; - 10 | const {x: c, y: d} = obj; - 11 | +error.todo-missing-source-locations.ts:15:9 + 13 | + 14 | const [a, b] = arr; +> 15 | const {x: c, y: d} = obj; + | ^ + 16 | let sound; + 17 | + 18 | if (y > 10) { Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:9:8 - 7 | const arr = [x, y]; - 8 | const obj = {x, y}; -> 9 | const [a, b] = arr; - | ^^^^^^^^^^^^ - 10 | const {x: c, y: d} = obj; - 11 | - 12 | useEffect(() => { +error.todo-missing-source-locations.ts:15:15 + 13 | + 14 | const [a, b] = arr; +> 15 | const {x: c, y: d} = obj; + | ^ + 16 | let sound; + 17 | + 18 | if (y > 10) { Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for VariableDeclaration is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:10:8 - 8 | const obj = {x, y}; - 9 | const [a, b] = arr; -> 10 | const {x: c, y: d} = obj; - | ^^^^^^^^^^^^^^^^^^ - 11 | - 12 | useEffect(() => { - 13 | if (a > 10) { +error.todo-missing-source-locations.ts:16:2 + 14 | const [a, b] = arr; + 15 | const {x: c, y: d} = obj; +> 16 | let sound; + | ^^^^^^^^^^ + 17 | + 18 | if (y > 10) { + 19 | sound = 'woof'; Todo: Important source location missing in generated code Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:12:2 - 10 | const {x: c, y: d} = obj; - 11 | -> 12 | useEffect(() => { +error.todo-missing-source-locations.ts:19:4 + 17 | + 18 | if (y > 10) { +> 19 | sound = 'woof'; + | ^^^^^^^^^^^^^^^ + 20 | } else { + 21 | sound = 'meow'; + 22 | } + +Todo: Important source location has wrong node type in generated code + +Source location for Identifier exists in the generated output but with wrong node type(s): ExpressionStatement. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:19:4 + 17 | + 18 | if (y > 10) { +> 19 | sound = 'woof'; + | ^^^^^ + 20 | } else { + 21 | sound = 'meow'; + 22 | } + +Todo: Important source location missing in generated code + +Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:21:4 + 19 | sound = 'woof'; + 20 | } else { +> 21 | sound = 'meow'; + | ^^^^^^^^^^^^^^^ + 22 | } + 23 | + 24 | useEffect(() => { + +Todo: Important source location has wrong node type in generated code + +Source location for Identifier exists in the generated output but with wrong node type(s): ExpressionStatement. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:21:4 + 19 | sound = 'woof'; + 20 | } else { +> 21 | sound = 'meow'; + | ^^^^^ + 22 | } + 23 | + 24 | useEffect(() => { + +Todo: Important source location missing in generated code + +Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:24:2 + 22 | } + 23 | +> 24 | useEffect(() => { | ^^^^^^^^^^^^^^^^^ -> 13 | if (a > 10) { +> 25 | if (a > 10) { | ^^^^^^^^^^^^^^^^^ -> 14 | console.log(a); +> 26 | console.log(a); | ^^^^^^^^^^^^^^^^^ -> 15 | } +> 27 | console.log(sound); | ^^^^^^^^^^^^^^^^^ -> 16 | }, [a]); - | ^^^^^^^^^^^ - 17 | - 18 | const foo = useCallback(() => { - 19 | return a + b; +> 28 | console.log(destA, destB); + | ^^^^^^^^^^^^^^^^^ +> 29 | } + | ^^^^^^^^^^^^^^^^^ +> 30 | }, [a, sound, destA, destB]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 31 | + 32 | const foo = useCallback(() => { + 33 | return a + b; Todo: Important source location missing in generated code Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:14:6 - 12 | useEffect(() => { - 13 | if (a > 10) { -> 14 | console.log(a); +error.todo-missing-source-locations.ts:26:6 + 24 | useEffect(() => { + 25 | if (a > 10) { +> 26 | console.log(a); | ^^^^^^^^^^^^^^^ - 15 | } - 16 | }, [a]); - 17 | + 27 | console.log(sound); + 28 | console.log(destA, destB); + 29 | } Todo: Important source location missing in generated code -Source location for VariableDeclarator is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:18:8 - 16 | }, [a]); - 17 | -> 18 | const foo = useCallback(() => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -> 19 | return a + b; - | ^^^^^^^^^^^^^^^^^ -> 20 | }, [a, b]); - | ^^^^^^^^^^^^^ - 21 | - 22 | function bar() { - 23 | return (c + d) * 2; +error.todo-missing-source-locations.ts:26:14 + 24 | useEffect(() => { + 25 | if (a > 10) { +> 26 | console.log(a); + | ^^^ + 27 | console.log(sound); + 28 | console.log(destA, destB); + 29 | } + +Todo: Important source location missing in generated code + +Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:27:6 + 25 | if (a > 10) { + 26 | console.log(a); +> 27 | console.log(sound); + | ^^^^^^^^^^^^^^^^^^^ + 28 | console.log(destA, destB); + 29 | } + 30 | }, [a, sound, destA, destB]); + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:27:14 + 25 | if (a > 10) { + 26 | console.log(a); +> 27 | console.log(sound); + | ^^^ + 28 | console.log(destA, destB); + 29 | } + 30 | }, [a, sound, destA, destB]); + +Todo: Important source location missing in generated code + +Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:28:6 + 26 | console.log(a); + 27 | console.log(sound); +> 28 | console.log(destA, destB); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 29 | } + 30 | }, [a, sound, destA, destB]); + 31 | + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:28:14 + 26 | console.log(a); + 27 | console.log(sound); +> 28 | console.log(destA, destB); + | ^^^ + 29 | } + 30 | }, [a, sound, destA, destB]); + 31 | + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:32:14 + 30 | }, [a, sound, destA, destB]); + 31 | +> 32 | const foo = useCallback(() => { + | ^^^^^^^^^^^ + 33 | return a + b; + 34 | }, [a, b]); + 35 | Todo: Important source location missing in generated code Source location for ReturnStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:19:4 - 17 | - 18 | const foo = useCallback(() => { -> 19 | return a + b; +error.todo-missing-source-locations.ts:33:4 + 31 | + 32 | const foo = useCallback(() => { +> 33 | return a + b; | ^^^^^^^^^^^^^ - 20 | }, [a, b]); - 21 | - 22 | function bar() { + 34 | }, [a, b]); + 35 | + 36 | function bar() { + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:34:6 + 32 | const foo = useCallback(() => { + 33 | return a + b; +> 34 | }, [a, b]); + | ^ + 35 | + 36 | function bar() { + 37 | return (c + d) * 2; + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:34:9 + 32 | const foo = useCallback(() => { + 33 | return a + b; +> 34 | }, [a, b]); + | ^ + 35 | + 36 | function bar() { + 37 | return (c + d) * 2; Todo: Important source location missing in generated code Source location for ReturnStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:23:4 - 21 | - 22 | function bar() { -> 23 | return (c + d) * 2; +error.todo-missing-source-locations.ts:37:4 + 35 | + 36 | function bar() { +> 37 | return (c + d) * 2; | ^^^^^^^^^^^^^^^^^^^ - 24 | } - 25 | - 26 | console.log('Hello, world!'); + 38 | } + 39 | + 40 | console.log('Hello, world!'); Todo: Important source location missing in generated code Source location for ExpressionStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:26:2 - 24 | } - 25 | -> 26 | console.log('Hello, world!'); +error.todo-missing-source-locations.ts:40:2 + 38 | } + 39 | +> 40 | console.log('Hello, world!'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 27 | - 28 | return [y, foo, bar]; - 29 | } + 41 | + 42 | return [y, foo, bar]; + 43 | } + +Todo: Important source location missing in generated code + +Source location for Identifier is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. + +error.todo-missing-source-locations.ts:40:10 + 38 | } + 39 | +> 40 | console.log('Hello, world!'); + | ^^^ + 41 | + 42 | return [y, foo, bar]; + 43 | } Todo: Important source location missing in generated code Source location for ReturnStatement is missing in the generated output. This can cause coverage instrumentation to fail to track this code properly, resulting in inaccurate coverage reports.. -error.todo-missing-source-locations.ts:28:2 - 26 | console.log('Hello, world!'); - 27 | -> 28 | return [y, foo, bar]; +error.todo-missing-source-locations.ts:42:2 + 40 | console.log('Hello, world!'); + 41 | +> 42 | return [y, foo, bar]; | ^^^^^^^^^^^^^^^^^^^^^ - 29 | } - 30 | + 43 | } + 44 | ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.js index 0277aa787357..70d376d81c6e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-missing-source-locations.js @@ -6,14 +6,28 @@ function Component({prop1, prop2}) { const y = x * 2; const arr = [x, y]; const obj = {x, y}; + let destA, destB; + if (y > 5) { + [destA, destB] = arr; + } + const [a, b] = arr; const {x: c, y: d} = obj; + let sound; + + if (y > 10) { + sound = 'woof'; + } else { + sound = 'meow'; + } useEffect(() => { if (a > 10) { console.log(a); + console.log(sound); + console.log(destA, destB); } - }, [a]); + }, [a, sound, destA, destB]); const foo = useCallback(() => { return a + b; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.expect.md index cee338b14e57..8ba85e3ff16f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.expect.md @@ -44,7 +44,6 @@ function Component(props) { let t0; if ($[0] !== props.a) { const a = [props.a]; - t0 = [a]; $[0] = props.a; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.expect.md index 28c2a8e03b53..f3d5e8ac6afc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.expect.md @@ -40,13 +40,11 @@ function Component(props) { [ fbt._param( "a really long description that got split into multiple lines", - props.name, ), ], { hk: "1euPUp" }, ); - t0 = element.toString(); $[0] = props.name; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.expect.md index eb41b86fdfdb..62366dc51419 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.expect.md @@ -32,16 +32,9 @@ function Component(props) { if ($[0] !== props.name) { const element = fbt._( 'Hello {"user" name}', - [ - fbt._param( - '"user" name', - - props.name, - ), - ], + [fbt._param('"user" name', props.name)], { hk: "S0vMe" }, ); - t0 = element.toString(); $[0] = props.name; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-unicode.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-unicode.expect.md index 60d234974665..6c3a94509eb8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-unicode.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-unicode.expect.md @@ -32,16 +32,9 @@ function Component(props) { if ($[0] !== props.name) { const element = fbt._( "Hello {user name ☺}", - [ - fbt._param( - "user name \u263A", - - props.name, - ), - ], + [fbt._param("user name \u263A", props.name)], { hk: "1En1lp" }, ); - t0 = element.toString(); $[0] = props.name; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-to-string.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-to-string.expect.md index eca12d2404c6..9ad917e6f788 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-to-string.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-to-string.expect.md @@ -32,16 +32,9 @@ function Component(props) { if ($[0] !== props.name) { const element = fbt._( "Hello {user name}", - [ - fbt._param( - "user name", - - props.name, - ), - ], + [fbt._param("user name", props.name)], { hk: "2zEDKF" }, ); - t0 = element.toString(); $[0] = props.name; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flag-enable-emit-hook-guards.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flag-enable-emit-hook-guards.expect.md index 301a46a45c38..714cd931ae8b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flag-enable-emit-hook-guards.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flag-enable-emit-hook-guards.expect.md @@ -78,7 +78,6 @@ function Component(t0) { setState(5); } }; - t3 = [state]; $[1] = state; $[2] = t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-in-statement.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-in-statement.expect.md index 09fdaa65ac3b..00ce1f020e06 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-in-statement.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-in-statement.expect.md @@ -33,7 +33,6 @@ function Component(props) { for (const key in props) { items.push(
{key}
); } - t0 =
{items}
; $[0] = props; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-value-block-initializer.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-value-block-initializer.expect.md index 6ef73de8b04f..a68e2a23fb26 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-value-block-initializer.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-value-block-initializer.expect.md @@ -73,7 +73,6 @@ function Component(props) { const item = props.items[i]; items.push(
{item.value}
); } - t0 =
{items}
; $[0] = props.items; $[1] = props.start; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-mutate.expect.md index dd1a045e790a..ceb5b9289dfa 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-mutate.expect.md @@ -38,7 +38,6 @@ function Component(_props) {
{toJSON(mutateAndReturn(item))}
, ); } - t0 =
{results}
; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-maybe-mutates-hook-return-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-maybe-mutates-hook-return-value.expect.md index 894c1ecc1d1e..c8d6224645be 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-maybe-mutates-hook-return-value.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-maybe-mutates-hook-return-value.expect.md @@ -29,7 +29,6 @@ function Component(props) { const onLoad = () => { log(id); }; - t0 = ; $[0] = id; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md index 714e61eb890e..73dbdc7f9d46 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md @@ -27,7 +27,6 @@ function Component(props) { const f = function () { return
{props.name}
; }; - t0 = f.call(); $[0] = props; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-jsx-tag-lowered-between-mutations.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-jsx-tag-lowered-between-mutations.expect.md index e355f58da9af..dbd57bc2f700 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-jsx-tag-lowered-between-mutations.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-jsx-tag-lowered-between-mutations.expect.md @@ -29,7 +29,6 @@ function Component(props) { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const maybeMutable = new MaybeMutable(); - t0 = {maybeMutate(maybeMutable)}; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-constructor-arg.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-constructor-arg.expect.md index e0d675a2c746..245d11243a97 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-constructor-arg.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-constructor-arg.expect.md @@ -60,7 +60,6 @@ function useFoo(t0) { if ($[3] !== propArr[1] || $[4] !== propArr[2]) { s2 = new Set(MODULE_LOCAL.values()); s2.add(propArr[1]); - s3 = new Set(s2.values()); s3.add(propArr[2]); $[3] = propArr[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-copy-constructor-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-copy-constructor-mutate.expect.md index d5fcb7f73de0..78bac9ae4f53 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-copy-constructor-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/global-types/set-copy-constructor-mutate.expect.md @@ -41,7 +41,6 @@ function useFoo(t0) { if ($[0] !== propArr[0]) { s1 = new Set([1, 2, 3]); s1.add(makeArray(propArr[0])); - s2 = new Set(s1); mutate(s2); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoist-destruct.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoist-destruct.expect.md index 24711915e52b..97a2615f43ce 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoist-destruct.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoist-destruct.expect.md @@ -37,7 +37,6 @@ function Foo() {
); }; - const [t1, t2] = [1, { x: 2 }]; const a = t1; const { x: t3, y: t4 } = t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.expect.md index ca465debafc2..db1168548bda 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.expect.md @@ -39,14 +39,11 @@ function hoisting() { const onClick = function onClick() { return bar.baz; }; - const onClick2 = function onClick2() { return bar[baz]; }; - const baz = "baz"; const bar = { baz: 1 }; - t0 = ( ); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-functionexpr-conditional-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-functionexpr-conditional-dep.expect.md index 96a1d3e5726c..4c032f697f0c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-functionexpr-conditional-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-functionexpr-conditional-dep.expect.md @@ -66,7 +66,6 @@ function Component(t0) { return null; } }; - t1 = ; $[0] = isObjNull; $[1] = obj; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-let-declaration-without-initialization.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-let-declaration-without-initialization.expect.md index 0e4b3b64e82d..a67bd73fa828 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-let-declaration-without-initialization.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-let-declaration-without-initialization.expect.md @@ -36,12 +36,10 @@ function useHook(t0) { let t1; if ($[0] !== cond) { const getX = () => x; - let x; if (cond) { x = CONST_NUMBER1; } - t1 = ; $[0] = cond; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-member-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-member-expression.expect.md index 2a2a00bf3d65..441dab588140 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-member-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-member-expression.expect.md @@ -34,9 +34,7 @@ function hoisting() { const onClick = function onClick(x) { return x + bar.baz; }; - const bar = { baz: 1 }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-const-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-const-declaration.expect.md index 301ca4e8a5fd..2b661a58b426 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-const-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-const-declaration.expect.md @@ -36,13 +36,10 @@ function hoisting() { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const qux = () => { let result; - result = foo(); return result; }; - const foo = () => bar + baz; - const bar = 3; const baz = 2; t0 = qux(); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration.expect.md index faf7a064d748..cd2a9d32538f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration.expect.md @@ -36,13 +36,10 @@ function hoisting() { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const qux = () => { let result; - result = foo(); return result; }; - let foo = () => bar + baz; - let bar = 3; const baz = 2; t0 = qux(); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-object-method.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-object-method.expect.md index df1797fc85b6..bc7c402b941c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-object-method.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-object-method.expect.md @@ -36,7 +36,6 @@ function hoisting() { }, }; const bar = _temp; - t0 = x.foo(); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.expect.md index c4a969c8884c..f393597719d0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.expect.md @@ -36,13 +36,11 @@ function useHook(t0) { let t1; if ($[0] !== cond) { const getX = () => x; - let x = CONST_NUMBER0; if (cond) { x = x + CONST_NUMBER1; x; } - t1 = ; $[0] = cond; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.expect.md index cdeb9c60aabc..7d6461e3a9fb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.expect.md @@ -37,14 +37,12 @@ function useHook(t0) { let t1; if ($[0] !== cond) { const getX = () => x; - let x = CONST_NUMBER0; if (cond) { x = x + CONST_NUMBER1; x; x = Math.min(x, 100); } - t1 = ; $[0] = cond; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call.expect.md index ef486bc7fa2e..61fbfc5efec5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call.expect.md @@ -37,7 +37,6 @@ function Foo(t0) { return x * factorial(x - 1); } }; - t1 = factorial(value); $[0] = value; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-repro-variable-used-in-assignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-repro-variable-used-in-assignment.expect.md index 2389c7e9763e..a4775bc45bea 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-repro-variable-used-in-assignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-repro-variable-used-in-assignment.expect.md @@ -30,7 +30,6 @@ function get2() { const copy = x; return copy; }; - const x = 2; t0 = callbk(); $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-setstate-captured-indirectly-jsx.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-setstate-captured-indirectly-jsx.expect.md index c0c2bff9f7a2..9397518d2d11 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-setstate-captured-indirectly-jsx.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-setstate-captured-indirectly-jsx.expect.md @@ -49,7 +49,6 @@ function useFoo() { let t2; if ($[2] !== handleLogout) { const getComponent = () => handleLogout()} />; - t2 = getComponent(); $[2] = handleLogout; $[3] = t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-simple-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-simple-function-expression.expect.md index 86e65086dabb..2df5c8ec44ef 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-simple-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-simple-function-expression.expect.md @@ -30,9 +30,7 @@ function hoisting() { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const foo = () => bar(); - const bar = _temp; - t0 = foo(); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hooks-with-prefix.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hooks-with-prefix.expect.md index c7fcfd1daaef..1170f6a60a81 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hooks-with-prefix.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hooks-with-prefix.expect.md @@ -61,7 +61,6 @@ function Component() { let t1; if ($[2] !== state) { const doubledArray = makeArray(state); - t1 = doubledArray.join(""); $[2] = state; $[3] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/idx-no-outlining.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/idx-no-outlining.expect.md index 880cdcdb2101..aec4231c8dd4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/idx-no-outlining.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/idx-no-outlining.expect.md @@ -29,7 +29,6 @@ function Component(props) { let t0; if ($[0] !== props) { var _ref; - t0 = (_ref = props) != null ? (_ref = _ref.group) != null diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/iife-return-modified-later-phi.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/iife-return-modified-later-phi.expect.md index a3b3b843a9d7..22f967883b09 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/iife-return-modified-later-phi.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/iife-return-modified-later-phi.expect.md @@ -30,7 +30,6 @@ function Component(props) { let items; if ($[0] !== props.a || $[1] !== props.cond) { let t0; - if (props.cond) { t0 = []; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md index 8afc59a80ba0..cde1360bf048 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md @@ -34,7 +34,6 @@ function Component(t0) { let t1; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { a = "a"; - const [t2, t3] = [null, null]; t1 = t3; a = t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-nested-object-method.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-nested-object-method.expect.md index 963bbc7d3e8c..7ac27ab8144a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-nested-object-method.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-nested-object-method.expect.md @@ -40,7 +40,6 @@ function Test() { return _temp; }, }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/conditional-call-chain.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/conditional-call-chain.expect.md index 6114996b896a..4622beeb0eb8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/conditional-call-chain.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/conditional-call-chain.expect.md @@ -77,7 +77,6 @@ function Component(t0) { hasLogged.current = true; } }; - t3 = ; $[4] = logA; $[5] = logB; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md index c5cfff1cf714..677e9acaeaee 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md @@ -48,7 +48,6 @@ import { useIdentity } from "shared-runtime"; function useMakeCallback(t0) { const $ = _c(2); const { obj, shouldSynchronizeState } = t0; - const [, setState] = useState(0); let t1; if ($[0] !== obj.value) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md index 735462657f93..211007ef5615 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md @@ -33,7 +33,6 @@ function Component(props) { let t1; if ($[0] !== item) { const count = new MaybeMutable(item); - T1 = View; T0 = View; if ($[5] === Symbol.for("react.memo_cache_sentinel")) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-static.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-static.expect.md index b1e18f940da7..812aa0ba7709 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-static.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-static.expect.md @@ -25,7 +25,6 @@ function Component(props) { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const count = new MaybeMutable(); - t0 = ( diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.expect.md index 5eaa1fd5040b..6ac06c1df23c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" import {identity} from 'shared-runtime'; function Component(props) { @@ -25,34 +25,17 @@ function Component(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" import { identity } from "shared-runtime"; function Component(props) { - const $ = _c(4); let el; try { let value; try { - let t0; - if ($[0] !== props.foo) { - t0 = identity(props.foo); - $[0] = props.foo; - $[1] = t0; - } else { - t0 = $[1]; - } - value = t0; + value = identity(props.foo); } catch { - let t0; - if ($[2] !== value) { - t0 =
; - $[2] = value; - $[3] = t0; - } else { - t0 = $[3]; - } - el = t0; + el =
; } } catch { return null; @@ -65,8 +48,8 @@ function Component(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"ErrorBoundaries","reason":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":11,"column":11,"index":222},"end":{"line":11,"column":32,"index":243},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":91},"end":{"line":17,"column":1,"index":298},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"ErrorBoundaries","reason":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":11,"column":11,"index":241},"end":{"line":11,"column":32,"index":262},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":110},"end":{"line":17,"column":1,"index":317},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.js index 3cf5cc9b8a60..a036272cdb05 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-catch-in-outer-try-with-catch.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" import {identity} from 'shared-runtime'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.expect.md index 323aedd869de..1e08cb24a663 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" function Component(props) { let el; try { @@ -18,19 +18,11 @@ function Component(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" function Component(props) { - const $ = _c(1); let el; try { - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 =
; - $[0] = t0; - } else { - t0 = $[0]; - } - el = t0; + el =
; } catch { return null; } @@ -42,8 +34,8 @@ function Component(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"ErrorBoundaries","reason":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":5,"column":9,"index":104},"end":{"line":5,"column":16,"index":111},"filename":"invalid-jsx-in-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":49},"end":{"line":10,"column":1,"index":160},"filename":"invalid-jsx-in-try-with-catch.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"ErrorBoundaries","reason":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":5,"column":9,"index":123},"end":{"line":5,"column":16,"index":130},"filename":"invalid-jsx-in-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":68},"end":{"line":10,"column":1,"index":179},"filename":"invalid-jsx-in-try-with-catch.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.js index d01a93bf5afd..45d932ec7c42 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-jsx-in-try-with-catch.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateNoJSXInTryStatements +// @loggerTestOnly @validateNoJSXInTryStatements @outputMode:"lint" function Component(props) { let el; try { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-set-state-in-effect-verbose-derived-event.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-set-state-in-effect-verbose-derived-event.expect.md index 60479b8c2304..be0a4dc43193 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-set-state-in-effect-verbose-derived-event.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-set-state-in-effect-verbose-derived-event.expect.md @@ -42,7 +42,6 @@ function VideoPlayer(t0) { console.log("Play state changed!"); } }; - t2 = [isPlaying, wasPlaying]; $[0] = isPlaying; $[1] = wasPlaying; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.expect.md index 6e5762f3c883..5cd44a9c851e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { @@ -24,49 +24,30 @@ function Component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import { useEffect, useState } from "react"; function Component() { - const $ = _c(2); const [state, setState] = useState(0); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - const f = () => { - setState(_temp); - }; - - t0 = () => { - f(); - }; - $[0] = t0; - } else { - t0 = $[0]; - } - const g = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = () => { - g(); - }; - $[1] = t1; - } else { - t1 = $[1]; - } - useEffect(t1); + const f = () => { + setState((s) => s + 1); + }; + const g = () => { + f(); + }; + useEffect(() => { + g(); + }); return state; } -function _temp(s) { - return s + 1; -} ``` ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":13,"column":4,"index":265},"end":{"line":13,"column":5,"index":266},"filename":"invalid-setState-in-useEffect-transitive.ts","identifierName":"g"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":92},"end":{"line":16,"column":1,"index":293},"filename":"invalid-setState-in-useEffect-transitive.ts"},"fnName":"Component","memoSlots":2,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":13,"column":4,"index":284},"end":{"line":13,"column":5,"index":285},"filename":"invalid-setState-in-useEffect-transitive.ts","identifierName":"g"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":111},"end":{"line":16,"column":1,"index":312},"filename":"invalid-setState-in-useEffect-transitive.ts"},"fnName":"Component","memoSlots":2,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.js index 50007c0bd13a..ef69e4be4339 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-transitive.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.expect.md index 946169205f0a..144cb7a52289 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useEffectEvent, useState} from 'react'; function Component() { @@ -21,40 +21,17 @@ function Component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import { useEffect, useEffectEvent, useState } from "react"; function Component() { - const $ = _c(4); const [state, setState] = useState(0); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - setState(true); - }; - $[0] = t0; - } else { - t0 = $[0]; - } - const effectEvent = useEffectEvent(t0); - let t1; - if ($[1] !== effectEvent) { - t1 = () => { - effectEvent(); - }; - $[1] = effectEvent; - $[2] = t1; - } else { - t1 = $[2]; - } - let t2; - if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t2 = []; - $[3] = t2; - } else { - t2 = $[3]; - } - useEffect(t1, t2); + const effectEvent = useEffectEvent(() => { + setState(true); + }); + useEffect(() => { + effectEvent(); + }, []); return state; } @@ -63,8 +40,8 @@ function Component() { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":10,"column":4,"index":267},"end":{"line":10,"column":15,"index":278},"filename":"invalid-setState-in-useEffect-via-useEffectEvent.ts","identifierName":"effectEvent"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":108},"end":{"line":13,"column":1,"index":309},"filename":"invalid-setState-in-useEffect-via-useEffectEvent.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":10,"column":4,"index":286},"end":{"line":10,"column":15,"index":297},"filename":"invalid-setState-in-useEffect-via-useEffectEvent.ts","identifierName":"effectEvent"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":127},"end":{"line":13,"column":1,"index":328},"filename":"invalid-setState-in-useEffect-via-useEffectEvent.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":3,"memoValues":3,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.js index a838e58564ec..823ace42c347 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect-via-useEffectEvent.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useEffectEvent, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.expect.md index 3c3a5a8053ad..5022b5517188 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { @@ -18,35 +18,24 @@ function Component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import { useEffect, useState } from "react"; function Component() { - const $ = _c(1); const [state, setState] = useState(0); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - setState(_temp); - }; - $[0] = t0; - } else { - t0 = $[0]; - } - useEffect(t0); + useEffect(() => { + setState((s) => s + 1); + }); return state; } -function _temp(s) { - return s + 1; -} ``` ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":7,"column":4,"index":180},"end":{"line":7,"column":12,"index":188},"filename":"invalid-setState-in-useEffect.ts","identifierName":"setState"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":92},"end":{"line":10,"column":1,"index":225},"filename":"invalid-setState-in-useEffect.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"EffectSetState","reason":"Calling setState synchronously within an effect can trigger cascading renders","description":"Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:\n* Update external systems with the latest state from React.\n* Subscribe for updates from some external system, calling setState in a callback function when external state changes.\n\nCalling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect)","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":7,"column":4,"index":199},"end":{"line":7,"column":12,"index":207},"filename":"invalid-setState-in-useEffect.ts","identifierName":"setState"},"message":"Avoid calling setState() directly within an effect"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":111},"end":{"line":10,"column":1,"index":244},"filename":"invalid-setState-in-useEffect.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.js index a95d3642cb8d..d2422caea022 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-setState-in-useEffect.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateNoSetStateInEffects +// @loggerTestOnly @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md index d46ce53bb03b..afebfba378d6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md @@ -59,7 +59,6 @@ function Component(props) { if ($[0] !== props.alternateComponent || $[1] !== props.component) { const maybeMutable = new MaybeMutable(); Tag = props.component; - T0 = Tag; t0 = ((Tag = props.alternateComponent), maybeMutate(maybeMutable)); $[0] = props.alternateComponent; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-captured.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-captured.expect.md index f99857fca33d..eac52a68b5ec 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-captured.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-captured.expect.md @@ -32,9 +32,7 @@ function Foo() { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const x = [{ value: 0 }, { value: 1 }, { value: 2 }]; - const foo = () => x[CONST_NUMBER0].value; - t0 = invoke(foo); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-param.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-param.expect.md index fcf52f52926e..5c0e939d524a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-param.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-array-access-member-expr-param.expect.md @@ -32,7 +32,6 @@ function Foo() { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const x = [{ value: 0 }, { value: 1 }, { value: 2 }]; const foo = (param) => x[param].value; - t0 = invoke(foo, 1); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-capture-returned-alias.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-capture-returned-alias.expect.md index bac21217c75f..ea9e981ba29d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-capture-returned-alias.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lambda-capture-returned-alias.expect.md @@ -46,12 +46,10 @@ function CaptureNotMutate(props) { let aliasedElement; if ($[2] !== idx || $[3] !== props.el) { const element = bar(props.el); - const fn = function () { const arr = { element }; return arr[idx]; }; - aliasedElement = fn(); mutate(aliasedElement); $[2] = idx; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md index 6cfdb6ca1f9c..a8069809b666 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md @@ -36,7 +36,6 @@ function Component(props) { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const object = {}; - t0 = () => { mutate(object); }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/multiple-calls-to-hoisted-callback-from-other-callback.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/multiple-calls-to-hoisted-callback-from-other-callback.expect.md index 57ca944af6bc..ba9b6684c9d5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/multiple-calls-to-hoisted-callback-from-other-callback.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/multiple-calls-to-hoisted-callback-from-other-callback.expect.md @@ -43,18 +43,15 @@ function Component(props) { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const a = () => b(); - const b = () => ( <>
onClick(true)}>a
onClick(false)}>b
); - const onClick = (value) => { setState(value); }; - t0 =
{a()}
; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-loops.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-loops.expect.md index 4b76d62482e8..dacee7424408 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-loops.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-loops.expect.md @@ -94,19 +94,14 @@ function testFunction(props) { break; } } - if (a) { } - if (b) { } - if (c) { } - if (d) { } - mutate(d, null); t0 = { a, b, c, d }; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-with-aliasing.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-with-aliasing.expect.md index 2dffce2ce270..8510bd2ecc8b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-with-aliasing.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutable-lifetime-with-aliasing.expect.md @@ -74,7 +74,6 @@ function Component(props) { const b = [a]; const c = {}; const d = { c }; - x = {}; x.b = b; const y = mutate(x, d); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutate-outer-scope-within-value-block.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutate-outer-scope-within-value-block.expect.md index dcade9000aa8..4633a1f80729 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutate-outer-scope-within-value-block.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutate-outer-scope-within-value-block.expect.md @@ -76,7 +76,6 @@ function useFoo(t0) { let t1; if ($[0] !== input) { const arr = shallowCopy(input); - const cond = identity(false); t1 = cond ? { val: CONST_TRUE } : mutate(arr); $[0] = input; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md index b02b76eac0e7..b60832af6676 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md @@ -32,7 +32,6 @@ function Component(props) { let element; if ($[0] !== props.value) { const key = {}; - element =
{props.value}
; mutate(key); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-within-capture-and-mutablerange.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-within-capture-and-mutablerange.expect.md index ef4160155749..ee091e299839 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-within-capture-and-mutablerange.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutation-within-capture-and-mutablerange.expect.md @@ -58,7 +58,6 @@ function useFoo(t0) { const x = { a }; const y = [b]; mutate(x); - z = [mutate(y)]; mutate(y); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/aliased-nested-scope-truncated-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/aliased-nested-scope-truncated-dep.expect.md index 8024676c65a3..64b08ebd4622 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/aliased-nested-scope-truncated-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/aliased-nested-scope-truncated-dep.expect.md @@ -182,12 +182,9 @@ function Component(t0) { if ($[0] !== prop) { const obj = shallowCopy(prop); const aliasedObj = identity(obj); - const id = [obj.id]; - mutate(aliasedObj); setPropertyByKey(aliasedObj, "id", prop.id + 1); - t1 = ; $[0] = prop; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/basic-mutation-via-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/basic-mutation-via-function-expression.expect.md index 8b767931a894..72f0e7fb28ef 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/basic-mutation-via-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/basic-mutation-via-function-expression.expect.md @@ -31,7 +31,6 @@ function Component(t0) { y.x = x; mutate(y); }; - f(); t1 =
{x}
; $[0] = a; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-backedge-phi-with-later-mutation.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-backedge-phi-with-later-mutation.expect.md index a77dad5fe779..99e9a66924ac 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-backedge-phi-with-later-mutation.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-backedge-phi-with-later-mutation.expect.md @@ -53,7 +53,6 @@ function Component(t0) { let z; if ($[0] !== prop1 || $[1] !== prop2) { let x = [{ value: prop1 }]; - while (x.length < 2) { arrayPush(x, { value: prop2 }); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-in-function-expression-indirect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-in-function-expression-indirect.expect.md index 326cd9f7e0d9..34c41ff54cf9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-in-function-expression-indirect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/capture-in-function-expression-indirect.expect.md @@ -48,7 +48,6 @@ function Component(t0) { const b = { x }; a.y.x = b; }; - f0(); mutate(y); t1 = ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/iife-return-modified-later-phi.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/iife-return-modified-later-phi.expect.md index a3b3b843a9d7..22f967883b09 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/iife-return-modified-later-phi.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/iife-return-modified-later-phi.expect.md @@ -30,7 +30,6 @@ function Component(props) { let items; if ($[0] !== props.a || $[1] !== props.cond) { let t0; - if (props.cond) { t0 = []; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections-2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections-2.expect.md index 013da083261e..b42bfb001eec 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections-2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections-2.expect.md @@ -41,7 +41,6 @@ function Component(t0) { const y = [x]; return y[0]; }; - const x0 = f(); const z = [x0]; const x1 = z[0]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections.expect.md index f8ceba27158b..4dcb9110ab05 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-boxing-unboxing-function-call-indirections.expect.md @@ -42,7 +42,6 @@ function Component(t0) { const x0 = y[0]; return [x0]; }; - const z = f(); const x1 = z[0]; x1.key = "value"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/object-expression-computed-member.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/object-expression-computed-member.expect.md index b899212b5bad..713a3112fe25 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/object-expression-computed-member.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/object-expression-computed-member.expect.md @@ -32,7 +32,6 @@ function Component(props) { let context; if ($[0] !== props.value) { const key = { a: "key" }; - const t0 = key.a; const t1 = identity([props.value]); let t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-function-expression-effects-stack-overflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-function-expression-effects-stack-overflow.expect.md index 9d168c9e5c1e..fe47e6b0a026 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-function-expression-effects-stack-overflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-function-expression-effects-stack-overflow.expect.md @@ -45,7 +45,6 @@ function Component() { .build({}) .build({}); }; - t1 = ; $[1] = t1; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-invalid-function-expression-effects-phi.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-invalid-function-expression-effects-phi.expect.md index 73cf419be14d..6043495bc191 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-invalid-function-expression-effects-phi.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-invalid-function-expression-effects-phi.expect.md @@ -38,10 +38,8 @@ function Component(t0) { while (z == null) { z = x; } - z.y = y; }; - f(); mutate(x); t1 =
{x}
; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md index 109219e03ada..ef8a2dc1757e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md @@ -33,11 +33,8 @@ function Example() { let t0; if ($[0] !== data) { const { a, b } = identity(data); - const el = ; - identity(a.at(0)); - t0 = ; $[0] = data; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md index a9f6e8805f3f..0e54471a23cd 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md @@ -56,9 +56,7 @@ function Foo(t0) { let t2; if ($[2] !== arr2 || $[3] !== foo || $[4] !== x) { let y = []; - getVal1 = _temp; - t2 = () => [y]; foo ? (y = x.concat(arr2)) : y; $[2] = arr2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-key-mutate-key-while-constructing-object.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-key-mutate-key-while-constructing-object.expect.md index 4c4b45967e25..77d3653e0c1b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-key-mutate-key-while-constructing-object.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-key-mutate-key-while-constructing-object.expect.md @@ -30,7 +30,6 @@ function Component(props) { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const key = {}; - t0 = mutateAndReturn(key); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md index 8d1615f65c6f..49be82b146bc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md @@ -31,7 +31,6 @@ function Component(props) { let context; if ($[0] !== props.value) { const key = { a: "key" }; - const t0 = key.a; const t1 = identity([props.value]); let t2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/optional-call-with-independently-memoizable-arg.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/optional-call-with-independently-memoizable-arg.expect.md index 2f93ccd27586..b313cc20762e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/optional-call-with-independently-memoizable-arg.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/optional-call-with-independently-memoizable-arg.expect.md @@ -27,7 +27,6 @@ function Component(props) { let t0; if ($[0] !== props) { const x = makeOptionalFunction(props); - t0 = x?.(
{props.text} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/original-reactive-scopes-fork/capture-ref-for-later-mutation.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/original-reactive-scopes-fork/capture-ref-for-later-mutation.expect.md index b5babb37cdf2..7e79b2d0437b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/original-reactive-scopes-fork/capture-ref-for-later-mutation.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/original-reactive-scopes-fork/capture-ref-for-later-mutation.expect.md @@ -46,7 +46,6 @@ function useKeyCommand() { const nextPosition = direction === "left" ? addOne(position) : position; currentPosition.current = nextPosition; }; - const moveLeft = { handler: handleKey("left") }; const moveRight = { handler: handleKey("right") }; t0 = [moveLeft, moveRight]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push-consecutive-phis.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push-consecutive-phis.expect.md index 16edbf2e2369..2bfb21bc6739 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push-consecutive-phis.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push-consecutive-phis.expect.md @@ -75,9 +75,7 @@ function Component(props) { } else { y = []; } - y.push(x); - t1 = [x, y]; $[1] = props.cond; $[2] = props.cond2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push.expect.md index 58e2c8f869a6..9fc02ca3b905 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-array-push.expect.md @@ -53,9 +53,7 @@ function Component(props) { } else { y = []; } - y.push(x); - t1 = [x, y]; $[1] = props.cond; $[2] = props.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-property-store.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-property-store.expect.md index 9223c6120012..f0a4ad368ff9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-property-store.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/phi-type-inference-property-store.expect.md @@ -49,9 +49,7 @@ function Component(props) { } else { y = { a: props.a }; } - y.x = x; - t1 = [x, y]; $[1] = props.a; $[2] = props.cond; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns-primitive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns-primitive.expect.md index 27fdecd79fa4..8850f869d07b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns-primitive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns-primitive.expect.md @@ -34,7 +34,6 @@ import { identity } from "shared-runtime"; function useFoo(cond) { let t0; - if (cond) { t0 = 2; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns.expect.md index cddc2dd86b9e..af959b9865bc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/prune-nonescaping-useMemo-mult-returns.expect.md @@ -34,7 +34,6 @@ import { identity } from "shared-runtime"; function useFoo(cond) { let t0; - if (cond) { t0 = identity(10); } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-in-other-reactive-block.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-in-other-reactive-block.expect.md index 3da133e9295b..350fdcfd43a5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-in-other-reactive-block.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-in-other-reactive-block.expect.md @@ -52,7 +52,6 @@ function useFoo(minWidth, otherProp) { t1 = $[6]; } const style = t1; - arrayPush(x, otherProp); t0 = [style, x]; $[0] = minWidth; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md index 1b94677c78d4..1a86ddc7c158 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md @@ -56,9 +56,7 @@ function Foo(t0) { let t2; if ($[2] !== arr2 || $[3] !== foo || $[4] !== x) { let y = []; - getVal1 = _temp; - t2 = () => [y]; foo ? (y = x.concat(arr2)) : y; $[2] = arr2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-in-other-reactive-block.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-in-other-reactive-block.expect.md index a3f36517ffff..742b82098ffc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-in-other-reactive-block.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-in-other-reactive-block.expect.md @@ -42,7 +42,6 @@ function useFoo(minWidth, otherProp) { let t0; if ($[0] !== minWidth || $[1] !== otherProp || $[2] !== width) { const x = []; - const t1 = Math.max(minWidth, width); let t2; if ($[4] !== t1) { @@ -53,7 +52,6 @@ function useFoo(minWidth, otherProp) { t2 = $[5]; } const style = t2; - arrayPush(x, otherProp); t0 = [style, x]; $[0] = minWidth; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md index 735120f90009..5e7df69d98b6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md @@ -47,7 +47,6 @@ function Foo(t0) { let val1; if ($[0] !== arr1 || $[1] !== arr2 || $[2] !== foo) { const x = [arr1]; - let y = []; let t2; if ($[5] === Symbol.for("react.memo_cache_sentinel")) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.expect.md index 7e0d9d2e64e8..7c2392453ca7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.expect.md @@ -45,11 +45,9 @@ function ComponentA(props) { if (b) { a.push(props.p0); } - if (props.p1) { b.push(props.p2); } - t0 = ; $[0] = props.p0; $[1] = props.p1; @@ -70,11 +68,9 @@ function ComponentB(props) { if (mayMutate(b)) { a.push(props.p0); } - if (props.p1) { b.push(props.p2); } - t0 = ; $[0] = props.p0; $[1] = props.p1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.expect.md index 6d88e411c0df..2a3da8b195af 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.expect.md @@ -31,7 +31,6 @@ function Component(props) { let items; if ($[0] !== props.a || $[1] !== props.cond) { let t0; - if (props.cond) { t0 = []; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/infer-component-props-non-null.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/infer-component-props-non-null.expect.md index 8079511850a8..2c3b7930a736 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/infer-component-props-non-null.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/infer-component-props-non-null.expect.md @@ -47,7 +47,6 @@ function Foo(props) { } arr.push(t1); } - t0 = ; $[0] = props.cond; $[1] = props.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.expect.md index 4ae80006678c..662f6c33f6ce 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.expect.md @@ -76,9 +76,7 @@ function Component(props) { } else { y = []; } - y.push(x); - t1 = [x, y]; $[1] = props.cond; $[2] = props.cond2; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.expect.md index 0b756a648ec2..a9a07e97244b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.expect.md @@ -54,9 +54,7 @@ function Component(props) { } else { y = []; } - y.push(x); - t1 = [x, y]; $[1] = props.cond; $[2] = props.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.expect.md index 6c7a91ba33b0..fb2d28b0306b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.expect.md @@ -49,9 +49,7 @@ function Component(props) { } else { y = { a: props.a }; } - y.x = x; - t1 = [x, y]; $[1] = props.a; $[2] = props.cond; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md index 7ffc258b3d6d..77f5ae4db3c4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md @@ -36,7 +36,6 @@ function useFoo(t0) { let t1; if ($[0] !== a.b.c) { const fn = () => () => ({ value: a.b.c }); - t1 = ; $[0] = a.b.c; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md index af49da4b6485..53dae3e6eeb1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md @@ -71,7 +71,6 @@ function useJoinCondDepsInUncondScopes(props) { if (CONST_TRUE) { setProperty(x, props.a.b); } - setProperty(y, props.a.b); t0 = [x, y]; $[0] = props.a.b; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-leave-case.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-leave-case.expect.md index cc6713b29503..2b3d6598d91a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-leave-case.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-leave-case.expect.md @@ -49,7 +49,6 @@ function Component(props) { x.push(props.p1); y = x; } - t0 = ( {x} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/switch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/switch.expect.md index c86cba7cc888..77661de5f070 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/switch.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/switch.expect.md @@ -34,7 +34,6 @@ function Component(props) { let y; if ($[0] !== props.p0 || $[1] !== props.p2 || $[2] !== props.p3) { const x = []; - switch (props.p0) { case true: { x.push(props.p2); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-invalidate-jsx.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-invalidate-jsx.expect.md index 840b79a06b5c..34c1400ec150 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-invalidate-jsx.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-invalidate-jsx.expect.md @@ -45,7 +45,6 @@ function Component(props) { let t1; if ($[2] !== x) { const y =
{x}
; - t1 =
{y}
; $[2] = x; $[3] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-may-invalidate-array.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-may-invalidate-array.expect.md index 953cbef5a7e8..7db6242783c5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-may-invalidate-array.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-may-invalidate-array.expect.md @@ -42,7 +42,6 @@ function Component(props) { let t0; if ($[0] !== x) { const y = [x]; - t0 = [y]; $[0] = x; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-dependency-object-captured-with-reactive-mutated.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-dependency-object-captured-with-reactive-mutated.expect.md index d058210fe11d..9ced7db26afe 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-dependency-object-captured-with-reactive-mutated.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-dependency-object-captured-with-reactive-mutated.expect.md @@ -34,7 +34,6 @@ function Component(props) { const y = props.y; const z = [x, y]; mutate(z); - t0 = [x]; $[0] = props.y; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-scopes.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-scopes.expect.md index 89beacbd5cf8..2481270f0481 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-scopes.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-scopes.expect.md @@ -35,7 +35,6 @@ function f(a, b) { x.push(b); } } - t0 =
{x}
; $[0] = a.length; $[1] = b; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-analysis-interleaved-reactivity.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-analysis-interleaved-reactivity.expect.md index 28263b6dbafc..43d96c41970c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-analysis-interleaved-reactivity.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-analysis-interleaved-reactivity.expect.md @@ -42,9 +42,7 @@ function Component(props) { const b = []; b.push(props.b); a.a = null; - const c = [a]; - t0 = [c, a]; $[0] = props.b; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassign-in-while-loop-condition.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassign-in-while-loop-condition.expect.md index fe19099b1613..0b0fc73df6f5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassign-in-while-loop-condition.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassign-in-while-loop-condition.expect.md @@ -39,7 +39,6 @@ function Component() { while ((item = items.pop())) { sum = sum + item; } - t0 = [items, sum]; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-conditional.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-conditional.expect.md index 4baca5ad6d49..82d59c358f2a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-conditional.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-conditional.expect.md @@ -29,7 +29,6 @@ function Component(props) { let x = []; x.push(props.p0); const y = x; - if (props.p1) { let t1; if ($[4] === Symbol.for("react.memo_cache_sentinel")) { @@ -40,9 +39,7 @@ function Component(props) { } x = t1; } - y.push(props.p2); - t0 = ; $[0] = props.p0; $[1] = props.p1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-separate-scopes.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-separate-scopes.expect.md index 422f4cf54754..3c1baee994c4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-separate-scopes.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment-separate-scopes.expect.md @@ -49,7 +49,6 @@ function foo(a, b, c) { if (a) { x.push(a); } - t0 =
{x}
; $[0] = a; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment.expect.md index 3804326553c9..de0f4d7449db 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reassignment.expect.md @@ -36,9 +36,7 @@ function Component(props) { t1 = $[3]; } x = t1; - y.push(props.p1); - t0 = ; $[0] = props.p0; $[1] = props.p1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.expect.md index 1e7295da57f4..9217d1372015 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.expect.md @@ -62,7 +62,6 @@ function Component() { } return callback(x - 1); } - t0 = callback(10); $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md index 37d347cd9a0b..d4b473c20068 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/join-uncond-scopes-cond-deps.expect.md @@ -69,7 +69,6 @@ function useJoinCondDepsInUncondScopes(props) { if (CONST_TRUE) { setProperty(x, props.a.b); } - setProperty(y, props.a.b); t0 = [x, y]; $[0] = props.a.b; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-no-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-no-added-to-dep.expect.md index 0c8583d402c4..b726a723cb03 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-no-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-no-added-to-dep.expect.md @@ -28,7 +28,6 @@ function VideoTab() { const x = () => { console.log(t); }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md index 63268de4271a..dd72a91d0870 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md @@ -25,7 +25,6 @@ function Foo(t0) { let t1; if ($[0] !== a) { const x = { a, val }; - t1 = ; $[0] = a; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-not-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-not-added-to-dep.expect.md index 2d64bbd5ad51..b7f1bd6c3363 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-not-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-not-added-to-dep.expect.md @@ -26,7 +26,6 @@ function VideoTab() { const x = () => { console.log(ref.current.x); }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-write-not-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-write-not-added-to-dep.expect.md index fab497b4aaaf..179e9037de47 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-write-not-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-field-write-not-added-to-dep.expect.md @@ -41,7 +41,6 @@ function Component() { const inputChanged = (e) => { ref.current.text.value = e.target.value; }; - t1 = ; $[1] = t1; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md index 76a1b00776e5..3d50eafb503b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md @@ -23,7 +23,6 @@ function Foo(t0) { let t1; if ($[0] !== a) { const x = { a, val: ref.current }; - t1 = ; $[0] = a; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep.expect.md index 567b6329a7c4..4497a823d36f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep.expect.md @@ -25,7 +25,6 @@ function VideoTab() { const x = () => { console.log(ref.current); }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-optional-field-no-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-optional-field-no-added-to-dep.expect.md index 85bb7b65c5af..a55709b2826b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-optional-field-no-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-optional-field-no-added-to-dep.expect.md @@ -25,7 +25,6 @@ function VideoTab() { const x = () => { ref.current?.x; }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-write-not-added-to-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-write-not-added-to-dep.expect.md index f2feb9ef52a1..6c6aae35263a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-write-not-added-to-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-write-not-added-to-dep.expect.md @@ -25,7 +25,6 @@ function VideoTab() { const x = () => { ref.current = 1; }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/regexp-literal.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/regexp-literal.expect.md index 6ea6bdcabfae..80b90980bcf8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/regexp-literal.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/regexp-literal.expect.md @@ -26,7 +26,6 @@ function Component(props) { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const pattern = /foo/g; value = makeValue(); - t0 = pattern.test(value); $[0] = t0; $[1] = value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md index f9471d995018..e8d1d04b0618 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md @@ -57,7 +57,6 @@ function useFoo(props) { }; return b; }; - t1 = a()()(); $0[0] = props.value; $0[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-aliased-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-aliased-mutate.expect.md index 5a866044bde2..d306b152dd09 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-aliased-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-aliased-mutate.expect.md @@ -73,7 +73,6 @@ function useFoo(t0) { if ($[0] !== a || $[1] !== b) { const x = []; const y = { value: a }; - arrayPush(x, y); const y_alias = y; const cb = () => y_alias.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-mutate.expect.md index 1427ec8eb503..c3b5d6d92560 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-aliased-capture-mutate.expect.md @@ -54,14 +54,12 @@ function useFoo(t0) { if ($[0] !== a) { const arr = []; const obj = { value: a }; - setPropertyByKey(obj, "arr", arr); const obj_alias = obj; const cb = () => obj_alias.arr.length; for (let i = 0; i < a; i++) { arr.push(i); } - t1 = ; $[0] = a; $[1] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-false-positive-ref-validation-in-use-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-false-positive-ref-validation-in-use-effect.expect.md index fd7f195a54f6..cb51d86d0b20 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-false-positive-ref-validation-in-use-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-false-positive-ref-validation-in-use-effect.expect.md @@ -68,7 +68,6 @@ function Component() { update(); } }; - t2 = [update]; $[2] = update; $[3] = t1; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-independently-memoized-property-load-for-method-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-independently-memoized-property-load-for-method-call.expect.md index 0089d20af2ff..ea711a5baf4b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-independently-memoized-property-load-for-method-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-independently-memoized-property-load-for-method-call.expect.md @@ -61,11 +61,8 @@ function Component(t0) { let timestampLabel; if ($[0] !== highlightedItem || $[1] !== label || $[2] !== serverTime) { const highlight = new Highlight(highlightedItem); - const time = serverTime.get(); - timestampLabel = time / 1000 || label; - t1 = highlight.render(); $[0] = highlightedItem; $[1] = label; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md index 2d657abf327b..f141eaa64f4c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md @@ -46,7 +46,6 @@ function Component(t0) { const a = identity(data, index); const b = identity(data, index); const c = identity(data, index); - const t4 = identity(b); if ($[6] !== t4) { t2 = ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-dependency-if-within-while.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-dependency-if-within-while.expect.md index d61a48b441a4..b45977b69533 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-dependency-if-within-while.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-dependency-if-within-while.expect.md @@ -51,7 +51,6 @@ export default function Component(props) { i++; } } - t0 = <>{items}; $[0] = b; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-ref-in-function-passed-to-hook.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-ref-in-function-passed-to-hook.expect.md index 03bca61ad1e1..83aa41077487 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-ref-in-function-passed-to-hook.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-ref-in-function-passed-to-hook.expect.md @@ -89,7 +89,6 @@ function Example() { observer.disconnect(); }; }; - t3 = []; $[2] = t2; $[3] = t3; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md index ef65f6026e5a..20eab399ba07 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md @@ -39,7 +39,6 @@ function Example(props) { obj.property = props.value; return obj; }; - t0 = f(); $[0] = object; $[1] = props.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md index 4df503bcd223..e5456ed85828 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md @@ -39,7 +39,6 @@ function Example(props) { obj.property = props.value; return obj; }; - t0 = f(); $[0] = object; $[1] = props.value; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md index 1b8f59e45e85..3a7113009437 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md @@ -62,7 +62,6 @@ function Component() { t1 = t2; break bb0; } - t0 = filteredItems.map(_temp2); } $[0] = items; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md index 34d4ded61691..925470cc6a31 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md @@ -50,7 +50,6 @@ function Component(props) { t1 = null; break bb0; } - t0 = (
{fbt._( diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md index 68dc127bc1e9..8a56a4647476 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md @@ -57,7 +57,6 @@ function Component(props) { t1 = null; break bb0; } - t0 = identity(propsString); } $[0] = props; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-mutates-context.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-mutates-context.expect.md index 0da18e5f6566..5ba1dbd7804d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-mutates-context.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-mutates-context.expect.md @@ -63,7 +63,6 @@ function Foo(t0) { obj.value = newValue; obj.a = a; }; - const updater = updaterFactory(); updater(b); t1 = ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-reassigns-context.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-reassigns-context.expect.md index da6b57defe0b..690c21f0efc8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-reassigns-context.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-returned-inner-fn-reassigns-context.expect.md @@ -61,7 +61,6 @@ function Foo(t0) { const fnFactory = () => () => { myVar = _temp; }; - let myVar = _temp2; useIdentity(); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md index c5a34bc4cad8..5a67449fff4b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md @@ -53,9 +53,7 @@ function Component(props) { let t0; if ($[0] !== buttons) { const [, ...nonPrimaryButtons] = buttons; - const renderedNonPrimaryButtons = nonPrimaryButtons.map(_temp); - t0 = {renderedNonPrimaryButtons}; $[0] = buttons; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unmerged-fbt-call-merge-overlapping-reactive-scopes.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unmerged-fbt-call-merge-overlapping-reactive-scopes.expect.md index fe7857a355ef..ee2c82048a9d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unmerged-fbt-call-merge-overlapping-reactive-scopes.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unmerged-fbt-call-merge-overlapping-reactive-scopes.expect.md @@ -44,7 +44,6 @@ function Component(props) { [fbt._plural(props.value.length, "number")], { hk: "4mUen7" }, ); - t0 = props.cond ? ( {x}
; $[0] = props.a; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md index 4bdc7c7d92c6..4595caec0d75 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md @@ -50,7 +50,6 @@ function Component(statusName) { const { status, text: t2 } = foo(statusName); text = t2; const { bg, color } = getStyles(status); - t1 = identity(bg); t0 = identity(color); $[0] = statusName; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md index 2bbfc31a11ad..0f279891d33b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md @@ -52,10 +52,8 @@ function Component(statusName) { if ($[0] !== statusName) { const { status, text: t1 } = foo(statusName); text = t1; - const { color, font: t2 } = getStyles(status); font = t2; - t0 = identity(color); $[0] = statusName; $[1] = font; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx-2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx-2.expect.md index 530153679a9b..fa78e6d7b034 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx-2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx-2.expect.md @@ -33,7 +33,6 @@ function Component(props) { foo(a, b); if (foo()) { } - foo(a, b); t0 =
; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx.expect.md index 44e1e3ae76db..c8fa82b44699 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-call-jsx.expect.md @@ -28,7 +28,6 @@ function Component(props) { const a = []; const b = {}; foo(a, b); - foo(a, b); t0 =
; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-leave-case.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-leave-case.expect.md index dd61d1fee128..1f83da465aef 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-leave-case.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-leave-case.expect.md @@ -48,7 +48,6 @@ function Component(props) { x.push(props.p1); y = x; } - t0 = ( {x} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property-alias-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property-alias-mutate.expect.md index ae0daf1213de..b9f5516739b9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property-alias-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property-alias-mutate.expect.md @@ -25,7 +25,6 @@ function foo() { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const a = {}; const x = a; - y = {}; y.x = x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.expect.md index b6895fc396d9..6625f0153e8a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { let Component; if (props.cond) { @@ -18,31 +18,15 @@ function Example(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { - const $ = _c(3); let Component; if (props.cond) { - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = createComponent(); - $[0] = t0; - } else { - t0 = $[0]; - } - Component = t0; + Component = createComponent(); } else { Component = DefaultComponent; } - let t0; - if ($[1] !== Component) { - t0 = ; - $[1] = Component; - $[2] = t0; - } else { - t0 = $[2]; - } - return t0; + return ; } ``` @@ -50,8 +34,8 @@ function Example(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":9,"column":10,"index":202},"end":{"line":9,"column":19,"index":211},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":5,"column":16,"index":124},"end":{"line":5,"column":33,"index":141},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":45},"end":{"line":10,"column":1,"index":217},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"fnName":"Example","memoSlots":3,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":9,"column":10,"index":221},"end":{"line":9,"column":19,"index":230},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":5,"column":16,"index":143},"end":{"line":5,"column":33,"index":160},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":64},"end":{"line":10,"column":1,"index":236},"filename":"invalid-conditionally-assigned-dynamically-constructed-component-in-render.ts"},"fnName":"Example","memoSlots":3,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.js index 6ff7ff321c33..1022cc9d5752 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-conditionally-assigned-dynamically-constructed-component-in-render.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { let Component; if (props.cond) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.expect.md index 3d9f1f76f96c..c6441bc4cb1e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = createComponent(); return ; @@ -13,18 +13,10 @@ function Example(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { - const $ = _c(1); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - const Component = createComponent(); - t0 = ; - $[0] = t0; - } else { - t0 = $[0]; - } - return t0; + const Component = createComponent(); + return ; } ``` @@ -32,8 +24,8 @@ function Example(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":120},"end":{"line":4,"column":19,"index":129},"filename":"invalid-dynamically-construct-component-in-render.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":91},"end":{"line":3,"column":37,"index":108},"filename":"invalid-dynamically-construct-component-in-render.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":45},"end":{"line":5,"column":1,"index":135},"filename":"invalid-dynamically-construct-component-in-render.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":139},"end":{"line":4,"column":19,"index":148},"filename":"invalid-dynamically-construct-component-in-render.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":110},"end":{"line":3,"column":37,"index":127},"filename":"invalid-dynamically-construct-component-in-render.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":64},"end":{"line":5,"column":1,"index":154},"filename":"invalid-dynamically-construct-component-in-render.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.js index 209cc83d65a2..8992b8bf7c75 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-construct-component-in-render.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = createComponent(); return ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.expect.md index 2939a27a8818..0882c4a10037 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { function Component() { return
; @@ -15,21 +15,12 @@ function Example(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { - const $ = _c(1); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - const Component = function Component() { - return
; - }; - - t0 = ; - $[0] = t0; - } else { - t0 = $[0]; + function Component() { + return
; } - return t0; + return ; } ``` @@ -37,8 +28,8 @@ function Example(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":6,"column":10,"index":130},"end":{"line":6,"column":19,"index":139},"filename":"invalid-dynamically-constructed-component-function.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":2,"index":73},"end":{"line":5,"column":3,"index":119},"filename":"invalid-dynamically-constructed-component-function.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":45},"end":{"line":7,"column":1,"index":145},"filename":"invalid-dynamically-constructed-component-function.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":6,"column":10,"index":149},"end":{"line":6,"column":19,"index":158},"filename":"invalid-dynamically-constructed-component-function.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":2,"index":92},"end":{"line":5,"column":3,"index":138},"filename":"invalid-dynamically-constructed-component-function.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":64},"end":{"line":7,"column":1,"index":164},"filename":"invalid-dynamically-constructed-component-function.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.js index e48712dbf75c..123fb043eb19 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-function.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { function Component() { return
; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.expect.md index 860490581b1d..707a0a958502 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = props.foo.bar(); return ; @@ -13,27 +13,10 @@ function Example(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { - const $ = _c(4); - let t0; - if ($[0] !== props.foo) { - t0 = props.foo.bar(); - $[0] = props.foo; - $[1] = t0; - } else { - t0 = $[1]; - } - const Component = t0; - let t1; - if ($[2] !== Component) { - t1 = ; - $[2] = Component; - $[3] = t1; - } else { - t1 = $[3]; - } - return t1; + const Component = props.foo.bar(); + return ; } ``` @@ -41,8 +24,8 @@ function Example(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":118},"end":{"line":4,"column":19,"index":127},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":91},"end":{"line":3,"column":35,"index":106},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":45},"end":{"line":5,"column":1,"index":133},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"fnName":"Example","memoSlots":4,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":137},"end":{"line":4,"column":19,"index":146},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":110},"end":{"line":3,"column":35,"index":125},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":64},"end":{"line":5,"column":1,"index":152},"filename":"invalid-dynamically-constructed-component-method-call.ts"},"fnName":"Example","memoSlots":4,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.js index 7f43ffacbd45..7392c74adccb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-method-call.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = props.foo.bar(); return ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.expect.md index 8dbcf0f108af..2607ef63d8da 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = new ComponentFactory(); return ; @@ -13,18 +13,10 @@ function Example(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { - const $ = _c(1); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - const Component = new ComponentFactory(); - t0 = ; - $[0] = t0; - } else { - t0 = $[0]; - } - return t0; + const Component = new ComponentFactory(); + return ; } ``` @@ -32,8 +24,8 @@ function Example(props) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":125},"end":{"line":4,"column":19,"index":134},"filename":"invalid-dynamically-constructed-component-new.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":91},"end":{"line":3,"column":42,"index":113},"filename":"invalid-dynamically-constructed-component-new.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":45},"end":{"line":5,"column":1,"index":140},"filename":"invalid-dynamically-constructed-component-new.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"StaticComponents","reason":"Cannot create components during render","description":"Components created during render will reset their state each time they are created. Declare components outside of render","details":[{"kind":"error","loc":{"start":{"line":4,"column":10,"index":144},"end":{"line":4,"column":19,"index":153},"filename":"invalid-dynamically-constructed-component-new.ts"},"message":"This component is created during render"},{"kind":"error","loc":{"start":{"line":3,"column":20,"index":110},"end":{"line":3,"column":42,"index":132},"filename":"invalid-dynamically-constructed-component-new.ts"},"message":"The component is created during render here"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":64},"end":{"line":5,"column":1,"index":159},"filename":"invalid-dynamically-constructed-component-new.ts"},"fnName":"Example","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.js index a735e076d998..4b4e3f7f0240 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/static-components/invalid-dynamically-constructed-component-new.js @@ -1,4 +1,4 @@ -// @loggerTestOnly @validateStaticComponents +// @loggerTestOnly @validateStaticComponents @outputMode:"lint" function Example(props) { const Component = new ComponentFactory(); return ; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/switch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/switch.expect.md index 7d6fc359147b..cf76c252787e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/switch.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/switch.expect.md @@ -33,7 +33,6 @@ function Component(props) { let y; if ($[0] !== props.p0 || $[1] !== props.p2 || $[2] !== props.p3) { const x = []; - switch (props.p0) { case true: { x.push(props.p2); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-function-expression-captures-value-later-frozen.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-function-expression-captures-value-later-frozen.expect.md index cc89c1967bed..446beadb3ff2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-function-expression-captures-value-later-frozen.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-function-expression-captures-value-later-frozen.expect.md @@ -28,14 +28,11 @@ function Component(props) { let t0; if ($[0] !== props.cond) { const x = {}; - const onChange = (e) => { maybeMutate(x, e.target.value); }; - if (props.cond) { } - onChange(); t0 = ; $[0] = props.cond; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-global-property-load-cached.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-global-property-load-cached.expect.md index cf2ad80e7ac5..058f5ab0a986 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-global-property-load-cached.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-global-property-load-cached.expect.md @@ -45,7 +45,6 @@ function Component(t0) { let t1; if ($[0] !== num) { const arr = makeArray(num); - T0 = SharedRuntime.Stringify; t1 = arr.push(num); $[0] = num; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-array.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-array.expect.md index 0d1ff8c1a9a1..1cd97874c376 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-array.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-array.expect.md @@ -36,7 +36,6 @@ function Component(props) { const y = {}; const items = [x, y]; items.pop(); - mutate(y); t0 = [x, y, items]; $[0] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.expect.md index aacadb108870..107833dad983 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.expect.md @@ -59,7 +59,6 @@ function Component(props) { if (isLoadingNext) { return; } - loadMoreWithTiming(); }; t2 = [isLoadingNext, loadMoreWithTiming]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression-returns-caught-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression-returns-caught-value.expect.md index 1b45e08393ba..e8f6af8d582a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression-returns-caught-value.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression-returns-caught-value.expect.md @@ -40,7 +40,6 @@ function Component(props) { return e; } }; - t0 = callback(); $[0] = props; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md index d100dadffe97..f49cc73b2939 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md @@ -29,7 +29,6 @@ function component() { let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { const o = {}; - x = {}; x.t = p; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useActionState-dispatch-considered-as-non-reactive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useActionState-dispatch-considered-as-non-reactive.expect.md index 4b6b94ce431c..b362e307cf21 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useActionState-dispatch-considered-as-non-reactive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useActionState-dispatch-considered-as-non-reactive.expect.md @@ -35,7 +35,6 @@ function Component() { const onSubmitAction = () => { dispatchAction(); }; - t0 = ; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md index 611606ea38d2..84f25ec25772 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md @@ -50,7 +50,6 @@ function Component(props) { return null; } }; - t0 = getValue(); $[0] = foo.current; $[1] = t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.expect.md index a500af2fc8f7..392ff267a26b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.expect.md @@ -36,7 +36,6 @@ function f() { const onClick = () => { dispatch(); }; - t0 =
; $[0] = t0; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.expect.md index e60888bafc64..8e9d259fa715 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Tooltip() { @@ -27,28 +27,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import { useState, useRef, useEffect } from "react"; function Tooltip() { - const $ = _c(2); const ref = useRef(null); const [tooltipHeight, setTooltipHeight] = useState(0); - let t0; - let t1; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - const { height } = ref.current.getBoundingClientRect(); - setTooltipHeight(height); - }; - t1 = []; - $[0] = t0; - $[1] = t1; - } else { - t0 = $[0]; - t1 = $[1]; - } - useEffect(t0, t1); + + useEffect(() => { + const { height } = ref.current.getBoundingClientRect(); + setTooltipHeight(height); + }, []); + return tooltipHeight; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.js index e27292c0a8a8..88201926788c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-set-state-in-useEffect-from-ref.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Tooltip() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.expect.md index ee19358f3fb0..845711d24be7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useLayoutEffect} from 'react'; function Component() { @@ -26,34 +26,17 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import { useState, useRef, useLayoutEffect } from "react"; function Component() { - const $ = _c(3); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = { size: 5 }; - $[0] = t0; - } else { - t0 = $[0]; - } - const ref = useRef(t0); + const ref = useRef({ size: 5 }); const [computedSize, setComputedSize] = useState(0); - let t1; - let t2; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = () => { - setComputedSize(ref.current.size * 10); - }; - t2 = []; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useLayoutEffect(t1, t2); + + useLayoutEffect(() => { + setComputedSize(ref.current.size * 10); + }, []); + return computedSize; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.js index d312b139b701..c6903f893327 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-arithmetic.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useLayoutEffect} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.expect.md index a7c3714b18f8..269bda83ce96 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component() { @@ -27,34 +27,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import { useState, useRef, useEffect } from "react"; function Component() { - const $ = _c(3); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = [1, 2, 3, 4, 5]; - $[0] = t0; - } else { - t0 = $[0]; - } - const ref = useRef(t0); + const ref = useRef([1, 2, 3, 4, 5]); const [value, setValue] = useState(0); - let t1; - let t2; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = () => { - setValue(ref.current[2]); - }; - t2 = []; - $[1] = t1; - $[2] = t2; - } else { - t1 = $[1]; - t2 = $[2]; - } - useEffect(t1, t2); + + useEffect(() => { + const index = 2; + setValue(ref.current[index]); + }, []); + return value; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.js index 90459ac445cf..a5cfd5c2b2bd 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-array-index.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.expect.md index 8a46686fcde2..ce186bcddf44 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component() { @@ -33,34 +33,24 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import { useState, useRef, useEffect } from "react"; function Component() { - const $ = _c(2); const ref = useRef(null); const [width, setWidth] = useState(0); - let t0; - let t1; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - const getBoundingRect = function getBoundingRect(ref_0) { - if (ref_0.current) { - return ref_0.current.getBoundingClientRect?.()?.width ?? 100; - } - return 100; - }; - - setWidth(getBoundingRect(ref)); - }; - t1 = []; - $[0] = t0; - $[1] = t1; - } else { - t0 = $[0]; - t1 = $[1]; - } - useEffect(t0, t1); + + useEffect(() => { + function getBoundingRect(ref_0) { + if (ref_0.current) { + return ref_0.current.getBoundingClientRect?.()?.width ?? 100; + } + return 100; + } + + setWidth(getBoundingRect(ref)); + }, []); + return width; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.js index e37b3f3ea2b4..8b92e7c5fd0d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-effect-from-ref-function-call.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.expect.md index 43a84784ea0b..6570731d290e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component({x, y}) { @@ -48,40 +48,26 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" @outputMode:"lint" import { useState, useRef, useEffect } from "react"; -function Component(t0) { - const $ = _c(4); - const { x, y } = t0; +function Component({ x, y }) { const previousXRef = useRef(null); const previousYRef = useRef(null); const [data, setData] = useState(null); - let t1; - let t2; - if ($[0] !== x || $[1] !== y) { - t1 = () => { - const previousX = previousXRef.current; - previousXRef.current = x; - const previousY = previousYRef.current; - previousYRef.current = y; - if (!areEqual(x, previousX) || !areEqual(y, previousY)) { - const data_0 = load({ x, y }); - setData(data_0); - } - }; - - t2 = [x, y]; - $[0] = x; - $[1] = y; - $[2] = t1; - $[3] = t2; - } else { - t1 = $[2]; - t2 = $[3]; - } - useEffect(t1, t2); + + useEffect(() => { + const previousX = previousXRef.current; + previousXRef.current = x; + const previousY = previousYRef.current; + previousYRef.current = y; + if (!areEqual(x, previousX) || !areEqual(y, previousY)) { + const data_0 = load({ x, y }); + setData(data_0); + } + }, [x, y]); + return data; } @@ -108,7 +94,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":163},"end":{"line":22,"column":1,"index":631},"filename":"valid-setState-in-useEffect-controlled-by-ref-value.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":1,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":182},"end":{"line":22,"column":1,"index":650},"filename":"valid-setState-in-useEffect-controlled-by-ref-value.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":1,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.js index 46f11057d118..4e884e1c65de 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-controlled-by-ref-value.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @loggerTestOnly @compilationMode:"infer" @outputMode:"lint" import {useState, useRef, useEffect} from 'react'; function Component({x, y}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.expect.md index ac55bd046993..da69a338f8a6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { @@ -26,26 +26,17 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import { useEffect, useState } from "react"; function Component() { - const $ = _c(1); const [state, setState] = useState(0); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - const f = () => { - setState(); - }; - - setTimeout(() => f(), 10); + useEffect(() => { + const f = () => { + setState(); }; - $[0] = t0; - } else { - t0 = $[0]; - } - useEffect(t0); + setTimeout(() => f(), 10); + }); return state; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.js index 525f3e97d191..f5255fd4b508 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener-transitive.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.expect.md index a7deed9afb09..7a5718a17103 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { @@ -23,22 +23,14 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import { useEffect, useState } from "react"; function Component() { - const $ = _c(1); const [state, setState] = useState(0); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - setTimeout(setState, 10); - }; - $[0] = t0; - } else { - t0 = $[0]; - } - useEffect(t0); + useEffect(() => { + setTimeout(setState, 10); + }); return state; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.js index 723e4841f6d3..68f5da981fc6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useEffect-listener.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects +// @validateNoSetStateInEffects @outputMode:"lint" import {useEffect, useState} from 'react'; function Component() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.expect.md index cacd46bfe42a..9a926dc2231e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useLayoutEffect} from 'react'; function Tooltip() { @@ -27,28 +27,18 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import { useState, useRef, useLayoutEffect } from "react"; function Tooltip() { - const $ = _c(2); const ref = useRef(null); const [tooltipHeight, setTooltipHeight] = useState(0); - let t0; - let t1; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { - const { height } = ref.current.getBoundingClientRect(); - setTooltipHeight(height); - }; - t1 = []; - $[0] = t0; - $[1] = t1; - } else { - t0 = $[0]; - t1 = $[1]; - } - useLayoutEffect(t0, t1); + + useLayoutEffect(() => { + const { height } = ref.current.getBoundingClientRect(); + setTooltipHeight(height); + }, []); + return tooltipHeight; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.js index 339b550730d7..b41b2c1e7ce5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/valid-setState-in-useLayoutEffect-from-ref.js @@ -1,4 +1,4 @@ -// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects +// @validateNoSetStateInEffects @enableAllowSetStateFromRefsInEffects @outputMode:"lint" import {useState, useRef, useLayoutEffect} from 'react'; function Tooltip() { diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 49da30ccf4c1..0db63ecd3efa 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -894,6 +894,7 @@ function resolveModuleChunk( const resolvedChunk: ResolvedModuleChunk = (chunk: any); resolvedChunk.status = RESOLVED_MODULE; resolvedChunk.value = value; + resolvedChunk.reason = null; if (__DEV__) { const debugInfo = getModuleDebugInfo(value); if (debugInfo !== null) { @@ -1114,6 +1115,8 @@ export function reportGlobalError( // because we won't be getting any new data to resolve it. if (chunk.status === PENDING) { triggerErrorOnChunk(response, chunk, error); + } else if (chunk.status === INITIALIZED && chunk.reason !== null) { + chunk.reason.error(error); } }); if (__DEV__) { @@ -1462,15 +1465,95 @@ function fulfillReference( ): void { const {handler, parentObject, key, map, path} = reference; - for (let i = 1; i < path.length; i++) { + try { + for (let i = 1; i < path.length; i++) { + while ( + typeof value === 'object' && + value !== null && + value.$$typeof === REACT_LAZY_TYPE + ) { + // We never expect to see a Lazy node on this path because we encode those as + // separate models. This must mean that we have inserted an extra lazy node + // e.g. to replace a blocked element. We must instead look for it inside. + const referencedChunk: SomeChunk = value._payload; + if (referencedChunk === handler.chunk) { + // This is a reference to the thing we're currently blocking. We can peak + // inside of it to get the value. + value = handler.value; + continue; + } else { + switch (referencedChunk.status) { + case RESOLVED_MODEL: + initializeModelChunk(referencedChunk); + break; + case RESOLVED_MODULE: + initializeModuleChunk(referencedChunk); + break; + } + switch (referencedChunk.status) { + case INITIALIZED: { + value = referencedChunk.value; + continue; + } + case BLOCKED: { + // It is possible that we're blocked on our own chunk if it's a cycle. + // Before adding the listener to the inner chunk, let's check if it would + // result in a cycle. + const cyclicHandler = resolveBlockedCycle( + referencedChunk, + reference, + ); + if (cyclicHandler !== null) { + // This reference points back to this chunk. We can resolve the cycle by + // using the value from that handler. + value = cyclicHandler.value; + continue; + } + // Fallthrough + } + case PENDING: { + // If we're not yet initialized we need to skip what we've already drilled + // through and then wait for the next value to become available. + path.splice(0, i - 1); + // Add "listener" to our new chunk dependency. + if (referencedChunk.value === null) { + referencedChunk.value = [reference]; + } else { + referencedChunk.value.push(reference); + } + if (referencedChunk.reason === null) { + referencedChunk.reason = [reference]; + } else { + referencedChunk.reason.push(reference); + } + return; + } + case HALTED: { + // Do nothing. We couldn't fulfill. + // TODO: Mark downstreams as halted too. + return; + } + default: { + rejectReference( + response, + reference.handler, + referencedChunk.reason, + ); + return; + } + } + } + } + value = value[path[i]]; + } + while ( typeof value === 'object' && value !== null && value.$$typeof === REACT_LAZY_TYPE ) { - // We never expect to see a Lazy node on this path because we encode those as - // separate models. This must mean that we have inserted an extra lazy node - // e.g. to replace a blocked element. We must instead look for it inside. + // If what we're referencing is a Lazy it must be because we inserted one as a virtual node + // while it was blocked by other data. If it's no longer blocked, we can unwrap it. const referencedChunk: SomeChunk = value._payload; if (referencedChunk === handler.chunk) { // This is a reference to the thing we're currently blocking. We can peak @@ -1491,132 +1574,57 @@ function fulfillReference( value = referencedChunk.value; continue; } - case BLOCKED: { - // It is possible that we're blocked on our own chunk if it's a cycle. - // Before adding the listener to the inner chunk, let's check if it would - // result in a cycle. - const cyclicHandler = resolveBlockedCycle( - referencedChunk, - reference, - ); - if (cyclicHandler !== null) { - // This reference points back to this chunk. We can resolve the cycle by - // using the value from that handler. - value = cyclicHandler.value; - continue; - } - // Fallthrough - } - case PENDING: { - // If we're not yet initialized we need to skip what we've already drilled - // through and then wait for the next value to become available. - path.splice(0, i - 1); - // Add "listener" to our new chunk dependency. - if (referencedChunk.value === null) { - referencedChunk.value = [reference]; - } else { - referencedChunk.value.push(reference); - } - if (referencedChunk.reason === null) { - referencedChunk.reason = [reference]; - } else { - referencedChunk.reason.push(reference); - } - return; - } - case HALTED: { - // Do nothing. We couldn't fulfill. - // TODO: Mark downstreams as halted too. - return; - } - default: { - rejectReference( - response, - reference.handler, - referencedChunk.reason, - ); - return; - } } } + break; } - value = value[path[i]]; - } - while ( - typeof value === 'object' && - value !== null && - value.$$typeof === REACT_LAZY_TYPE - ) { - // If what we're referencing is a Lazy it must be because we inserted one as a virtual node - // while it was blocked by other data. If it's no longer blocked, we can unwrap it. - const referencedChunk: SomeChunk = value._payload; - if (referencedChunk === handler.chunk) { - // This is a reference to the thing we're currently blocking. We can peak - // inside of it to get the value. - value = handler.value; - continue; - } else { - switch (referencedChunk.status) { - case RESOLVED_MODEL: - initializeModelChunk(referencedChunk); + const mappedValue = map(response, value, parentObject, key); + parentObject[key] = mappedValue; + + // If this is the root object for a model reference, where `handler.value` + // is a stale `null`, the resolved value can be used directly. + if (key === '' && handler.value === null) { + handler.value = mappedValue; + } + + // If the parent object is an unparsed React element tuple, we also need to + // update the props and owner of the parsed element object (i.e. + // handler.value). + if ( + parentObject[0] === REACT_ELEMENT_TYPE && + typeof handler.value === 'object' && + handler.value !== null && + handler.value.$$typeof === REACT_ELEMENT_TYPE + ) { + const element: any = handler.value; + switch (key) { + case '3': + transferReferencedDebugInfo(handler.chunk, fulfilledChunk); + element.props = mappedValue; + break; + case '4': + // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. + if (__DEV__) { + element._owner = mappedValue; + } break; - case RESOLVED_MODULE: - initializeModuleChunk(referencedChunk); + case '5': + // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. + if (__DEV__) { + element._debugStack = mappedValue; + } + break; + default: + transferReferencedDebugInfo(handler.chunk, fulfilledChunk); break; } - switch (referencedChunk.status) { - case INITIALIZED: { - value = referencedChunk.value; - continue; - } - } - } - break; - } - - const mappedValue = map(response, value, parentObject, key); - parentObject[key] = mappedValue; - - // If this is the root object for a model reference, where `handler.value` - // is a stale `null`, the resolved value can be used directly. - if (key === '' && handler.value === null) { - handler.value = mappedValue; - } - - // If the parent object is an unparsed React element tuple, we also need to - // update the props and owner of the parsed element object (i.e. - // handler.value). - if ( - parentObject[0] === REACT_ELEMENT_TYPE && - typeof handler.value === 'object' && - handler.value !== null && - handler.value.$$typeof === REACT_ELEMENT_TYPE - ) { - const element: any = handler.value; - switch (key) { - case '3': - transferReferencedDebugInfo(handler.chunk, fulfilledChunk); - element.props = mappedValue; - break; - case '4': - // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. - if (__DEV__) { - element._owner = mappedValue; - } - break; - case '5': - // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. - if (__DEV__) { - element._debugStack = mappedValue; - } - break; - default: - transferReferencedDebugInfo(handler.chunk, fulfilledChunk); - break; + } else if (__DEV__ && !reference.isDebug) { + transferReferencedDebugInfo(handler.chunk, fulfilledChunk); } - } else if (__DEV__ && !reference.isDebug) { - transferReferencedDebugInfo(handler.chunk, fulfilledChunk); + } catch (error) { + rejectReference(response, reference.handler, error); + return; } handler.deps--; @@ -1882,6 +1890,7 @@ function loadServerReference, T>( const initializedChunk: InitializedChunk = (chunk: any); initializedChunk.status = INITIALIZED; initializedChunk.value = handler.value; + initializedChunk.reason = null; if (resolveListeners !== null) { wakeChunk(response, resolveListeners, handler.value, initializedChunk); } else { @@ -2359,7 +2368,7 @@ function parseModelString( // Symbol return Symbol.for(value.slice(2)); } - case 'F': { + case 'h': { // Server Reference const ref = value.slice(2); return getOutlinedModel( @@ -3138,6 +3147,7 @@ function startReadableStream( streamState: StreamState, ): void { let controller: ReadableStreamController = (null: any); + let closed = false; const stream = new ReadableStream({ type: type, start(c) { @@ -3195,6 +3205,10 @@ function startReadableStream( } }, close(json: UninitializedModel): void { + if (closed) { + return; + } + closed = true; if (previousBlockedChunk === null) { controller.close(); } else { @@ -3205,6 +3219,10 @@ function startReadableStream( } }, error(error: mixed): void { + if (closed) { + return; + } + closed = true; if (previousBlockedChunk === null) { // $FlowFixMe[incompatible-call] controller.error(error); @@ -3265,6 +3283,7 @@ function startAsyncIterable( (chunk: any); initializedChunk.status = INITIALIZED; initializedChunk.value = {done: false, value: value}; + initializedChunk.reason = null; if (resolveListeners !== null) { wakeChunkIfInitialized( response, @@ -3294,6 +3313,9 @@ function startAsyncIterable( nextWriteIndex++; }, close(value: UninitializedModel): void { + if (closed) { + return; + } closed = true; if (nextWriteIndex === buffer.length) { buffer[nextWriteIndex] = createResolvedIteratorResultChunk( @@ -3321,6 +3343,9 @@ function startAsyncIterable( } }, error(error: Error): void { + if (closed) { + return; + } closed = true; if (nextWriteIndex === buffer.length) { buffer[nextWriteIndex] = diff --git a/packages/react-client/src/ReactFlightReplyClient.js b/packages/react-client/src/ReactFlightReplyClient.js index f75f54f4ead0..4dc13ce48607 100644 --- a/packages/react-client/src/ReactFlightReplyClient.js +++ b/packages/react-client/src/ReactFlightReplyClient.js @@ -104,7 +104,7 @@ function serializePromiseID(id: number): string { } function serializeServerReferenceID(id: number): string { - return '$F' + id.toString(16); + return '$h' + id.toString(16); } function serializeTemporaryReferenceMarker(): string { @@ -112,7 +112,6 @@ function serializeTemporaryReferenceMarker(): string { } function serializeFormDataReference(id: number): string { - // Why K? F is "Function". D is "Date". What else? return '$K' + id.toString(16); } @@ -474,8 +473,22 @@ export function processReply( } } + const existingReference = writtenObjects.get(value); + // $FlowFixMe[method-unbinding] if (typeof value.then === 'function') { + if (existingReference !== undefined) { + if (modelRoot === value) { + // This is the ID we're currently emitting so we need to write it + // once but if we discover it again, we refer to it by id. + modelRoot = null; + } else { + // We've already emitted this as an outlined object, so we can + // just refer to that by its existing ID. + return existingReference; + } + } + // We assume that any object with a .then property is a "Thenable" type, // or a Promise type. Either of which can be represented by a Promise. if (formData === null) { @@ -484,11 +497,19 @@ export function processReply( } pendingParts++; const promiseId = nextPartId++; + const promiseReference = serializePromiseID(promiseId); + writtenObjects.set(value, promiseReference); const thenable: Thenable = (value: any); thenable.then( partValue => { try { - const partJSON = serializeModel(partValue, promiseId); + const previousReference = writtenObjects.get(partValue); + let partJSON; + if (previousReference !== undefined) { + partJSON = JSON.stringify(previousReference); + } else { + partJSON = serializeModel(partValue, promiseId); + } // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above. const data: FormData = formData; data.append(formFieldPrefix + promiseId, partJSON); @@ -504,10 +525,9 @@ export function processReply( // that throws on the server instead. reject, ); - return serializePromiseID(promiseId); + return promiseReference; } - const existingReference = writtenObjects.get(value); if (existingReference !== undefined) { if (modelRoot === value) { // This is the ID we're currently emitting so we need to write it diff --git a/packages/react-server-dom-esm/src/ReactFlightESMReferences.js b/packages/react-server-dom-esm/src/ReactFlightESMReferences.js index 6c2737e89e72..8ad9f222faf7 100644 --- a/packages/react-server-dom-esm/src/ReactFlightESMReferences.js +++ b/packages/react-server-dom-esm/src/ReactFlightESMReferences.js @@ -88,6 +88,12 @@ function bind(this: ServerReference): any { return newFn; } +const serverReferenceToString = { + value: () => 'function () { [omitted code] }', + configurable: true, + writable: true, +}; + export function registerServerReference( reference: T, id: string, @@ -111,12 +117,14 @@ export function registerServerReference( configurable: true, }, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } : { $$typeof, $$id, $$bound, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, }) as PropertyDescriptorMap, ); } diff --git a/packages/react-server-dom-parcel/src/ReactFlightParcelReferences.js b/packages/react-server-dom-parcel/src/ReactFlightParcelReferences.js index 3e7b603288e6..3dd67e733cee 100644 --- a/packages/react-server-dom-parcel/src/ReactFlightParcelReferences.js +++ b/packages/react-server-dom-parcel/src/ReactFlightParcelReferences.js @@ -95,6 +95,12 @@ function bind(this: ServerReference): any { return newFn; } +const serverReferenceToString = { + value: () => 'function () { [omitted code] }', + configurable: true, + writable: true, +}; + export function registerServerReference( reference: ServerReference, id: string, @@ -118,12 +124,14 @@ export function registerServerReference( configurable: true, }, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } : { $$typeof, $$id, $$bound, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, }) as PropertyDescriptorMap, ); } diff --git a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js index 1b4525a35490..082a9c0ce583 100644 --- a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js +++ b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js @@ -102,6 +102,12 @@ function bind(this: ServerReference): any { return newFn; } +const serverReferenceToString = { + value: () => 'function () { [omitted code] }', + configurable: true, + writable: true, +}; + export function registerServerReference( reference: T, id: string, @@ -125,12 +131,14 @@ export function registerServerReference( configurable: true, }, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } : { $$typeof, $$id, $$bound, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, }) as PropertyDescriptorMap, ); } diff --git a/packages/react-server-dom-unbundled/src/ReactFlightUnbundledReferences.js b/packages/react-server-dom-unbundled/src/ReactFlightUnbundledReferences.js index de437414ef15..07646e18ec40 100644 --- a/packages/react-server-dom-unbundled/src/ReactFlightUnbundledReferences.js +++ b/packages/react-server-dom-unbundled/src/ReactFlightUnbundledReferences.js @@ -102,6 +102,12 @@ function bind(this: ServerReference): any { return newFn; } +const serverReferenceToString = { + value: () => 'function () { [omitted code] }', + configurable: true, + writable: true, +}; + export function registerServerReference( reference: T, id: string, @@ -125,12 +131,14 @@ export function registerServerReference( configurable: true, }, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } as PropertyDescriptorMap) : ({ $$typeof, $$id, $$bound, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } as PropertyDescriptorMap), ); } diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js index de437414ef15..07646e18ec40 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js @@ -102,6 +102,12 @@ function bind(this: ServerReference): any { return newFn; } +const serverReferenceToString = { + value: () => 'function () { [omitted code] }', + configurable: true, + writable: true, +}; + export function registerServerReference( reference: T, id: string, @@ -125,12 +131,14 @@ export function registerServerReference( configurable: true, }, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } as PropertyDescriptorMap) : ({ $$typeof, $$id, $$bound, bind: {value: bind, configurable: true}, + toString: serverReferenceToString, } as PropertyDescriptorMap), ); } diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js index f1a8e41bc0fa..6aa375804f75 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js @@ -156,6 +156,23 @@ describe('ReactFlightDOM', () => { }; } + function createUnclosingStream( + stream: ReadableStream, + ): ReadableStream { + const reader = stream.getReader(); + + const s = new ReadableStream({ + async pull(controller) { + const {done, value} = await reader.read(); + if (!done) { + controller.enqueue(value); + } + }, + }); + + return s; + } + const theInfinitePromise = new Promise(() => {}); function InfiniteSuspend() { throw theInfinitePromise; @@ -2970,7 +2987,7 @@ describe('ReactFlightDOM', () => { const {prelude} = await pendingResult; const result = await ReactServerDOMClient.createFromReadableStream( - Readable.toWeb(prelude), + createUnclosingStream(Readable.toWeb(prelude)), ); const iterator = result.multiShotIterable[Symbol.asyncIterator](); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js index 5f7dfa516eb6..a7290f9523d4 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js @@ -228,7 +228,7 @@ describe('ReactFlightDOMEdge', () => { async function createBufferedUnclosingStream( stream: ReadableStream, - ): ReadableStream { + ): Promise> { const chunks: Array = []; const reader = stream.getReader(); while (true) { @@ -2309,4 +2309,34 @@ describe('ReactFlightDOMEdge', () => { const result = await response; expect(result).toEqual({obj: obj, node: 'hi'}); }); + + it('does not leak the server reference code', async () => { + function foo() { + return 'foo'; + } + + const bar = () => { + return 'bar'; + }; + + const anonymous = ( + () => () => + 'anonymous' + )(); + + expect( + ReactServerDOMServer.registerServerReference(foo, 'foo-id').toString(), + ).toBe('function () { [omitted code] }'); + + expect( + ReactServerDOMServer.registerServerReference(bar, 'bar-id').toString(), + ).toBe('function () { [omitted code] }'); + + expect( + ReactServerDOMServer.registerServerReference( + anonymous, + 'anonymous-id', + ).toString(), + ).toBe('function () { [omitted code] }'); + }); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js index 805d20471ae9..bca803c12395 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js @@ -140,7 +140,7 @@ describe('ReactFlightDOMNode', () => { async function createBufferedUnclosingStream( stream: ReadableStream, - ): ReadableStream { + ): Promise> { const chunks: Array = []; const reader = stream.getReader(); while (true) { @@ -407,7 +407,7 @@ describe('ReactFlightDOMNode', () => { ); }); - it('should cancels the underlying ReadableStream when we are cancelled', async () => { + it('should cancel the underlying and transported ReadableStreams when we are cancelled', async () => { let controller; let cancelReason; const s = new ReadableStream({ @@ -431,16 +431,30 @@ describe('ReactFlightDOMNode', () => { ), ); - const writable = new Stream.PassThrough(streamOptions); - rscStream.pipe(writable); + const readable = new Stream.PassThrough(streamOptions); + rscStream.pipe(readable); + + const result = await ReactServerDOMClient.createFromNodeStream(readable, { + moduleMap: {}, + moduleLoading: webpackModuleLoading, + }); + const reader = result.getReader(); controller.enqueue('hi'); + await serverAct(async () => { + // We should be able to read the part we already emitted before the abort + expect(await reader.read()).toEqual({ + value: 'hi', + done: false, + }); + }); + const reason = new Error('aborted'); - writable.destroy(reason); + readable.destroy(reason); await new Promise(resolve => { - writable.on('error', () => { + readable.on('error', () => { resolve(); }); }); @@ -448,9 +462,17 @@ describe('ReactFlightDOMNode', () => { expect(cancelReason.message).toBe( 'The destination stream errored while writing data.', ); + + let error = null; + try { + await reader.read(); + } catch (x) { + error = x; + } + expect(error).toBe(reason); }); - it('should cancels the underlying ReadableStream when we abort', async () => { + it('should cancel the underlying and transported ReadableStreams when we abort', async () => { const errors = []; let controller; let cancelReason; @@ -1342,12 +1364,12 @@ describe('ReactFlightDOMNode', () => { '\n' + ' in Dynamic' + (gate(flags => flags.enableAsyncDebugInfo) - ? ' (file://ReactFlightDOMNode-test.js:1216:27)\n' + ? ' (file://ReactFlightDOMNode-test.js:1238:27)\n' : '\n') + ' in body\n' + ' in html\n' + - ' in App (file://ReactFlightDOMNode-test.js:1229:25)\n' + - ' in ClientRoot (ReactFlightDOMNode-test.js:1304:16)', + ' in App (file://ReactFlightDOMNode-test.js:1251:25)\n' + + ' in ClientRoot (ReactFlightDOMNode-test.js:1326:16)', ); } else { expect( @@ -1356,7 +1378,7 @@ describe('ReactFlightDOMNode', () => { '\n' + ' in body\n' + ' in html\n' + - ' in ClientRoot (ReactFlightDOMNode-test.js:1304:16)', + ' in ClientRoot (ReactFlightDOMNode-test.js:1326:16)', ); } @@ -1366,8 +1388,8 @@ describe('ReactFlightDOMNode', () => { normalizeCodeLocInfo(ownerStack, {preserveLocation: true}), ).toBe( '\n' + - ' in Dynamic (file://ReactFlightDOMNode-test.js:1216:27)\n' + - ' in App (file://ReactFlightDOMNode-test.js:1229:25)', + ' in Dynamic (file://ReactFlightDOMNode-test.js:1238:27)\n' + + ' in App (file://ReactFlightDOMNode-test.js:1251:25)', ); } else { expect( @@ -1375,7 +1397,7 @@ describe('ReactFlightDOMNode', () => { ).toBe( '' + '\n' + - ' in App (file://ReactFlightDOMNode-test.js:1229:25)', + ' in App (file://ReactFlightDOMNode-test.js:1251:25)', ); } } else { diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReplyEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReplyEdge-test.js index b874383dcdd7..ac5aff0d8748 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReplyEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReplyEdge-test.js @@ -135,7 +135,7 @@ describe('ReactFlightDOMReplyEdge', () => { expect(await resultBlob.arrayBuffer()).toEqual(await blob.arrayBuffer()); }); - it('should supports ReadableStreams with typed arrays', async () => { + it('should support ReadableStreams with typed arrays', async () => { const buffer = new Uint8Array([ 123, 4, 10, 5, 100, 255, 244, 45, 56, 67, 43, 124, 67, 89, 100, 20, ]).buffer; @@ -239,6 +239,53 @@ describe('ReactFlightDOMReplyEdge', () => { expect(streamedBuffers.flatMap(t => Array.from(t))).toEqual(expectedBytes); }); + it('should cancel the transported ReadableStream when we are cancelled', async () => { + const s = new ReadableStream({ + start(controller) { + controller.enqueue('hi'); + controller.close(); + }, + }); + + const body = await ReactServerDOMClient.encodeReply(s); + + const iterable = { + async *[Symbol.asyncIterator]() { + // eslint-disable-next-line no-for-of-loops/no-for-of-loops + for (const entry of body) { + if (entry[1] === 'C') { + // Return before finishing the stream. + return; + } + yield entry; + } + }, + }; + + const result = await ReactServerDOMServer.decodeReplyFromAsyncIterable( + iterable, + webpackServerMap, + ); + + const reader = result.getReader(); + + // We should be able to read the part we already emitted before the abort + expect(await reader.read()).toEqual({ + value: 'hi', + done: false, + }); + + let error = null; + try { + await reader.read(); + } catch (x) { + error = x; + } + + expect(error).not.toBe(null); + expect(error.message).toBe('Connection closed.'); + }); + it('should abort when parsing an incomplete payload', async () => { const infinitePromise = new Promise(() => {}); const controller = new AbortController(); diff --git a/packages/react-server/src/ReactFlightReplyServer.js b/packages/react-server/src/ReactFlightReplyServer.js index 742cae6d2012..4d5a6da8b8e2 100644 --- a/packages/react-server/src/ReactFlightReplyServer.js +++ b/packages/react-server/src/ReactFlightReplyServer.js @@ -33,6 +33,7 @@ import { import {ASYNC_ITERATOR} from 'shared/ReactSymbols'; import hasOwnProperty from 'shared/hasOwnProperty'; +import getPrototypeOf from 'shared/getPrototypeOf'; interface FlightStreamController { enqueueModel(json: string): void; @@ -128,6 +129,26 @@ ReactPromise.prototype.then = function ( switch (chunk.status) { case INITIALIZED: if (typeof resolve === 'function') { + let inspectedValue = chunk.value; + // Recursively check if the value is itself a ReactPromise and if so if it points + // back to itself. This helps catch recursive thenables early error. + let cycleProtection = 0; + while (inspectedValue instanceof ReactPromise) { + cycleProtection++; + if (inspectedValue === chunk || cycleProtection > 1000) { + if (typeof reject === 'function') { + reject(new Error('Cannot have cyclic thenables.')); + } + return; + } + if (inspectedValue.status === INITIALIZED) { + inspectedValue = inspectedValue.value; + } else { + // If this is lazily resolved, pending or blocked, it'll eventually become + // initialized and break the loop. Rejected also breaks it. + break; + } + } resolve(chunk.value); } break; @@ -156,6 +177,9 @@ ReactPromise.prototype.then = function ( } }; +const ObjectPrototype = Object.prototype; +const ArrayPrototype = Array.prototype; + export type Response = { _bundlerConfig: ServerManifest, _prefix: string, @@ -506,6 +530,7 @@ function loadServerReference, T>( const initializedChunk: InitializedChunk = (chunk: any); initializedChunk.status = INITIALIZED; initializedChunk.value = handler.value; + initializedChunk.reason = null; if (resolveListeners !== null) { wakeChunk(response, resolveListeners, handler.value); } @@ -674,6 +699,7 @@ function initializeModelChunk(chunk: ResolvedModelChunk): void { const initializedChunk: InitializedChunk = (chunk: any); initializedChunk.status = INITIALIZED; initializedChunk.value = value; + initializedChunk.reason = null; } catch (error) { const erroredChunk: ErroredChunk = (chunk: any); erroredChunk.status = ERRORED; @@ -694,6 +720,8 @@ export function reportGlobalError(response: Response, error: Error): void { // because we won't be getting any new data to resolve it. if (chunk.status === PENDING) { triggerErrorOnChunk(response, chunk, error); + } else if (chunk.status === INITIALIZED && chunk.reason !== null) { + chunk.reason.error(error); } }); } @@ -728,57 +756,34 @@ function fulfillReference( ): void { const {handler, parentObject, key, map, path} = reference; - for (let i = 1; i < path.length; i++) { - // The server doesn't have any lazy references but we unwrap Chunks here in the same way as the client. - while (value instanceof ReactPromise) { - const referencedChunk: SomeChunk = value; - switch (referencedChunk.status) { - case RESOLVED_MODEL: - initializeModelChunk(referencedChunk); - break; - } - switch (referencedChunk.status) { - case INITIALIZED: { - value = referencedChunk.value; - continue; - } - case BLOCKED: - case PENDING: { - // If we're not yet initialized we need to skip what we've already drilled - // through and then wait for the next value to become available. - path.splice(0, i - 1); - // Add "listener" to our new chunk dependency. - if (referencedChunk.value === null) { - referencedChunk.value = [reference]; - } else { - referencedChunk.value.push(reference); - } - if (referencedChunk.reason === null) { - referencedChunk.reason = [reference]; - } else { - referencedChunk.reason.push(reference); - } - return; - } - default: { - rejectReference(response, reference.handler, referencedChunk.reason); - return; - } + try { + for (let i = 1; i < path.length; i++) { + // The server doesn't have any lazy references so we don't expect to go through a Promise. + const name = path[i]; + if ( + typeof value === 'object' && + value !== null && + (getPrototypeOf(value) === ObjectPrototype || + getPrototypeOf(value) === ArrayPrototype) && + hasOwnProperty.call(value, name) + ) { + value = value[name]; + } else { + throw new Error('Invalid reference.'); } } - const name = path[i]; - if (typeof value === 'object' && hasOwnProperty.call(value, name)) { - value = value[name]; - } - } - const mappedValue = map(response, value, parentObject, key); - parentObject[key] = mappedValue; + const mappedValue = map(response, value, parentObject, key); + parentObject[key] = mappedValue; - // If this is the root object for a model reference, where `handler.value` - // is a stale `null`, the resolved value can be used directly. - if (key === '' && handler.value === null) { - handler.value = mappedValue; + // If this is the root object for a model reference, where `handler.value` + // is a stale `null`, the resolved value can be used directly. + if (key === '' && handler.value === null) { + handler.value = mappedValue; + } + } catch (error) { + rejectReference(response, reference.handler, error); + return; } // There are no Elements or Debug Info to transfer here. @@ -889,53 +894,17 @@ function getOutlinedModel( case INITIALIZED: let value = chunk.value; for (let i = 1; i < path.length; i++) { - // The server doesn't have any lazy references but we unwrap Chunks here in the same way as the client. - while (value instanceof ReactPromise) { - const referencedChunk: SomeChunk = value; - switch (referencedChunk.status) { - case RESOLVED_MODEL: - initializeModelChunk(referencedChunk); - break; - } - switch (referencedChunk.status) { - case INITIALIZED: { - value = referencedChunk.value; - break; - } - case BLOCKED: - case PENDING: { - return waitForReference( - referencedChunk, - parentObject, - key, - response, - map, - path.slice(i - 1), - ); - } - default: { - // This is an error. Instead of erroring directly, we're going to encode this on - // an initialization handler so that we can catch it at the nearest Element. - if (initializingHandler) { - initializingHandler.errored = true; - initializingHandler.value = null; - initializingHandler.reason = referencedChunk.reason; - } else { - initializingHandler = { - chunk: null, - value: null, - reason: referencedChunk.reason, - deps: 0, - errored: true, - }; - } - return (null: any); - } - } - } const name = path[i]; - if (typeof value === 'object' && hasOwnProperty.call(value, name)) { + if ( + typeof value === 'object' && + value !== null && + (getPrototypeOf(value) === ObjectPrototype || + getPrototypeOf(value) === ArrayPrototype) && + hasOwnProperty.call(value, name) + ) { value = value[name]; + } else { + throw new Error('Invalid reference.'); } } const chunkValue = map(response, value, parentObject, key); @@ -1006,6 +975,11 @@ function parseTypedArray( const id = parseInt(reference.slice(2), 16); const prefix = response._prefix; const key = prefix + id; + const chunks = response._chunks; + if (chunks.has(id)) { + throw new Error('Already initialized typed array.'); + } + // We should have this backingEntry in the store already because we emitted // it before referencing it. It should be a Blob. // TODO: Use getOutlinedModel to allow us to emit the Blob later. We should be able to do that now. @@ -1055,6 +1029,7 @@ function parseTypedArray( const initializedChunk: InitializedChunk = (chunk: any); initializedChunk.status = INITIALIZED; initializedChunk.value = handler.value; + initializedChunk.reason = null; if (resolveListeners !== null) { wakeChunk(response, resolveListeners, handler.value); } @@ -1116,8 +1091,13 @@ function parseReadableStream( parentKey: string, ): ReadableStream { const id = parseInt(reference.slice(2), 16); + const chunks = response._chunks; + if (chunks.has(id)) { + throw new Error('Already initialized stream.'); + } let controller: ReadableStreamController = (null: any); + let closed = false; const stream = new ReadableStream({ type: type, start(c) { @@ -1166,6 +1146,10 @@ function parseReadableStream( } }, close(json: string): void { + if (closed) { + return; + } + closed = true; if (previousBlockedChunk === null) { controller.close(); } else { @@ -1176,6 +1160,10 @@ function parseReadableStream( } }, error(error: mixed): void { + if (closed) { + return; + } + closed = true; if (previousBlockedChunk === null) { // $FlowFixMe[incompatible-call] controller.error(error); @@ -1218,6 +1206,10 @@ function parseAsyncIterable( parentKey: string, ): $AsyncIterable | $AsyncIterator { const id = parseInt(reference.slice(2), 16); + const chunks = response._chunks; + if (chunks.has(id)) { + throw new Error('Already initialized stream.'); + } const buffer: Array>> = []; let closed = false; @@ -1241,6 +1233,9 @@ function parseAsyncIterable( nextWriteIndex++; }, close(value: string): void { + if (closed) { + return; + } closed = true; if (nextWriteIndex === buffer.length) { buffer[nextWriteIndex] = createResolvedIteratorResultChunk( @@ -1268,6 +1263,9 @@ function parseAsyncIterable( } }, error(error: Error): void { + if (closed) { + return; + } closed = true; if (nextWriteIndex === buffer.length) { buffer[nextWriteIndex] = @@ -1329,7 +1327,7 @@ function parseModelString( const chunk = getChunk(response, id); return chunk; } - case 'F': { + case 'h': { // Server Reference const ref = value.slice(2); return getOutlinedModel(response, ref, obj, key, loadServerReference); diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index d5b534adb497..021913636bdb 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -2797,7 +2797,7 @@ function serializePromiseID(id: number): string { } function serializeServerReferenceID(id: number): string { - return '$F' + id.toString(16); + return '$h' + id.toString(16); } function serializeSymbolReference(name: string): string { diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index e87d750ecaf8..d8c8e0b7685c 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -551,5 +551,9 @@ "563": "This render completed successfully. All cacheSignals are now aborted to allow clean up of any unused resources.", "564": "Unknown command. The debugChannel was not wired up properly.", "565": "resolveDebugMessage/closeDebugChannel should not be called for a Request that wasn't kept alive. This is a bug in React.", - "566": "FragmentInstance.scrollIntoView() does not support scrollIntoViewOptions. Use the alignToTop boolean instead." + "566": "FragmentInstance.scrollIntoView() does not support scrollIntoViewOptions. Use the alignToTop boolean instead.", + "567": "Already initialized stream.", + "568": "Already initialized typed array.", + "569": "Cannot have cyclic thenables.", + "570": "Invalid reference." }