diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index 74e5f89c00..77b860051d 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -210,6 +210,7 @@ export function lower( return Ok({ id, params, + fnType: parent == null ? env.fnType : "Other", returnType: null, // TODO: extract the actual return type node if present body: builder.build(), context, diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts index 4bd46477e7..0f56cce988 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts @@ -8,7 +8,7 @@ import * as t from "@babel/types"; import { CompilerError, CompilerErrorDetailOptions } from "../CompilerError"; import { assertExhaustive } from "../Utils/utils"; -import { Environment } from "./Environment"; +import { Environment, ReactFunctionType } from "./Environment"; import { HookKind } from "./ObjectShape"; import { Type } from "./Types"; @@ -240,6 +240,7 @@ export type ReactiveTryTerminal = { export type HIRFunction = { loc: SourceLocation; id: string | null; + fnType: ReactFunctionType; env: Environment; params: Array; returnType: t.FlowType | t.TSType | null; diff --git a/compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts b/compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts index 518ec1b504..edb3a9df31 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts @@ -137,7 +137,7 @@ export default function inferReferenceEffects( reason: new Set([ValueReason.ReactiveFunctionArgument]), }; - if (fn.env.fnType === "Component") { + if (fn.fnType === "Component") { CompilerError.invariant(fn.params.length <= 2, { reason: "Expected React component to have not more than two parameters: one for props and for ref", diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.expect.md new file mode 100644 index 0000000000..f0c6f0e8f9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.expect.md @@ -0,0 +1,53 @@ + +## Input + +```javascript +import { Stringify } from "shared-runtime"; +function Component(props) { + const cb = (x, y, z) => x + y + z; + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 0 }], +}; + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +import { Stringify } from "shared-runtime"; +function Component(props) { + const $ = useMemoCache(3); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (x, y, z) => x + y + z; + $[0] = t0; + } else { + t0 = $[0]; + } + const cb = t0; + let t1; + if ($[1] !== props.id) { + t1 = ; + $[1] = props.id; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 0 }], +}; + +``` + +### Eval output +(kind: ok)
{"cb":"[[ function params=3 ]]","id":0}
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.tsx b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.tsx new file mode 100644 index 0000000000..92525fd6a6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/component-inner-function-with-many-args.tsx @@ -0,0 +1,11 @@ +import { Stringify } from "shared-runtime"; +function Component(props) { + const cb = (x, y, z) => x + y + z; + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 0 }], +};