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 ab5ac590d90..30d66522715 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 f6872da1117..4a170cdbdf3 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 fe850f9a538..c396f6b0881 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 5c98997953d..a38256896b1 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 0ab7934a1a6..123a69afc21 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 d1890237093..cd357af70f6 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 0b03ac99789..eb2d451c564 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 2b9efc0f4a6..b7b89dc1a1d 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 b30ee7e0d68..e91766e79c5 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 12c7b4d5eab..a44c3a1a5de 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 97b3bb13d70..aff7a2e7b99 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 70320c37627..b39077c9535 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 4c979728f68..37407b5cd0b 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 d40a1e080ad..5a272796587 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 56e3039f63c..ee7a71e8f8a 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 810f1a3f5e4..cd782c3f791 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 25499af1b02..7aa0702d470 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 b0bd96c2bf2..4482eab8e6a 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 223823621d0..158d31faca2 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 fcde7d675c8..03c0db7e971 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 ba9e39e691b..602e49672e2 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 b7288a854ff..0778152f341 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 85a66bb204c..7310e0fcd26 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 f855f2231d0..0bcaf60a8e6 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 6a01460e009..bfa6c830712 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 2edb60a5a2b..08b92e940fc 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 17dd0f83594..3a8f9e84cac 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 f69149aba41..fbb6e50871d 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 58013c15608..ce5bfda6440 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 756a219e645..fa5ae370e67 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 fb65cbfeb82..4cdcb53bb23 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 2f3a3d0e616..4db10f4df4c 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 1de911c9b37..9d559946bea 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 37458dcea06..afddca39e9a 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 79e65e4849a..db84ab8be45 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 fdcbccd3de5..e1c33a6c73f 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 f25e20863d3..31b77d14817 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 69814825450..960cf987d4e 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 6df5f2eed6f..e454caf2ec8 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 48811aa5a94..226a3938bd7 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 afd198caa26..1c020d3015d 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 b5100dc2a63..de184ede639 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 43b5a8c52ad..879d582c924 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 0160fbbb4a7..fc4d86a3f29 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 5bb963daac3..b6cebdb4080 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 e88d5833a9a..f11a4b26b53 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 18ad2bdca19..9425aee2441 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 fdc7081f375..080aa8e04dc 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 a6442b36477..3eabb40feeb 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 74391e86ad3..374877863dd 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 f19e9518d6f..c9c9778ab84 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 6a3593a3b27..1bd8fa23faa 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 1df99a191dc..bf48efbbc10 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 e84031591e0..ac72a441484 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 e419583cc6d..16e52562bd8 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 e26643723d9..58328b2e959 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 ae7622d4d06..565e23bb0fe 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 f23f51d6cb8..7ba22f51864 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 4075975b325..1754209d837 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 4e0ff4e2394..c1b99a95ab8 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 ab0bd70f363..856209928d1 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 29dea440b46..928b7e9f712 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 e29ece67bd5..6cd45831215 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 c7199d95480..c627b583b25 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 39648ef8d5e..4243834c2f6 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 5a6af555408..858daba5023 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 3f662f13f71..abb1643e692 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 9a843d1883c..70174794dc7 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 3594deaa02e..a5424ab03b2 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 87cf7722da3..690574e4429 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 5a7a693d50b..3be4e88a07a 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 d82575b8c35..b5c079f5423 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 9db091a2fb7..fbc0d292ce6 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 e8a29205647..79ae59e64c1 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 f0a17391c0e..da168277214 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 a6199bb7147..54af8a11478 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 0277aa78735..70d376d81c6 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 cee338b14e5..8ba85e3ff16 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 28c2a8e03b5..f3d5e8ac6af 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 eb41b86fdfd..62366dc5141 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 60d23497466..6c3a94509eb 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 eca12d2404c..9ad917e6f78 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 301a46a45c3..714cd931ae8 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 09fdaa65ac3..00ce1f020e0 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 6ef73de8b04..a68e2a23fb2 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 dd1a045e790..ceb5b9289df 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 894c1ecc1d1..c8d6224645b 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 714e61eb890..73dbdc7f9d4 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 e355f58da9a..dbd57bc2f70 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 e0d675a2c74..245d11243a9 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 d5fcb7f73de..78bac9ae4f5 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 24711915e52..97a2615f43c 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 ca465debafc..db1168548bd 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 96a1d3e5726..4c032f697f0 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 0e4b3b64e82..a67bd73fa82 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 2a2a00bf3d6..441dab58814 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 301ca4e8a5f..2b661a58b42 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 faf7a064d74..cd2a9d32538 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 df1797fc85b..bc7c402b941 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 c4a969c8884..f393597719d 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 cdeb9c60aab..7d6461e3a9f 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 ef486bc7fa2..61fbfc5efec 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 2389c7e9763..a4775bc45be 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 c0c2bff9f7a..9397518d2d1 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 86e65086dab..2df5c8ec44e 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 c7fcfd1daae..1170f6a60a8 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 880cdcdb210..aec4231c8dd 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 a3b3b843a9d..22f967883b0 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 8afc59a80ba..cde1360bf04 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 963bbc7d3e8..7ac27ab8144 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 6114996b896..4622beeb0eb 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 c5cfff1cf71..677e9acaeae 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 735462657f9..211007ef561 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 b1e18f940da..812aa0ba770 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 5eaa1fd5040..6ac06c1df23 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 3cf5cc9b8a6..a036272cdb0 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 323aedd869d..1e08cb24a66 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 d01a93bf5af..45d932ec7c4 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 60479b8c230..be0a4dc4319 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 6e5762f3c88..5cd44a9c851 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 50007c0bd13..ef69e4be433 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 946169205f0..144cb7a5228 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 a838e58564e..823ace42c34 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 3c3a5a8053a..5022b551718 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 a95d3642cb8..d2422caea02 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 d46ce53bb03..afebfba378d 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 f99857fca33..eac52a68b5e 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 fcf52f52926..5c0e939d524 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 bac21217c75..ea9e981ba29 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 6cfdb6ca1f9..a8069809b66 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 57ca944af6b..ba9b6684c9d 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 4b76d62482e..dacee742440 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 2dffce2ce27..8510bd2ecc8 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 dcade9000aa..4633a1f8072 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 b02b76eac0e..b60832af667 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 ef416015574..ee091e29983 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 8024676c65a..64b08ebd462 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 8b767931a89..72f0e7fb28e 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 a77dad5fe77..99e9a66924a 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 326cd9f7e0d..34c41ff54cf 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 a3b3b843a9d..22f967883b0 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 013da083261..b42bfb001ee 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 f8ceba27158..4dcb9110ab0 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 b899212b5ba..713a3112fe2 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 9d168c9e5c1..fe47e6b0a02 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 73cf419be14..6043495bc19 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 109219e03ad..ef8a2dc1757 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 a9f6e8805f3..0e54471a23c 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 4c4b45967e2..77d3653e0c1 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 8d1615f65c6..49be82b146b 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 2f93ccd2758..b313cc20762 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 b5babb37cdf..7e79b2d0437 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 16edbf2e236..2bfb21bc673 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 58e2c8f869a..9fc02ca3b90 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 9223c612001..f0a4ad368ff 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 27fdecd79fa..8850f869d07 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 cddc2dd86b9..af959b9865b 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 3da133e9295..350fdcfd43a 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 1b94677c78d..1a86ddc7c15 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 a3f36517fff..742b82098ff 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 735120f9000..5e7df69d98b 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 7e0d9d2e64e..7c2392453ca 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 6d88e411c0d..2a3da8b195a 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 8079511850a..2c3b7930a73 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 4ae80006678..662f6c33f6c 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 0b756a648ec..a9a07e97244 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 6c7a91ba33b..fb2d28b0306 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 7ffc258b3d6..77f5ae4db3c 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 af49da4b648..53dae3e6eeb 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 cc6713b2950..2b3d6598d91 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 c86cba7cc88..77661de5f07 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 840b79a06b5..34c1400ec15 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 953cbef5a7e..7db6242783c 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 d058210fe11..9ced7db26af 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 89beacbd5cf..2481270f048 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 28263b6dbaf..43d96c41970 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 fe19099b161..0b0fc73df6f 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 4baca5ad6d4..82d59c358f2 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 422f4cf5475..3c1baee994c 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 3804326553c..de0f4d7449d 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 1e7295da57f..9217d137201 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 37d347cd9a0..d4b473c2006 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 0c8583d402c..b726a723cb0 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 63268de4271..dd72a91d087 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 2d64bbd5ad5..b7f1bd6c336 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 fab497b4aaa..179e9037de4 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 76a1b00776e..3d50eafb503 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 567b6329a7c..4497a823d36 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 85bb7b65c5a..a55709b2826 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 f2feb9ef52a..6c6aae35263 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 6ea6bdcabfa..80b90980bcf 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 f9471d99501..e8d1d04b061 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 5a866044bde..d306b152dd0 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 1427ec8eb50..c3b5d6d9256 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 fd7f195a54f..cb51d86d0b2 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 0089d20af2f..ea711a5baf4 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 2d657abf327..f141eaa64f4 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 d61a48b441a..b45977b6953 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 03bca61ad1e..83aa4107748 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 ef65f6026e5..20eab399ba0 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 4df503bcd22..e5456ed8582 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 1b8f59e45e8..3a711300943 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 34d4ded6169..925470cc6a3 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 68dc127bc1e..8a56a464747 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 0da18e5f656..5ba1dbd7804 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 da6b57defe0..690c21f0efc 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 c5a34bc4cad..5a67449fff4 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 fe7857a355e..ee2c82048a9 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 4bdc7c7d92c..4595caec0d7 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 2bbfc31a11a..0f279891d33 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 530153679a9..fa78e6d7b03 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 44e1e3ae76d..c8fa82b4469 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 dd61d1fee12..1f83da465ae 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 ae0daf1213d..b9f5516739b 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 b6895fc396d..6625f0153e8 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 6ff7ff321c3..1022cc9d575 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 3d9f1f76f96..c6441bc4cb1 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 209cc83d65a..8992b8bf7c7 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 2939a27a881..0882c4a1003 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 e48712dbf75..123fb043eb1 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 860490581b1..707a0a95850 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 7f43ffacbd4..7392c74adcc 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 8dbcf0f108a..2607ef63d8d 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 a735e076d99..4b4e3f7f024 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 7d6fc359147..cf76c252787 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 cc89c1967be..446beadb3ff 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 cf2ad80e7ac..058f5ab0a98 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 0d1ff8c1a9a..1cd97874c37 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 aacadb10887..107833dad98 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 1b45e08393b..e8f6af8d582 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 d100dadffe9..f49cc73b293 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 4b6b94ce431..b362e307cf2 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 611606ea38d..84f25ec2577 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 a500af2fc8f..392ff267a26 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 e60888bafc6..8e9d259fa71 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 e27292c0a8a..88201926788 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 ee19358f3fb..845711d24be 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 d312b139b70..c6903f89332 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 a7c3714b18f..269bda83ce9 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 90459ac445c..a5cfd5c2b2b 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 8a46686fcde..ce186bcddf4 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 e37b3f3ea2b..8b92e7c5fd0 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 43a84784ea0..6570731d290 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 46f11057d11..4e884e1c65d 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 ac55bd04699..da69a338f8a 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 525f3e97d19..f5255fd4b50 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 a7deed9afb0..7a5718a1710 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 723e4841f6d..68f5da981fc 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 cacd46bfe42..9a926dc2231 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 339b550730d..b41b2c1e7ce 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 49da30ccf4c..0db63ecd3ef 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 f75f54f4ead..4dc13ce4860 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 6c2737e89e7..8ad9f222faf 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 3e7b603288e..3dd67e733ce 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 1b4525a3549..082a9c0ce58 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 de437414ef1..07646e18ec4 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 de437414ef1..07646e18ec4 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 f1a8e41bc0f..6aa375804f7 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 5f7dfa516eb..a7290f9523d 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 805d20471ae..bca803c1239 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 b874383dcdd..ac5aff0d874 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 742cae6d201..4d5a6da8b8e 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 d5b534adb49..021913636bd 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 e87d750ecaf..d8c8e0b7685 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." }