Commit Graph

2629 Commits

Author SHA1 Message Date
mofeiZ
93b61fc4ec
[compiler][ez] Stop bailing out early for hoisted gated functions (#32597)
Some code movement for the next PR
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32597).
* #32598
* __->__ #32597
2025-03-13 19:08:38 -04:00
mofeiZ
f457d0b4c6
[compiler][ez] Only fail gating hoisting check for referenced identifiers (#32596)
Reduce false positive bailouts by using the same
`isReferencedIdentifier` logic that the compiler also uses for
determining context variables and a function's own hoisted declarations.

Details:
Previously, we counted every babel identifier as a reference. This is
problematic because babel counts most string symbols as an identifier.

```js
print(x);  // x is an identifier as expected
obj.x      // x is.. also an identifier here
{x: 2}     // x is also an identifier here
```

This PR adds a check for `isReferencedIdentifier`. Note that only
non-lval
references pass this check. This should be fine as we don't need to
hoist function declarations before writes to the same lvalue (which
should error in strict mode anyways)
```js
print(x);  // isReferencedIdentifier(x) -> true
obj.x      // isReferencedIdentifier(x) -> false
{x: 2}     // isReferencedIdentifier(x) -> false
x = 2      // isReferencedIdentifier(x) -> false
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32596).
* __->__ #32596
* #32595
* #32594
* #32593
* #32522
* #32521
2025-03-13 12:10:22 -04:00
mofeiZ
1c79cb82ab
[compiler][ez] Move compiler gating tests (#32595)
Move all gating tests to `gating/`
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32595).
* #32596
* __->__ #32595
* #32594
* #32593
* #32522
* #32521
2025-03-13 12:06:48 -04:00
mofeiZ
89a46a57df
[compiler][optim] more shapes for mixedreadonly (#32594)
- Add `at`, `indexOf`, and `includes`
- Optimize MixedReadOnly which is currently only used by hook return
values. Hook return values are typed as Frozen, this change propagates
that to return values of aliasing function calls (such as `at`). One
potential issue is that developers may pass
`enableAssumeHooksFollowRulesOfReact:false` and set
`transitiveMixedData`, expecting their transitive mixed data to be
mutable. This is a bit of an edge case and already doesn't have clear
semantics.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32594).
* #32596
* #32595
* __->__ #32594
* #32593
* #32522
* #32521
2025-03-13 11:59:50 -04:00
mofeiZ
eb53139ee5
[compiler][optim] infer mixedReadOnly for numeric and computed properties (#32593)
Expand type inference to infer mixedReadOnly types for numeric and
computed property accesses.
```js
function Component({idx})
  const data = useFragment(...)
  // we want to type `posts` correctly as Array
  const posts = data.viewers[idx].posts.slice(0, 5);
  // ...
}
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32593).
* #32596
* #32595
* #32594
* __->__ #32593
* #32522
* #32521
2025-03-13 11:58:40 -04:00
mofeiZ
38a7600920
[compiler][optim] Add shape for Array.from (#32522)
(see title)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32522).
* #32596
* #32595
* #32594
* #32593
* __->__ #32522
* #32521
2025-03-13 11:58:17 -04:00
mofeiZ
ed1264f077
[compiler] Patch array and argument spread mutability (#32521)
Array and argument spreads may mutate stateful iterables. Spread sites
should have `ConditionallyMutate` effects (e.g. mutate if the ValueKind
is mutable, otherwise read).

See
- [ecma spec (13.2.4.1 Runtime Semantics: ArrayAccumulation.
SpreadElement : ...
AssignmentExpression)](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-arrayaccumulation).
- [ecma spec 13.3.8.1 Runtime Semantics:
ArgumentListEvaluation](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-argumentlistevaluation)

Note that
- Object and JSX Attribute spreads do not evaluate iterables (srcs
[mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#description),
[ecma](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-propertydefinitionevaluation))
- An ideal mutability inference system could model known collections
(i.e. Arrays or Sets) as a "mutated collection of non-mutable objects"
(see `todo-granular-iterator-semantics`), but this is not what we do
today. As such, an array / argument spread will always extend the range
of built-in arrays, sets, etc
- Due to HIR limitations, call expressions with argument spreads may
cause unnecessary bailouts and/or scope merging when we know the call
itself has `freeze`, `capture`, or `read` semantics (e.g.
`useHook(...mutableValue)`)
We can deal with this by rewriting these call instructions to (1) create
an intermediate array to consume the iterator and (2) capture and spread
the array at the callsite
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32521).
* #32596
* #32595
* #32594
* #32593
* #32522
* __->__ #32521
2025-03-13 11:58:02 -04:00
Tyler Scott Williams
ef06b54f8d
fix: clarify which mobx libs are not compatible with compiler (#32570)
## Summary

Right now, `react-compiler-healthcheck` flags `mobx` as a "known
incompatible library". But it's not precisely *MobX* that's
incompatible. It's the observer HOC that comes from `mobx-react` and
`mobx-react-lite`.

I've been working on
[mst-use-observable](https://github.com/coolsoftwaretyler/mst-use-observable),
which makes MobX-State-Tree compatible with the compiler. However,
projects that use `mobx-state-tree` and `mst-use-observable` will still
depend on `mobx` as a dependency.

And there [have been efforts in the past to write a hook for
observability](https://github.com/mobxjs/mobx/discussions/2566). So it's
possible that MobX could become compatible, so long as authors access it
with a hook, rather than the HOC.

I would like to propose updating the health check to be a little more
precise and flag the HOC dependencies, rather than MobX itself.

Thanks in advance for your consideration!

## How did you test this change?

`npx react-compiler-healthcheck` shouldn't flag on `mobx` in
dependencies, but will for `mobx-react-lite` and `mobx-react`.

Test suites, formatting, linting, all passed.

---------

Co-authored-by: lauren <poteto@users.noreply.github.com>
2025-03-13 11:46:26 -04:00
Mohhamad Hussain
1b77c3d7b9
Update DEVELOPMENT_GUIDE.md (#32281)
fix: update CONTRIBUTING.md link path

Updated the relative path to CONTRIBUTING.md from `../CONTRIBUTING.md`
to `./../../CONTRIBUTING.md` to ensure the correct file is referenced.

<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
2025-03-13 11:45:26 -04:00
michael faith
5ccfcd17ff
feat(eslint-plugin-react-hooks): merge rule from eslint-plugin-react-compiler into react-hooks plugin (#32416)
This change merges the `react-compiler` rule from
`eslint-plugin-react-compiler` into the `eslint-plugin-react-hooks`
plugin. In order to do the move in a way that keeps commit history with
the moved files, but also no remove them from their origin until a
future cleanup change can be done, I did the `git mv` first, and then
recreated the files that were moved in their original places, as a
separate commit. Unfortunately GH shows the moved files as new instead
of the ones that are truly new. But in the IDE and `git blame`, commit
history is intact with the moved files.

Since this change adds new dependencies, and one of those dependencies
has a higher `engines` declaration for `node` than what the plugin
currently has, this is technically a breaking change and will have to go
out as part of a major release.

### Related Changes
- https://github.com/facebook/react/pull/32458

---------

Co-authored-by: Lauren Tan <poteto@users.noreply.github.com>
2025-03-12 21:43:06 -04:00
lauren
f31779a112
[ez] Run Prettier on eslint-plugin-react-compiler/src/types (#32590)
Extracting portions of #32416 for easier review.

This PR contains small formatting fixes.

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32590).
* #32592
* #32591
* __->__ #32590
* #32589
* #32588

---------

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
2025-03-12 19:12:22 -04:00
lauren
5de83dcc0f
[playground] Use onMount to check if the editor is available (#32586)
Playground test flakiness seems to be fixed but adding this as an extra
precaution
2025-03-12 18:27:15 -04:00
lauren
26bca0005c
[playground] Wait for Monaco to fully load (#32584)
I'm not sure what exactly is causing the flakiness in the playground e2e
tests but I suspect it's some kind of timing issue.

Let's try waiting for Monaco to be fully initialized before running
tests.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32584).
* __->__ #32584
* #32583
2025-03-12 17:47:24 -04:00
lauren
e0e98d9560
[playground] Update various deps (#32583)
Updates various deps to align with the rest of the codebase.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32583).
* #32584
* __->__ #32583
2025-03-12 17:47:12 -04:00
lauren
4ab827b869
[compiler] Dedupe @babel/types (#32581)
Extracting portions of #32416 for easier review. This PR dedupes
@babel/types to resolve to 7.26.3, for compatibility in the root
workspace where eslint-plugin-react-hooks resides.

I also needed to update @babel/preset-typescript in snap.

The compiler changes in HIR and ReactiveScopes were needed due to types
changing. Notably, Babel [added support for optional chaining
assignment](https://github.com/babel/babel/pull/15751) (currently [Stage
1](https://github.com/tc39/proposal-optional-chaining-assignment)), so
in the latest versions of @babel/types, AssignmentExpression.left can
now also be of t.OptionalMemberExpression.

Given that this is in Stage 1, the compiler probably shouldn't support
this syntax, so this PR updates HIR to bailout with a TODO if there is a
non LVal on the lhs of an Assignment Expression.

There was also a small superficial SourceLocation change needed in
`InferReactiveScopeVariables` as Babel 8 changes were [accidentally
released in
7](https://github.com/babel/babel/issues/10746#issuecomment-2699146670).
It doesn't affect our analysis so it seems fine to just update with the
new properties.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32581).
* #32582
* __->__ #32581

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
2025-03-12 17:02:10 -04:00
mofeiZ
3456b6634a
[compiler] Repro for object spread and Array.from with mutable iterators (#32520)
See newly added test fixtures. Repros fixed in later prs of this stack
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32520).
* #32522
* #32521
* __->__ #32520
2025-03-12 15:08:55 -04:00
lauren
0ca3deebcf
[rcr] Fix incorrect output platform (#32569)
Accidentally copypasted the wrong esbuild config.
2025-03-11 10:41:48 -04:00
lauren
00aa0043c7
[compiler] Migrate compiler packages to tsup (#32550)
Currently in the `compiler` workspace, we invoke esbuild directly to
build most packages (with the exception of `snap`). This has been mostly
fine, but does not allow us to do things like generate type declaration
files.

I would like #32416 to be able to consume the merged
eslint-plugin-react-compiler from source rather than via npm, and one of
the things that has come up from my exploration in that stack using the
compiler from source is that babel-plugin-react-compiler is missing type
declarations. This is primarily because React's build process uses
rollup + rollup-plugin-typescript, which runs tsc. So the merged plugin
needs to typecheck properly in order to build. An alternative might be
to migrate to something like babel with rollup instead to simply strip
types rather than typecheck before building. The minor downside of that
approach is that we would need to manually maintain a d.ts file for
eslint-plugin-react-hooks. For now I would like to see if this PR helps
us make progress rather than go for the slightly worse alternative.

[`tsup`](https://github.com/egoist/tsup) is esbuild based so build
performance is comparable. It is slower when generating d.ts files, but
it's still much faster than rollup which we used prior to esbuild. For
now, I have turned off `dts` by default, and it is only passed when
publishing on npm.

If you want to also generate d.ts files you can run `yarn build --dts`.

```
# BEFORE: build all compiler packages (esbuild)
$ time yarn build

  Done in 15.61s.
yarn build  13.82s user 1.54s system 96% cpu 15.842 total

# ---

# AFTER: build all compiler packages (tsup)
$ time yarn build

  Done in 12.39s.
yarn build  12.58s user 1.68s system 106% cpu 13.350 total

# ---

# AFTER: build all compiler packages and type declarations (tsup)
$ time yarn build --dts

  Done in 30.69s.
yarn build  43.57s user 3.20s system 150% cpu 31.061 total
```

I still need to test if this unblocks #32416 but this stack can be
landed independently though as we could probably just release type
declarations on npm. No one should be using the compiler directly, but
if they really wanted to, lack of type declarations would not stop them
(cf React secret internals).

Note that I still kept esbuild as we still use it directly for forgive.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32550).
* #32551
* __->__ #32550
2025-03-07 16:41:55 -05:00
lauren
9e9b54d7f6
[compiler] Make CompilerError compatible with reflection (#32539) 2025-03-06 13:06:36 -05:00
Jordan Brown
d4e24b349e
[autodeps] Do not include nonreactive refs or setStates in inferred deps (#32236) 2025-03-03 15:26:57 -05:00
Jordan Brown
bdce84a539
[autodeps] Support namespaces (#32162)
Summary: Correctly supports React.useEffect when React is
imported as `import * as React from 'react'`
(as well as other namespaces as specified in the config).
2025-03-03 15:20:41 -05:00
Jordan Brown
a1f157e9a9
[compiler][ez] Add validation for auto-deps config (#31813)
numRequiredArgs has to be more than 0 and the pass depends on that

--
2025-03-03 14:39:03 -05:00
lauren
ebc22ef7e1
[forgive][ez] Ignore test file (#32477) 2025-02-25 19:09:21 -05:00
lauren
92e65ca68f
[forgive] Add basic codelens provider (#32476)
Adds a first codelens provider for successfully compiled functions. A
later PR will add an actual command that will fire when the codelens is
clicked

![Screenshot 2025-02-25 at 6 40
20 PM](https://github.com/user-attachments/assets/924586e0-f70a-45d1-b0e6-a89af9371c8d)
2025-02-25 18:55:49 -05:00
lauren
d42a90cf4f
[forgive] Init (#31918)
Init basic LSP. At the moment the extension doesn't do anything
interesting, but it does compile successfully.
2025-02-25 12:19:11 -05:00
lauren
58def9f2e6
[forgive] Add build scripts (#31927)
Adds basic build scripts.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31927).
* #31918
* __->__ #31927
2025-02-25 12:16:10 -05:00
lauren
dd9974bbb8
[forgive] Scaffold workspaces (#31917)
Basic workspace setup for Forgive.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31917).
* #31918
* #31927
* __->__ #31917
2025-02-25 12:08:46 -05:00
mofeiZ
5f31228d7d
[compiler][playground] Upgrade to Next 15.2.0-canary.64 (#32428)
Upgrade compiler playground to use the newest nextjs release, which
includes react compiler transform pipeline optimizations
https://github.com/vercel/next.js/pull/75676/.

Also made a drive-by fix to avoid the error `Cannot update a component
('Router') while rendering a different component ('StoreProvider'). To
locate the bad setState() call inside 'StoreProvider', follow the stack
trace as described in https://react.dev/link/setstate-in-render`. The
bad setState came from `history.replaceState({}, '', \`#${hash}\`);`.

Prior to this, playground ran side effects in a reducer (i.e. during
render). These have now been moved an effect.
2025-02-20 12:28:34 -05:00
mofeiZ
fcb4e0f137
[compiler] remove invariant to account for backedges (#32417)
Fixes https://github.com/facebook/react/issues/32269, see comments for
details.

Added test fixture for repro
2025-02-19 16:22:53 -05:00
mofeiZ
86b1913474
[compiler][be] Clean up bug test fixtures; evaluate more fixtures (#31812)
Test fixtures testing different compiler features (e.g. non-auto
memoization) should live in separate directories.

Remove bug-prefixed fixtures that have since been fixed

Add test evaluator export to more fixtures
2025-02-18 12:25:33 -07:00
mofeiZ
a9575dcf62
[compiler] Represent array accesses with PropertyLoad (#32287)
Prior to this PR, our HIR represented property access with numeric
literals (e.g. `myVar[0]`) as ComputedLoads. This means that they were
subject to some deopts (most notably, not being easily dedupable /
hoistable as dependencies).

Now, `PropertyLoad`, `PropertyStore`, etc reference numeric and string
literals (although not yet string literals that aren't valid babel
identifiers). The difference between PropertyLoad and ComputedLoad is
fuzzy now (maybe we should rename these).
- PropertyLoad: property keys are string and numeric literals, only when
the string literals are valid babel identifiers
- ComputedLoad: non-valid babel identifier string literals (rare) and
other non-literal expressions

The biggest feature from this PR is that it trivially enables
array-indicing expressions as dependencies. The compiler can also
specify global and imported types for arrays (e.g. return value of
`useState`)


I'm happy to close this if it complicates more than it helps --
alternative options are to entirely rely on instruction reordering-based
approaches like ReactiveGraphIR or make dependency-specific parsing +
hoisting logic more robust.
2025-02-18 11:54:20 -07:00
mofeiZ
19cc5af41e
[compiler] Clean up deadcode: DeriveMinimalDeps (non-hir fork) (#32104)
(title)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32104).
* #32287
* __->__ #32104
* #32098
* #32097
2025-02-18 09:38:02 -07:00
mofeiZ
498514c04d
[compiler] Clean up deadcode: ReactiveFunctionValue (#32098)
(title)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32098).
* #32287
* #32104
* __->__ #32098
* #32097
2025-02-18 09:37:34 -07:00
mofeiZ
a92acdb188
[compiler] Remove redundant InferMutableContextVariables (#32097)
This removes special casing for `PropertyStore` mutability inference
within FunctionExpressions.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32097).
* #32287
* #32104
* #32098
* __->__ #32097
2025-02-18 09:37:21 -07:00
mofeiZ
d99f8bba2e
[compiler] Delete LoweredFunction.dependencies and hoisted instructions (#32096)
LoweredFunction dependencies were exclusively used for dependency
extraction (in `propagateScopeDeps`). Now that we have a
`propagateScopeDepsHIR` that recursively traverses into nested
functions, we can delete `dependencies` and their associated synthetic
`LoadLocal`/`PropertyLoad` instructions.

[Internal snapshot
diff](https://www.internalfb.com/phabricator/paste/view/P1716950202) for
this change shows ~.2% of files changed. I [read through ~60 of the
changed
files](https://www.internalfb.com/phabricator/paste/view/P1733074307)
- most changes are due to better outlining (due to better DCE)
- a few changes in memo inference are due to changed ordering
```
// source
arr.map(() => contextVar.inner);

// previous instructions
$0 = LoadLocal arr
$1 = $0.map
// Below instructions are synthetic
$2 = LoadLocal contextVar
$3 = $2.inner
$4 = Function deps=$3 context=contextVar {
  ...
}
```
- a few changes are effectively bugfixes (see
`aliased-nested-scope-fn-expr`)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32096).
* #32099
* #32286
* #32104
* #32098
* #32097
* __->__ #32096
2025-02-18 09:32:49 -07:00
lauren
d814852baf
[compiler] Upgrade esbuild (#32368)
Just a simple upgrade
2025-02-12 11:59:56 -05:00
lauren
989b0cccc2
[compiler] Add simple walltime measurement (#32331)
Adds a new Timing logger event to the compiler which currently only
records the walltime of running the compiler from the time the babel
plugin's Program visitor enters to the time it exits.

To enable, run the compiler with `ENABLE_REACT_COMPILER_TIMINGS=1 ...`
or `export ENABLE_REACT_COMPILER_TIMINGS=1` to set it by default.
2025-02-07 16:04:46 -05:00
inottn
76e44c2911
[compiler] Improve error messages for unhandled terminal and instruction kinds (#32324)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
Improve the error message, as the value is currently an object instead
of a string, which results in it being converted to '[object Object]'.

## How did you test this change?
Already tested locally.
<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
2025-02-07 15:48:03 -05:00
inottn
10a4c88f58
[compiler] Handle TSInstantiationExpression in lowerExpression (#32302)
Fix #31745
2025-02-03 08:41:04 -08:00
mofeiZ
152bfe3769
[compiler][rfc] Hacky retry pipeline for fire (#32164)
Hacky retry pipeline for when transforming `fire(...)` calls encounters
validation, todo, or memoization invariant bailouts. Would love feedback
on how we implement this to be extensible to other compiler
non-memoization features (e.g. inlineJSX)

Some observations:
- Compiler "front-end" passes (e.g. lower, type, effect, and mutability
inferences) should be shared for all compiler features -- memo and
otherwise
- Many passes (anything dealing with reactive scope ranges, scope blocks
/ dependencies, and optimizations such as ReactiveIR #31974) can be left
out of the retry pipeline. This PR hackily skips memoization features by
removing reactive scope creation, but we probably should restructure the
pipeline to skip these entirely on a retry
- We should maintain a canonical set of "validation flags"

Note the newly added fixtures are prefixed with `bailout-...` when the
retry fire pipeline is used. These fixture outputs contain correctly
inserted `useFire` calls and no memoization.
2025-01-31 15:57:26 -08:00
michael faith
a657bc5dee
build(eslint-plugin-react-hooks): add dev dependencies for typescript migration (#32279)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

Contributing to https://github.com/facebook/react/pull/32240, this
change adds the dev dependencies needed to support the migration of the
plugin to typescript.
2025-01-31 14:32:23 -05:00
Jeremy JIANG
dc44bca85b
fix(react-compiler-healthcheck): Add shebang to banner (#32225)
## Summary

PR https://github.com/facebook/react/pull/31963 migrated the bundler
from Rollup to esbuild, but the `react-compiler-healthcheck` script
lacks a shebang, leading to issues with `npx` not being able to execute
it.


dc7578290f/compiler/packages/react-compiler-healthcheck/rollup.config.js (L60-L78)


9eabb37338/compiler/packages/react-compiler-healthcheck/scripts/build.js (L38-L53)

## How did you test this change?

**Before**

(fail)

```shell
(main)> npx --version
10.5.0
(main)> npx react-compiler-healthcheck
/home/jeremy/.npm/_npx/67b118a83a29962c/node_modules/.bin/react-compiler-healthcheck: line 1: /bin: Is a directory
/home/jeremy/.npm/_npx/67b118a83a29962c/node_modules/.bin/react-compiler-healthcheck: line 2: syntax error near unexpected token `('
/home/jeremy/.npm/_npx/67b118a83a29962c/node_modules/.bin/react-compiler-healthcheck: line 2: ` * Copyright (c) Meta Platforms, Inc. and affiliates.'
```

**After**

```shell
(main)> npx react-compiler-healthcheck
Successfully compiled 108 out of 146 components.
StrictMode usage not found.
Found no usage of incompatible libraries.
```
2025-01-27 11:59:25 -05:00
Joe Savona
9eabb37338 [compiler][be] Remove unused experimental Rust port
I wrote this a couple summers back as an experiment to see how easily we could translate the compiler to Rust. We make extensive use of in-place mutation of the IR, and the experiment proved that this we can get reasonable ergonomics for this in Rust which was cool. We've since ended up using some of the code here for Relay, allowing Relay Compiler to parse JS files to do more fine-grained extraction of data. For React Compiler though, we plan to continue using JavaScript and explore lightweight native wrappers for things like OXC and SWC plugins. We're also working with the Hermes team to eventually compile the compiler with Static Hermes.

As Tomo always says: always bet on JavaScript.

ghstack-source-id: c5770a2efc
Pull Request resolved: https://github.com/facebook/react/pull/32219
2025-01-24 12:23:31 -08:00
Jordan Brown
ae9017ceab
Move effect dep inference tests to infer-effect-dependencies directory (#32161)
Summary: Grouping them to make it easy to see that they are all related

Test Plan:
2025-01-22 17:09:41 -05:00
mofeiZ
a0b91fbd65
[compiler][ez] Fix main (bad rebase / amend for #32095) (#32160)
See title: this fixes test cases broken by
https://github.com/facebook/react/pull/32095 adding instead of moving
new test fixtures
2025-01-22 16:21:53 -05:00
mofeiZ
b83090fca2
[compiler] Fix invalid Array.map type (#32095)
See test fixture
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32095).
* #32099
* #32104
* #32098
* #32097
* #32096
* __->__ #32095
* #32094
* #32093
2025-01-22 15:02:51 -05:00
mofeiZ
deba48a727
[compiler] Repro for invalid Array.map type (#32094)
See test fixture
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32094).
* #32099
* #32104
* #32098
* #32097
* #32096
* #32095
* __->__ #32094
* #32093
2025-01-22 14:58:52 -05:00
mofeiZ
b6b33bfb92
[compiler][ez] rewrite invariant in InferReferenceEffects (#32093)
Small patch to pass aliased context values into
`Object|ArrayExpression`s
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32093).
* #32099
* #32104
* #32098
* #32097
* #32096
* #32095
* #32094
* __->__ #32093
2025-01-22 14:34:08 -05:00
mofeiZ
7c864c9834
[compiler][ez] Patch for JSX escape sequences in @babel/generator (#32131)
Fall back to using JSXExpressionContainer for strings potentially
containing escape sequences (a single backslash) to fix
https://github.com/facebook/react/issues/32123. This is an extension of
https://github.com/facebook/react/pull/29079
2025-01-22 14:22:35 -05:00
mofeiZ
19557443c8
[compiler][repro] JSX escape sequences not printed correctly by @babel/generator (#32130)
Repro for https://github.com/facebook/react/issues/32123

Note that this is only a bug when calling `@babel/generator:generate()`
before transforming JSX.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32130).
* #32131
* __->__ #32130
2025-01-22 13:52:05 -05:00
Alex Yang
e5a2062c80
fix(react-compiler): JSXText emits incorrect with bracket (#32138)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

Our [LlamaIndex](https://www.llamaindex.ai/) Product is blocked by this
bug

Fixes: https://github.com/facebook/react/issues/32137

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
2025-01-22 12:04:59 -05:00
藍+85CD
9b62ee71f4
docs(eslint-plugin-react-compiler): fix typo (#32149) 2025-01-22 16:59:50 +01:00
Orta Therox
18eaf51bd5
Support eslint 8+ flat plugin syntax out of the box for eslint-plugin-react-compiler (#32120)
## Summary

The current docs for the react compiler eslint plugin is based on
integrating with the old-style eslint config format. This is generally
fine, but most plugins (and the [official
docs](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file))
are now describing themselves in the new format.

This PR has two changes:

- Update the exports to include a "flat configuration"
- Adds a README change describing how to handle both configs

The solution is semi-based on @guillaumebrunerie's answer in
https://github.com/reactwg/react-compiler/discussions/25 mixed with
reading the source code for
[eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/src/index.ts)

## How did you test this change?

I faked this API in the most recent deploy:

![Screenshot 2025-01-18 at 19 58
44](https://github.com/user-attachments/assets/ae0e4bea-fb96-4073-a5f7-c886d087b6af)

Then used that in my app:

![Screenshot 2025-01-18 at 20 04
33](https://github.com/user-attachments/assets/21f77158-7535-453a-b988-49cf59d22d71)

and get myself some compiler messages:

```
/Users/orta/dev/app/apps/puzzmo.com/src/palette/HoverPopover.tsx
  31:37  error  Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)  react-compiler/react-compiler

/Users/orta/dev/app/apps/puzzmo.com/src/components/gameplay/PlayGamePauseOverlay.tsx
   33:7   error  Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)  react-compiler/react-compiler
   35:5   error  Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)  react-compiler/react-compiler
```
2025-01-18 17:41:34 -05:00
Joseph Savona
7f3826e8e4
[compiler] validation against calling impure functions (#31960)
For now we just reject all calls of impure functions, and the validation
is off by default. Going forward we can make this more precise and only
reject impure functions called during render.

Note that I was intentionally imprecise in the return type of these
functions in order to avoid changing output of existing code. We lie to
the compiler and say that Date.now, performance.now, and Math.random
return unknown mutable objects rather than primitives. Once the
validation is complete and vetted we can switch this to be more precise.
2025-01-17 09:04:02 -08:00
lauren
35dcf02b04
[rcr] Always target node (#32091)
Alternative to #32071. As a follow up to #31993, the `platform` target
was incorrectly being set to `browser` since it was the default argument
for the build script. This corrects it to `node` and `cjs` which I think
should resolve node 20 issues.
2025-01-16 13:37:13 -05:00
michael faith
b3a95caf61
fix(eslint-plugin-react-compiler): support v9 context api (#32045)
## Summary

This change fixes a gap in the plugin's support of eslint v9. In one
place that it's using the `SourceCode` api, it's correctly considering
v9's api. But in the other place where `SourceCode` is used, it's only
using the legacy api, which was removed in v9.
2025-01-13 13:49:31 -05:00
mofeiZ
af8532f251
[compiler][ez] Patch compilationMode:infer object method edge case (#32055)
Fix for  https://github.com/facebook/react/issues/31180
2025-01-13 12:18:59 -05:00
mofeiZ
d16fe4be5b
[compiler] Playground qol: shared compilation option directives with tests (#32012)
- Adds @compilationMode(all|infer|syntax|annotation) and
@panicMode(none) directives. This is now shared with our test infra
- Playground still defaults to `infer` mode while tests default to `all`
mode
- See added fixture tests
2025-01-09 12:38:16 -05:00
lauren
8932ca32f4
[playground] Partially revert #32009 (#32035)
I had forgotten that our default error reporting threshold was `none`
due to the fact that build pipelines should not throw errors. This
resets it back to throwing on all errors which mostly is the same as the
eslint plugin.

Closes #32014.
2025-01-09 12:21:05 -05:00
lauren
6efbc0897f
[playground] Use default compiler config (#32009)
The playground's compilation mode is currently set to 'all' along with
reporting all errors.

This tends to be misleading since people usually expect a 1:1 match
between how the playground works with what the compiler does in their
codebase, eg https://github.com/reactwg/react-compiler/discussions/51.
2025-01-07 11:53:27 -05:00
lauren
11df5224e6
[rcr] Generate ts defs (#31994)
This was accidentally removed in the esbuild transition.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31994).
* #31995
* __->__ #31994
2025-01-06 11:01:38 -05:00
Cody Olsen
9627d71c50
fix: react-compiler-runtime should be cjs (#31993) 2025-01-06 09:06:09 -05:00
lauren
220dece92b
[compiler] Switch to esbuild (#31963)
This migrates the compiler's bundler to esbuild instead of rollup.
Unlike React, our bundling use cases are far simpler since the majority
of our packages are meant to be run on node. Rollup was adding
considerable build time overhead whereas esbuild remains fast and has
all the functionality we need out of the box.


### Before
```
time yarn workspaces run build
yarn workspaces v1.22.22

> babel-plugin-react-compiler
yarn run v1.22.22
$ rimraf dist && rollup --config --bundleConfigAsCjs

src/index.ts → dist/index.js...
(!) Circular dependencies
# ...
created dist/index.js in 15.5s
  Done in 16.45s.

> eslint-plugin-react-compiler
yarn run v1.22.22
$ rimraf dist && rollup --config --bundleConfigAsCjs

src/index.ts → dist/index.js...
(!) Circular dependencies
# ...
created dist/index.js in 9.1s
  Done in 10.11s.

> make-read-only-util
yarn run v1.22.22
warning package.json: No license field
$ tsc
  Done in 1.81s.

> react-compiler-healthcheck
yarn run v1.22.22
$ rimraf dist && rollup --config --bundleConfigAsCjs

src/index.ts → dist/index.js...
(!) Circular dependencies
# ...
created dist/index.js in 8.7s
  Done in 10.43s.

> react-compiler-runtime
yarn run v1.22.22
$ rimraf dist && rollup --config --bundleConfigAsCjs

src/index.ts → dist/index.js...
(!) src/index.ts (1:0): Module level directives cause errors when bundled, "use no memo" in "src/index.ts" was ignored.
# ...
created dist/index.js in 1.1s
  Done in 1.82s.

> snap
yarn run v1.22.22
$ rimraf dist && concurrently -n snap,runtime "tsc --build" "yarn --silent workspace react-compiler-runtime build --silent"
$ rimraf dist && rollup --config --bundleConfigAsCjs --silent
[runtime] yarn --silent workspace react-compiler-runtime build --silent exited with code 0
[snap] tsc --build exited with code 0
  Done in 5.73s.
  Done in 47.30s.
yarn workspaces run build  75.92s user 5.48s system 170% cpu 47.821 total
```

### After

```
time yarn workspaces run build
yarn workspaces v1.22.22

> babel-plugin-react-compiler
yarn run v1.22.22
$ rimraf dist && scripts/build.js
  Done in 1.02s.

> eslint-plugin-react-compiler
yarn run v1.22.22
$ rimraf dist && scripts/build.js
  Done in 0.93s.

> make-read-only-util
yarn run v1.22.22
warning package.json: No license field
$ rimraf dist && scripts/build.js
  Done in 0.89s.

> react-compiler-healthcheck
yarn run v1.22.22
$ rimraf dist && scripts/build.js
  Done in 0.58s.

> react-compiler-runtime
yarn run v1.22.22
$ rimraf dist && scripts/build.js
  Done in 0.48s.

> snap
yarn run v1.22.22
$ rimraf dist && concurrently -n snap,runtime "tsc --build" "yarn --silent workspace react-compiler-runtime build"
$ rimraf dist && scripts/build.js
[runtime] yarn --silent workspace react-compiler-runtime build exited with code 0
[snap] tsc --build exited with code 0
  Done in 4.69s.
  Done in 9.46s.
yarn workspaces run build  9.70s user 0.99s system 103% cpu 10.329 total
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31963).
* #31964
* __->__ #31963
* #31962
2025-01-02 16:59:56 -05:00
lauren
c784273bcc
[compiler] Update prettier-plugin-hermes-parser (#31962)
Just updating this package.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31962).
* #31964
* #31963
* __->__ #31962
2025-01-02 16:59:45 -05:00
lauren
c8c89fab5b
[compiler] Update rollup plugins (#31919)
Update our various compiler rollup plugins.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31919).
* #31927
* #31918
* #31917
* #31916
* __->__ #31919
2025-01-02 11:24:26 -05:00
lauren
4309bde2b4
[rcr] Relax react peer dep requirement (#31915)
There's no real reason to restrict the React peer dep to
non-experimental, so relax it.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31915).
* #31919
* #31918
* #31917
* #31916
* __->__ #31915
* #31920
2024-12-27 14:27:43 -05:00
lauren
fc8a898dd1
[compiler] Fix broken fire snapshot (#31920)
This was not committed in #31811
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31920).
* #31919
* #31918
* #31917
* #31916
* #31915
* __->__ #31920
2024-12-26 14:58:37 -05:00
Jordan Brown
6907aa2a30
[compiler] Rewrite effect dep arrays that use fire (#31811)
If an effect uses a dep array, also rewrite the dep array to use the
fire binding

--
2024-12-20 17:16:59 -05:00
Jordan Brown
45a720f7c7
[compile] Error on fire outside of effects and ensure correct compilation, correct import (#31798)
Traverse the compiled functions to ensure there are no lingering fires
and that all
fire calls are inside an effect lambda.

Also corrects the import to import from the compiler runtime instead


--
2024-12-20 16:55:01 -05:00
Jordan Brown
ab27231dc5
[compiler] add fire imports (#31797)
Summary:

Adds import {useFire} from 'react' when fire syntax is used.

This is experimentation and may not become a stable feature in the
compiler.

--
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31797).
* #31811
* #31798
* __->__ #31797
2024-12-20 15:25:30 -05:00
Jordan Brown
03297e048d
[compiler] transform fire calls (#31796)
This is the diff with the meaningful changes. The approach is:
1. Collect fire callees and remove fire() calls, create a new binding
for the useFire result
2. Update LoadLocals for captured callees to point to the useFire result
3. Update function context to reference useFire results
4. Insert useFire calls after getting to the component scope

This approach aims to minimize the amount of new bindings we introduce
for the function expressions
to minimize bookkeeping for dependency arrays. We keep all of the
LoadLocals leading up to function
calls as they are and insert new instructions to load the originally
captured function, call useFire,
and store the result in a new promoted temporary. The lvalues that
referenced the original callee are
changed to point to the new useFire result.

This is the minimal diff to implement the expected behavior (up to
importing the useFire call, next diff)
and further stacked diffs implement error handling. The rules for fire
are:
1. If you use fire for a callee in the effect once you must use it for
every time you call it in that effect
2. You can only use fire in a useEffect lambda/functions defined inside
the useEffect lambda

There is still more work to do here, like updating the effect dependency
array and handling object methods

--
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31796).
* #31811
* #31798
* #31797
* __->__ #31796
2024-12-20 15:09:09 -05:00
Joseph Savona
6a3d6a4382
[compiler] Allow type cast expressions with refs (#31871)
We report a false positive for the combination of a ref-accessing
function placed inside an array which is they type-cast. Here we teach
ref validation about type casts. I also tried other variants like
`return ref as const` but those already worked.

Closes #31864
2024-12-20 08:56:48 -08:00
mofeiZ
8a7b30669a
[compiler][ez] Add shape for global Object.keys (#31583)
Add shape / type for global Object.keys. This is useful because
- it has an Effect.Read (not an Effect.Capture) as it cannot alias its
argument.
- Object.keys return an array
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31583).
* __->__ #31583
* #31582
2024-12-16 16:45:17 -05:00
mofeiZ
a78bbf9dbc
[compiler] Context variables as dependencies (#31582)
We previously didn't track context variables in the hoistable values
sidemap of `propagateScopeDependencies`. This was overly conservative as
we *do* track the mutable range of context variables, and it is safe to
hoist accesses to context variables after their last direct / aliased
maybe-assignment.

```js
function Component({value}) {
  // start of mutable range for `x`
  let x = DEFAULT;
  const setX = () => x = value;
  const aliasedSet = maybeAlias(setX);
  maybeCall(aliasedSet);
  // end of mutable range for `x`

  // here, we should be able to take x (and property reads
  // off of x) as dependencies
  return <Jsx value={x} />
}
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31582).
* #31583
* __->__ #31582
2024-12-16 16:45:05 -05:00
Jordan Brown
c869063f0d
[compiler] Add fire to known React APIs (#31795)
Makes `fire` a known export for type-based analysis

--
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31795).
* #31811
* #31798
* #31797
* #31796
* __->__ #31795
* #31794
2024-12-16 15:48:32 -05:00
Jordan Brown
308be6e8dc
[compiler] Add option for firing effect functions (#31794)
Config flag for `fire`

--
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31794).
* #31811
* #31798
* #31797
* #31796
* #31795
* __->__ #31794
2024-12-16 15:48:19 -05:00
mofeiZ
d325f872de
[compiler][be] Logger based debug printing in test runner (#31809)
Avoid mutable logging enabled state and writing to `process.stdout`
within our babel transform.
2024-12-16 15:15:13 -05:00
mofeiZ
ac17270652
[compiler][ez] Clean up duplicate code in propagateScopeDeps (#31581)
Clean up duplicate checks for when to skip processing values as
dependencies / hoistable temporaries.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31581).
* #31583
* #31582
* __->__ #31581
2024-12-16 15:11:52 -05:00
mofeiZ
80b81fe563
[compiler] Repro for aliased captures within inner function expressions (#31770)
see fixture
2024-12-16 14:43:34 -05:00
mofeiZ
e30872a4e0
[compiler][be] Playground now compiles entire program (#31774)
Compiler playground now runs the entire program through
`babel-plugin-react-compiler` instead of a custom pipeline which
previously duplicated function inference logic from `Program.ts`. In
addition, the playground output reflects the tranformed file (instead of
a "virtual file" of manually concatenated functions).

This helps with the following:
- Reduce potential discrepencies between playground and babel plugin
behavior. See attached fixture output for an example where we previously
diverged.
- Let playground users see compiler-inserted imports (e.g. `_c` or
`useFire`)

This also helps us repurpose playground into a more general tool for
compiler-users instead of just for compiler engineers.
- imports and other functions are preserved.
We differentiate between imports and globals in many cases (e.g.
`inferEffectDeps`), so it may be misleading to omit imports in printed
output
- playground now shows other program-changing behavior like position of
outlined functions and hoisted declarations
- emitted compiled functions do not need synthetic names
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31774).
* #31809
* __->__ #31774
2024-12-16 14:43:21 -05:00
Joseph Savona
a1b3bd0da0
Optimize method calls w props receiver (#31775)
Redo of #31771 without ghstack
2024-12-13 17:10:07 -08:00
Jack Pope
16367ceb02
[compiler] Fix dropped ref with spread props in InlineJsxTransform (#31726)
When supporting ref as prop in
https://github.com/facebook/react/pull/31558, I missed fixing the
optimization to pass a spread-props-only props object in without an
additional object copy. In the case that we have only a ref along with a
spread, we cannot return only the spread object. This results in
dropping the ref.

In this example
```javascript
<Foo ref={ref} {...props} />
```

The bugged output is:
```javascript
{
  // ...
  props: props
}
```

With this change we now get the correct output:
```javascript
{
  // ...
  props: {ref: ref, ...props}
}
```
2024-12-10 16:11:17 -05:00
Mike Vitousek
76d603a72a [compiler] Support for non-declatation for in/of iterators
ghstack-source-id: a28801e022
Pull Request resolved: https://github.com/facebook/react/pull/31710
2024-12-09 12:04:00 -08:00
Mike Vitousek
226b85926a [compiler] Support for context variable loop iterators
Summary:
Fixing a compiler todo

ghstack-source-id: c4d9226b17
Pull Request resolved: https://github.com/facebook/react/pull/31709
2024-12-09 12:03:52 -08:00
Jordan Brown
6bcf0d20da
[compiler] Empty dep arrays for globals/module-scoped values/imports (#31666)
Any LoadGlobal in the "infer deps" position can safely use an empty dep
array. Globals have no reactive deps!

I just keep messing up sapling. This is the revised version of #31662
2024-12-03 13:54:08 -05:00
mofeiZ
b9b510df2a
Revert "Replace deprecated dependency in eslint-plugin-react-compiler" (#31665)
Reverts facebook/react#31629

`@babel/plugin-proposal-private-methods` is not compatible with
`@babel/traverse` versions < 7.25 (see
https://github.com/babel/babel/issues/16851). Internally we have
partners that use a less modern babel version, and we expect this to be
an issue for older codebases in OSS as well.
2024-12-03 11:46:08 -05:00
Jordan Brown
1b1283ade7
[compiler] Support default imports for autodep config (#31657)
## Summary

Allows us to add deps for things like `import useWrapperEffect from
'useWrapperEffect'`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31657).
* __->__ #31657
* #31652
2024-12-03 07:42:53 -05:00
Jordan Brown
2ab471c8d2
[compiler] Don't include current field accesses in auto-deps (#31652)
## Summary

Drops .current field accesses in inferred dep arrays

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31652).
* #31657
* __->__ #31652
2024-12-03 07:42:28 -05:00
mofeiZ
865d2c418d
[compiler] Add meta internal option for useMemoCache import (#31654)
Adds `target: 'donotuse_meta_internal'`, which inserts useMemoCache
imports directly from `react`. Note that this is only valid for Meta
bundles, as others do not [re-export the `c`
function](5b0ef217ef/packages/react/index.fb.js (L68-L70)).

```js
// target=donotuse_meta_internal
import {c as _c} from 'react';

// target=19
import {c as _c} from 'react/compiler-runtime';

// target=17,18
import {c as _c} from 'react-compiler-runtime';
```

Meta is a bit special in that react runtime and compiler are guaranteed
to be up-to-date and compatible. It also has its own bundling and module
resolution logic, which makes importing from `react/compiler-runtime`
tricky.

I'm also fine with implementing the alternative which adds an internal
stub for `react-compiler-runtime` and
[bundles](5b0ef217ef/scripts/rollup/bundles.js (L120))
the runtime for internal builds.
2024-12-02 17:42:58 -05:00
Pavel
7670501b0d
Replace deprecated dependency in eslint-plugin-react-compiler (#31629) 2024-11-24 23:32:11 -05:00
Jordan Brown
2a9f4c04e5
[compiler] Infer deps configuration (#31616)
Adds a way to configure how we insert deps for experimental purposes.

```
[
  {
    module: 'react',
    imported: 'useEffect',
    numRequiredArgs: 1,
  },
  {
    module: 'MyExperimentalEffectHooks',
    imported: 'useExperimentalEffect',
    numRequiredArgs: 2,
  },
]
```

would insert dependencies for calls of `useEffect` imported from `react`
if they have 1 argument and calls of useExperimentalEffect` from
`MyExperimentalEffectHooks` if they have 2 arguments. The pushed dep
array is appended to the arg list.
2024-11-22 17:19:20 -05:00
Joseph Savona
eee5ca2a92
[compiler] Prune all unused array destructure items during DCE (#31619)
We didn't originally support holes within array patterns, so DCE was
only able to prune unused items from the end of an array pattern. Now
that we support holes we can replace any unused item with a hole, and
then just prune the items to the last identifier/spread entry.

Note: this was motivated by finding useState where either the state or
setState go unused — both are strong indications that you're violating
the rules in some way. By DCE-ing the unused portions of the useState
destructuring we can easily check if you're ignoring either value.

closes #31603 

This is a redo of that PR not using ghstack
2024-11-22 15:59:59 -05:00
Jordan Brown
e697386c10
[compiler] First cut at dep inference (#31386)
This is for researching/prototyping, not a feature we are releasing
imminently.

Putting up an early version of inferring effect dependencies to get
feedback on the approach. We do not plan to ship this as-is, and may not
start by going after direct `useEffect` calls. Until we make that
decision, the heuristic I use to detect when to insert effect deps will
suffice for testing.

The approach is simple: when we see a useEffect call with no dep array
we insert the deps inferred for the lambda passed in. If the first
argument is not a lambda then we do not do anything.

This diff is the easy part. I think the harder part will be ensuring
that we can infer the deps even when we have to bail out of memoization.
We have no other features that *must* run regardless of rules of react
violations. Does anyone foresee any issues using the compiler passes to
infer reactive deps when there may be violations?

I have a few questions:
1. Will there ever be more than one instruction in a block containing a
useEffect? if no, I can get rid of the`addedInstrs` variable that I use
to make sure I insert the effect deps array temp creation at the right
spot.
2. Are there any cases for resolving the first argument beyond just
looking at the lvalue's identifier id that I'll need to take into
account? e.g., do I need to recursively resolve certain bindings?

---------

Co-authored-by: Mofei Zhang <feifei0@meta.com>
2024-11-22 12:15:13 -05:00
lauren
6f0dc2947b
[compiler] Update hermes deps (#31586)
```
=> Found "hermes-parser@0.25.1"
info Reasons this module exists
   - "_project_#prettier-plugin-hermes-parser" depends on it
   - Hoisted from "_project_#prettier-plugin-hermes-parser#hermes-parser"
   - Hoisted from "_project_#eslint-plugin-react-compiler#hermes-parser"
   - Hoisted from "_project_#snap#hermes-parser"
   - Hoisted from "_project_#snap#babel-plugin-syntax-hermes-parser#hermes-parser"
   - Hoisted from "_project_#eslint-plugin-react-compiler#hermes-eslint#hermes-parser"
info Disk size without dependencies: "1.49MB"
info Disk size with unique dependencies: "1.82MB"
info Disk size with transitive dependencies: "1.82MB"
info Number of shared dependencies: 1
  Done in 0.81s.
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31586).
* __->__ #31586
* #31585
2024-11-19 10:52:48 -05:00
lauren
d2e8954d06
[compiler] Update react deps (#31585)
```
=> Found "react@0.0.0-experimental-4beb1fd8-20241118"
info Reasons this module exists
   - "_project_#babel-plugin-react-compiler" depends on it
   - Hoisted from "_project_#babel-plugin-react-compiler#react"
   - Hoisted from "_project_#snap#react"
info Disk size without dependencies: "252KB"
info Disk size with unique dependencies: "252KB"
info Disk size with transitive dependencies: "252KB"
info Number of shared dependencies: 0
  Done in 0.60s.
```

```
=> Found "react-dom@0.0.0-experimental-4beb1fd8-20241118"
info Reasons this module exists
   - "_project_#babel-plugin-react-compiler" depends on it
   - Hoisted from "_project_#babel-plugin-react-compiler#react-dom"
   - Hoisted from "_project_#snap#react-dom"
info Disk size without dependencies: "8.04MB"
info Disk size with unique dependencies: "8.17MB"
info Disk size with transitive dependencies: "8.17MB"
info Number of shared dependencies: 1
  Done in 0.56s.
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31585).
* #31586
* __->__ #31585
2024-11-19 10:52:38 -05:00
lauren
c866d75060
[playground] Fix broken tests (#31573)
Our e2e setup with monaco is kinda brittle since it relies on the dom.
It seems like longish text gets truncated so let's just simpify all
these test cases.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31573).
* __->__ #31573
* #31572
2024-11-18 19:18:09 -05:00
lauren
ee10c74824
[playground] Fix incorrect ci path and change reporter (#31572)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31572).
* #31573
* __->__ #31572
2024-11-18 19:17:58 -05:00
Aditya Subramanyam
579cc2a44c
[playground] Add support for "use no memo" (#31561)
Fixes #31331

## Summary
There is a bug in
playground(https://github.com/facebook/react/issues/31331) which doesnt
support 'use memo' or 'use no memo' directives. Its misleading while
debugging components in the playground

## How did you test this change?
Ran test cases and added a few extra test cases as well

## Changes
1) Adds support for 'use memo' and 'use no memo'
2) Cleanup E2E test cases a bit
3) Adds test cases for use memo
4) Added documentation to run test cases

## Implementation
`parseFunctions` returns a set of functions to be compiled. But, it
doesnt filter out/handle memoized opted/un-opted functions using
directives.

ive just created a `compile` flag to enable/disable compiling
[here](https://github.com/facebook/react/pull/31561/files#diff-305de47a3fe3ce778e22d5c5cf438419a59de8e7f785b45f659e7b41b1e30b03R113)

Then I am just skipping those functions from getting compile
[here](https://github.com/facebook/react/pull/31561/files#diff-305de47a3fe3ce778e22d5c5cf438419a59de8e7f785b45f659e7b41b1e30b03R253)
2024-11-18 15:38:22 -05:00
mofeiZ
e33b13795d
[compiler] repro for type inference + control flow bug (#31570)
Repro for bug in our type inference system.

We currently propagate inferred types through control flow / potential
type guards. Note that this is inconsistent with both
[Flow](https://flow.org/try/#1N4Igxg9gdgZglgcxALlAIwIZoKYBsD6uEEAztvhgE6UYCe+JADpdhgCYowa5kA0I2KAFcAtiRQAXSkOz9sADwxgJ+NPTbYuQ3BMnTZA+Y2yU4IwRO4A6SFBIrGVDGM7c+h46fNRLuKxJIGWh8MeT0ZfhYlCStpHzNsFBAMIQkIEQwJODAQfiEyfBE4eWw2fDgofDBMsAALfAA3KjgsXGxxZC4eAw0G-GhcWn9aY3wWZldu-g1mbGqJUoBaCRHEzrcDEgBrbAk62kXhXFxJ923d-cPRHEpTgyEoMDaqZdW7vKgoOfaSKgOKpqmDA+d4gB5fMA-P6LCCMLLQbiLOoYCqgh6-GDYRYIXYLSgkRZkCR4jpddwPfJLZjpOBkO4AX34kA0SRWxgABAAxYjsgC87OAAB0oOzReythU2Mh2YKQNyILLeMKxeymrgZNLhCIbsL6QBuYVs7DsgBCVD5AuVYolUClMpAZsoiqtorVGvZWpuSqg9OFMAeyjg0HZdTmW3lAAp5NKAPJoABWcwkAEppWZGLg4O12fJ2bSuTyhSKxSwJEJKCKAOQ2tiVvMi3MAMkbOasNb5vP5svlsoNPuFfoD8JFGQqUel8vZAB9TVReCHoHa0MRnlBUwWIJbi6K4DB2RHbGxk1uVSrd-uAIShsDh4hR5PHoun5-siS1SgQADuHuw34AotQECUBGsqysmfYvuyvrbqepblg2EFitBKpwRWOZ9vSuQgA0JgkEGUBJBk9gmCA9JAA)
and
[Typescript](https://www.typescriptlang.org/play/?#code/C4TwDgpgBAYg9nKBeKBvAUFLUDWBLAOwBMAuKAInjnIBpNsA3AQwBsBXCMgtgWwCMIAJ3QBfANzpQkKACEmg5GnpZ8xMuTmDayqM3aco3fkLoj0AMzYEAxsDxwCUawAsI1nFQAUADzJw+AFZuwACUZEwAzhFCwBFQ3lB4cVRK2InmUJ4AhJ4A5KpEuYmOCQBkpfEAdAXISCiUCOQhIalp2MDOgnAA7oYQvQCigl2CnuRWEN6QthBETTpmZhZWtvaOPEyEPmQpAD6y8jRODqRQfAgsEEwEYbAIrVh4GZ7WJy0Ybdgubh4IPiEST5YQQQYBsQQlQHYMxpEFgiHxCQiIA)
2024-11-18 11:54:11 -05:00
Jack Pope
4beb1fd8ba
[compiler] Support enableRefAsProp in jsx transform (#31558)
Since `enableRefAsProp` shipped everywhere, the ReactElement
implementation on prod puts refs on both `element.ref` and
`element.props.ref`. Here we let the `ref` case fall through so its now
available on props, matching the JSX runtime.
2024-11-18 10:51:16 -05:00
mofeiZ
0480cdb58c
[compiler][be] Clean up nested function context in DCE (#31202)
Now that we rely on function context exclusively, let's clean up
`HIRFunction.context` after DCE. This PR is in preparation of #31204,
which would otherwise have unnecessary declarations (of context values
that become entirely DCE'd)

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31202).
* __->__ #31202
* #31203
* #31201
* #31200
* #31521
2024-11-15 13:06:39 -05:00
mofeiZ
0f3c62b466
[compiler][be] Patch test fixtures for evaluator (#31203)
Add more `FIXTURE_ENTRYPOINT`s

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31203).
* #31202
* __->__ #31203
* #31201
* #31200
* #31521
2024-11-15 13:06:29 -05:00
mofeiZ
858633f900
[compiler] Lower JSXMemberExpression with LoadLocal (#31201)
`JSXMemberExpression` is currently the only instruction (that I know of)
that directly references identifier lvalues without a corresponding
`LoadLocal`.

This has some side effects:
- deadcode elimination and constant propagation now reach
JSXMemberExpressions
- we can delete `LoweredFunction.dependencies` without dangling
references (previously, the only reference to JSXMemberExpression
objects in HIR was in function dependencies)
- JSXMemberExpression now is consistent with all other instructions
(e.g. has a rvalue-producing LoadLocal)

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31201).
* #31202
* #31203
* __->__ #31201
* #31200
* #31521
2024-11-15 13:06:19 -05:00
mofeiZ
c09402aa2f
[compiler] Stop using function dependencies in propagateScopeDeps (#31200)
Recursively visit inner function instructions to extract dependencies
instead of using `LoweredFunction.dependencies` directly.

This is currently gated by enableFunctionDependencyRewrite, which needs
to be removed before we delete `LoweredFunction.dependencies` altogether
(#31204).

Some nice side effects
- optional-chaining deps for inner functions
- full DCE and outlining for inner functions (see #31202)
- fewer extraneous instructions (see #31204)

-
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31200).
* #31202
* #31203
* #31201
* __->__ #31200
* #31521
2024-11-15 13:06:05 -05:00
mofeiZ
4972718c26
[compiler] Fix: ref.current now correctly reactive (#31521)
We were previously filtering out `ref.current` dependencies in
propagateScopeDependencies:checkValidDependency`. This is incorrect.

Instead, we now always take a dependency on ref values (the outer box)
as they may be reactive. Pruning is done in
pruneNonReactiveDependencies.

This PR includes a small patch to `collectReactiveIdentifier`. Prior to
this, we conservatively assumed that pruned scopes always produced
reactive declarations. This assumption fixed a bug with non-reactivity,
but some of these declarations are `useRef` calls. Now we have special
handling for this case
```js
// This often produces a pruned scope
React.useRef(1);
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31521).
* #31202
* #31203
* #31201
* #31200
* __->__ #31521
2024-11-15 13:05:55 -05:00
Niklas Mollenhauer
3c15d219aa
[compiler] Disable emit of .tsbuildinfo (#31459)
## Summary
`@rollup/plugin-typescript` emits a warning while building, hinting that
`outputToFilesystem` defaults to true.

Although "noEmit" is set to `true` for the tsconfig, rollup writes a
`dist/.tsbuildinfo`. That file is then also shipped inside the npm
module and doesn't offer any benefit for library consumers. Setting this
option to false results in the file not being written and thus omitted
from the npm module.

## How did you test this change?
`dist/.tsbuildinfo` is not emitted any more.
2024-11-14 15:43:36 -05:00
mofeiZ
3770c11011
[compiler] repro for reactive ref.current accesses (#31519)
See test fixture
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31519).
* #31521
* __->__ #31519
2024-11-12 14:04:54 -05:00
mofeiZ
2ec26bc432
[compiler] Repro for mutable range edge case (#31479)
See test fixtures
2024-11-11 18:04:29 -05:00
Sathya Gunasekaran
a88b9e5f68
[compiler] Outline JSX with non-jsx children (#31442)
Previously, we bailed out on outlining jsx that had children that were
not part of the outlined jsx.

Now, we add support for children by treating as attributes.
2024-11-06 17:54:44 +00:00
Sathya Gunasekaran
09197bb786
[compiler] Outline jsx with duplicate attributes (#31441)
Previously, we would skip outlining jsx expressions that had duplicate
jsx attributes as we would not rename them causing incorrect
compilation.

In this PR, we add outlining support for duplicate jsx attributes by
renaming them.
2024-11-06 17:50:13 +00:00
Sathya Gunasekaran
2df8f61885
[compiler] Store original and new prop names (#31440)
Previously, we'd directly store the original attributes from the jsx
expressions. But this isn't enough as we want to rename duplicate
attributes.

This PR refactors the prop collection logic to store both the original
and new names for jsx attributes in the newly outlined jsx expression.

For now, both the new and old names are the same. In the future, they
will be different when we add support for outlining expressions with
duplicate attribute names.
2024-11-06 17:44:52 +00:00
mofeiZ
c3570b158d
[compiler] Collect temporaries and optional chains from inner functions (#31346)
Recursively collect identifier / property loads and optional chains from
inner functions. This PR is in preparation for #31200

Previously, we only did this in `collectHoistablePropertyLoads` to
understand hoistable property loads from inner functions.
1. collectTemporariesSidemap
2. collectOptionalChainSidemap
3. collectHoistablePropertyLoads
- ^ this recursively calls `collectTemporariesSidemap`,
`collectOptionalChainSidemap`, and `collectOptionalChainSidemap` on
inner functions
4. collectDependencies

Now, we have
1. collectTemporariesSidemap
- recursively record identifiers in inner functions. Note that we track
all temporaries in the same map as `IdentifierIds` are currently unique
across functions
2. collectOptionalChainSidemap
    - recursively records optional chain sidemaps in inner functions
3. collectHoistablePropertyLoads
    - (unchanged, except to remove recursive collection of temporaries)
4. collectDependencies
- unchanged: to be modified to recursively collect dependencies in next
PR

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31346).
* #31202
* #31203
* #31201
* #31200
* __->__ #31346
* #31199
2024-11-05 19:25:05 -05:00
mofeiZ
fd018af617
[compiler] Delete propagateScopeDeps (non-hir) (#31199)
`enablePropagateScopeDepsHIR` is now used extensively in Meta. This has
been tested for over two weeks in our e2e tests and production.

The rest of this stack deletes `LoweredFunction.dependencies`, which the
non-hir version of `PropagateScopeDeps` depends on. To avoid a more
forked HIR (non-hir with dependencies and hir with no dependencies),
let's go ahead and clean up the non-hir version of
PropagateScopeDepsHIR.

Note that all fixture changes in this PR were previously reviewed when
they were copied to `propagate-scope-deps-hir-fork`. Will clean up /
merge these duplicate fixtures in a later PR

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31199).
* #31202
* #31203
* #31201
* #31200
* #31346
* __->__ #31199
2024-11-05 19:22:04 -05:00
mofeiZ
f2f002c7c1
[compiler][be] Stabilize compiler output: sort deps and decls by name (#31362)
All dependencies and declarations of a reactive scope can be reordered
to scope start/end. i.e. generated code does not depend on conditional
short-circuiting logic as dependencies are inferred to have no side
effects.

Sorting these by name helps us get higher signal compilation snapshot
diffs when upgrading the compiler and testing PRs
2024-11-05 18:26:50 -05:00
mofeiZ
792fa065ca
[compiler][ez] Clean up pragma parsing for tests + playground (#31347)
Move environment config parsing for `inlineJsxTransform`,
`lowerContextAccess`, and some dev-only options out of snap (test
fixture). These should now be available for playground via
`@inlineJsxTransform` and `lowerContextAccess`.

Other small change:
Changed zod fields from `nullish()` -> `nullable().default(null)`.
[`nullish`](https://zod.dev/?id=nullish) fields accept `null |
undefined` and default to `undefined`. We don't distinguish between null
and undefined for any of these options, so let's only accept null +
default to null. This also makes EnvironmentConfig in the playground
more accurate. Previously, some fields just didn't show up as
`prettyFormat({field: undefined})` does not print `field`.
2024-11-05 18:19:44 -05:00
mofeiZ
33195602ea
[compiler][ez] tsconfig: treat all snap fixtures as modules (#31350)
Qol improvement. Currently, typescript lints treat test fixtures without
an export as a 'global script' (see
[docs](https://www.typescriptlang.org/docs/handbook/2/modules.html#how-javascript-modules-are-defined)).
This gives confusing lints for duplicate declarations (in the global
scope)
2024-11-05 17:57:18 -05:00
mofeiZ
5ca2bc6d63
[compiler][ez] Fixture repro for function hoisting bug (#31349)
Repro for bug reported by @alexmckenley
2024-11-05 17:56:53 -05:00
mofeiZ
bddb7c9b5c
[compiler] Add fixture for objectexpr computed key bug (#31348)
We were bailing out on complex computed-key syntax (prior to #31344) as
we assumed that this caused bugs (due to inferring computed key rvalues
to have `freeze` effects).

This fixture shows that this bailout is unrelated to the underlying bug
2024-11-05 17:56:36 -05:00
mofeiZ
527bcaa83d
[compiler] patch: rewrite scope dep/decl in inlineJsxTransform (#31431)
This bugfix is needed to land #31199 PropagateScopeDepsHIR infers scope
declarations for the `inline-jsx-transform` test fixture (the non-hir
version does not).

These declarations must get the rewritten phi identifiers
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31431).
* #31204
* #31202
* #31203
* #31201
* #31200
* #31346
* #31199
* __->__ #31431
* #31345
* #31197
2024-11-05 15:27:39 -05:00
mofeiZ
e7e269b726
[compiler] bugfix for hoistable deps for nested functions (#31345)
`PropertyPathRegistry` is responsible for uniqueing identifier and
property paths. This is necessary for the hoistability CFG merging logic
which takes unions and intersections of these nodes to determine a basic
block's hoistable reads, as a function of its neighbors. We also depend
on this to merge optional chained and non-optional chained property
paths

This fixes a small bug in #31066 in which we create a new registry for
nested functions. Now, we use the same registry for a component / hook
and all its inner functions

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31345).
* #31204
* #31202
* #31203
* #31201
* #31200
* #31346
* #31199
* #31431
* __->__ #31345
* #31197
2024-11-05 15:25:54 -05:00
mofeiZ
dd1a021bad
[compiler][ez] Patch hoistability for ObjectMethods (#31197)
Extends #31066 to ObjectMethods (somehow missed this before).

'
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31197).
* #31204
* #31202
* #31203
* #31201
* #31200
* #31346
* #31199
* #31431
* #31345
* __->__ #31197
2024-11-05 15:25:39 -05:00
lauren
b81e6dd2da
[cleanup] Remove compiler runtime-compat fixture library (#31430)
There's no real reason to keep this around anymore now that the compiler
beta is released and we have validated that react-compiler-runtime is
[usable by
libraries](https://www.npmjs.com/package/react-compiler-runtime?activeTab=dependents).

Let's clean this up for now.
2024-11-05 14:14:39 -05:00
Jack Pope
543eb09321
[compiler] Wrap inline jsx transform codegen in conditional (#31267)
JSX inlining is a prod-only optimization. We want to enforce this while
maintaining the same compiler output in DEV and PROD.

Here we add a conditional to the transform that only replaces JSX with
object literals outside of DEV. Then a later build step can handle DCE
based on the value of `__DEV__`
2024-11-04 13:19:05 -05:00
lauren
603e6108f3
[compiler] Update react deps to experimental instead of beta (#31385)
Some tests rely on experimental APIs so let's just use
react@experimental instead of beta
2024-10-29 21:51:41 -04:00
lauren
4abe4b5821
[compiler] Check if local identifier is a hook when resolving globals (#31384)
When resolving import specifiers from the react namespace (`import
{imported as local} from 'react'`), we were previously only checking if
the `imported` identifier was a hook if we didn't already have its
definition in the global registry. We also need to check if `local` is a
hook in the case of aliasing since there may be hook-like APIs in react
that don't start with `use` (eg they are experimental or unstable).

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31384).
* #31385
* __->__ #31384
* #31383
2024-10-29 21:36:48 -04:00
lauren
3928cb00db
[compiler] Ref validation repro for ImportSpecifier with renamed local (#31383)
This was originally reported in
https://github.com/reactwg/react-compiler/discussions/27.

Adding a failing repro to capture this case.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31383).
* #31385
* #31384
* __->__ #31383
2024-10-29 21:36:36 -04:00
Sathya Gunasekaran
02c0e824e4
[compiler][ez] Remove unused param (#31376) 2024-10-28 15:08:27 +00:00
Sathya Gunasekaran
aded0ef831
[compiler] Handle member expr as computed property (#31344)
This PR loosens the restriction on the types of computed properties we
can handle.

Previously, we would disallow anything that is not an identifier because
non-identifiers could be mutating. But member expressions are not
mutating so we can treat them similar to identifiers.
2024-10-28 13:10:01 +00:00
Mike Vitousek
fe04dbcbc4 [compiler] Fix to ref access check to ban ref?.current
ghstack-source-id: ea417a468e
Pull Request resolved: https://github.com/facebook/react/pull/31360
2024-10-25 16:51:36 -07:00
Pascal Birchler
d19ba8ecdd
[react-compiler-runtime] Support React 17 peer dependency (#31336)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

The recent blog post and
[documentation](https://react.dev/learn/react-compiler#using-react-compiler-with-react-17-or-18)
say that `react-compiler-runtime` supports React 17, yet it currently
requires React 18 or 19 as a peer dependency, making it unusable for
installing on a project still using React 17.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

Manually installing the package on a React 17 codebase.

---------

Co-authored-by: lauren <poteto@users.noreply.github.com>
2024-10-24 14:08:57 -04:00
lauren
28668d39be
[playground] Upgrade to Next 15 stable (#31333) 2024-10-23 12:13:22 -04:00
Henry Q. Dineen
b4cbdc5a7c
remove terser from react-compiler-runtime build (#31326)
## Summary

This fixes a minor nit I have about the `react-compiler-runtime` package
in that the published code is minified. I assume most consumers will
minify their own bundles so there's no real advantage to minifying it as
part of the build.

For my purposes it makes it more difficult to read the code, use
`patch-package` (if needed), or diff two versions without referencing
the source code on github or mapping it back to original source using
the source maps.

## How did you test this change?

I ran the build locally and looked at the result but did not run the
code. It's a lot more readable except for the commonjs
compatibility-related stuff that Rollup inserts.
2024-10-22 19:49:10 -04:00
Simen Bekkhus
ae90522bc6
chore: remove unsued deps from React Compiler Babel plugin (#31315)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

Since the Babel plugin is bundled into a single file (except for
`@babel/types`
45804af18d/compiler/packages/babel-plugin-react-compiler/rollup.config.js (L18))
we can move these deps to `devDependencies`.

Main motivation is e.g. not installing ancient version of
`pretty-format` (asked in https://github.com/facebook/react/issues/29062
without getting a reason, but if consumers can just skip the deps
entirely that's even better).

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

## How did you test this change?

I tested by installing the plugin into an empty project, deleting
everything in `node_modules` _except_ for `babel-plugin-react-compiler`
and doing `require('babel-plugin-react-compiler')`. It still worked
fine, so it should work in other cases as well 😀

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
2024-10-22 13:51:58 -04:00
Joseph Savona
cdde15efe1
[compiler] InlineJSXTransform transforms jsx inside function expressions (#31282)
InlineJSXTransform wasn't traversing into function expressions or object
methods, so any JSX inside such functions wouldn't have gotten inlined.
This PR updates to traverse nested functions to transform all JSX within
a hook or component.

Note that this still doesn't transform JSX outside of components or
hooks, ie in standalone render helpers.
2024-10-18 11:27:48 -07:00
lauren
915be0ef78
[playground] Upgrade various packages (#31293)
Just some housekeeping
2024-10-18 14:25:36 -04:00
lauren
61383303d3
[playground] Remove unnecessary fs package (#31292)
Seems like this was accidentally added.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31292).
* #31293
* __->__ #31292
* #31291
2024-10-18 14:09:30 -04:00
lauren
ee6ca23b24
[playground] Upgrade to Next 15 (#31291)
This was previously blocked because the playground was a part of the
compiler's yarn workspace and there was some funky hoisting going on.
Now that we are decoupled we can upgrade to Next 15, which hopefully
should improve build times.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31291).
* #31293
* #31292
* __->__ #31291
2024-10-18 14:09:07 -04:00
lauren
d57217544a
[fixture] Update compiler to use latest package (#31289)
Pins the compiler to the latest version in our fixture app.
2024-10-18 13:32:26 -04:00
lauren
35b63ca90d
[ci:compiler] Only add latest tag to non-experimental (#31288)
It turns out npm sets the latest tag by default so simply removing it
didn't change the previous behavior.

The `latest` tag is typically used for stable release versions, and
other tags for unstable versions such as prereleases. Since the compiler
is still in prerelease, let's set the latest tag only for
non-experimental releases to help signal which version is the safest to
try out.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31288).
* #31289
* __->__ #31288
2024-10-18 13:24:30 -04:00
lauren
1ce58ddd67
[ci] Don't auto push to latest tag (#31284)
By default let's stop pushing to the latest tag now that we have a
non-experimental release.
2024-10-18 00:20:14 -04:00
lauren
9c60cbe3d1
[compiler] Clean up publish script (#31278)
Few small tweaks to make it easier to run adhoc publishes
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31278).
* #31283
* __->__ #31278
2024-10-17 18:02:41 -04:00
Sathya Gunasekaran
c91b3b090a
JSX Outlining (#30956)
Currently, the react compiler can not compile within callbacks which can
potentially cause over rendering. Consider this example:
```jsx
function Component(countries, onDelete) {
  const name = useFoo();
  return countries.map(() => {
    return (
      <Foo>
        <Bar name={name}/>
        <Baz onclick={onDelete} />
      </Foo>
    );
  });
}
```

In this case, there's no memoization of the nested jsx elements. But
instead if we were to manually refactor the nested jsx into separate
component like this:
```jsx
function Component(countries, onDelete) {
  const name = useFoo();
  return countries.map(() => {
    return <Temp name={name} onDelete={onDelete} />;
  });
}

function Temp({ name, onDelete }) {
  return (
    <Foo>
      <Bar name={name} />
      <Baz onclick={onDelete} />
    </Foo>
  );
}

```

The compiler can now optimise both these components:
```jsx
function Component(countries, onDelete) {
  const $ = _c(4);
  const name = useFoo();
  let t0;
  if ($[0] !== name || $[1] !== onDelete || $[2] !== countries) {
    t0 = countries.map(() => <Temp name={name} onDelete={onDelete} />);
    $[0] = name;
    $[1] = onDelete;
    $[2] = countries;
    $[3] = t0;
  } else {
    t0 = $[3];
  }
  return t0;
}

function Temp(t0) {
  const $ = _c(7);
  const { name, onDelete } = t0;
  let t1;
  if ($[0] !== name) {
    t1 = <Bar name={name} />;
    $[0] = name;
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  let t2;
  if ($[2] !== onDelete) {
    t2 = <Baz onclick={onDelete} />;
    $[2] = onDelete;
    $[3] = t2;
  } else {
    t2 = $[3];
  }
  let t3;
  if ($[4] !== t1 || $[5] !== t2) {
    t3 = (
      <Foo>
        {t1}
        {t2}
      </Foo>
    );
    $[4] = t1;
    $[5] = t2;
    $[6] = t3;
  } else {
    t3 = $[6];
  }
  return t3;
}
```

Now, when `countries` is updated by adding one single value, only the
newly added value is re-rendered and not the entire list. Rather than
having to do this manually, this PR teaches the react compiler to do
this transformation.

This PR adds a new pass (`OutlineJsx`) to capture nested jsx statements
and outline them in a separate component. This newly outlined component
can then by memoized by the compiler, giving us more fine grained
rendering.
2024-10-17 18:15:32 +01:00
lauren
3ed64f8232
[ez] Update references to 'forget' in react-compiler-runtime (#31277)
Updates the runtime to reference React Compiler instead of Forget.
2024-10-16 18:44:50 -04:00
lauren
b60286b834
[compiler] Use consistent version hash for npm (#31177)
Modifies our release script to use the same version hash (the hashed
`compiler` directory) for all compiler packages to keep them consistent.
2024-10-14 11:20:47 -04:00
Mike Vitousek
147374d71a [compiler] Kill markReactiveIdentifier and friends
Summary:
With the previous PR we no longer need to mark identifiers as reactive in contexts where we don't have places. We already deleted most uses of markReactiveId; the last case was to track identifiers through loadlocals etc -- but we already use a disjoint alias map that accounts for loadlocals when setting reactivity.

ghstack-source-id: 69ce0a78b0
Pull Request resolved: https://github.com/facebook/react/pull/31178
2024-10-11 17:26:57 -07:00
Mike Vitousek
6cf5bd9013 [compiler] Allow refs to be lazily initialized during render
Summary:
The official guidance for useRef notes an exception to the rule that refs cannot be accessed during render: to avoid recreating the ref's contents, you can test that the ref is uninitialized and then initialize it using an if statement:

```
if (ref.current == null) {
  ref.current = SomeExpensiveOperation()
}
```

The compiler didn't recognize this exception, however, leading to code that obeyed all the official guidance for refs being rejected by the compiler. This PR fixes that, by extending the ref validation machinery with an awareness of guard operations that allow lazy initialization. We now understand `== null` and similar operations, when applied to a ref and consumed by an if terminal, as marking the consequent of the if as a block in which the ref can be safely written to. In order to do so we need to create a notion of ref ids, which link different usages of the same ref via both the ref and the ref value.

ghstack-source-id: d2729274f351e1eb0268f28f629fa4c2568ebc4d
Pull Request resolved: https://github.com/facebook/react/pull/31188
2024-10-11 16:14:33 -07:00
dependabot[bot]
9c525ea44a
Bump micromatch from 4.0.5 to 4.0.8 in /compiler (#31186)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5
to 4.0.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micromatch/micromatch/releases">micromatch's
releases</a>.</em></p>
<blockquote>
<h2>4.0.8</h2>
<p>Ultimate release that fixes both CVE-2024-4067 and CVE-2024-4068. We
consider the issues low-priority, so even if you see automated scanners
saying otherwise, don't be scared.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md">micromatch's
changelog</a>.</em></p>
<blockquote>
<h2>[4.0.8] - 2024-08-22</h2>
<ul>
<li>backported CVE-2024-4067 fix (from v4.0.6) over to 4.x branch</li>
</ul>
<h2>[4.0.7] - 2024-05-22</h2>
<ul>
<li>this is basically v4.0.5, with some README updates</li>
<li><strong>it is vulnerable to CVE-2024-4067</strong></li>
<li>Updated braces to v3.0.3 to avoid CVE-2024-4068</li>
<li>does NOT break API compatibility</li>
</ul>
<h2>[4.0.6] - 2024-05-21</h2>
<ul>
<li>Added <code>hasBraces</code> to check if a pattern contains
braces.</li>
<li>Fixes CVE-2024-4067</li>
<li><strong>BREAKS API COMPATIBILITY</strong></li>
<li>Should be labeled as a major release, but it's not.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8bd704ec0d"><code>8bd704e</code></a>
4.0.8</li>
<li><a
href="a0e68416a4"><code>a0e6841</code></a>
run verb to generate README documentation</li>
<li><a
href="4ec288484f"><code>4ec2884</code></a>
Merge branch 'v4' into hauserkristof-feature/v4.0.8</li>
<li><a
href="03aa805217"><code>03aa805</code></a>
Merge pull request <a
href="https://redirect.github.com/micromatch/micromatch/issues/266">#266</a>
from hauserkristof/feature/v4.0.8</li>
<li><a
href="814f5f70ef"><code>814f5f7</code></a>
lint</li>
<li><a
href="67fcce6a10"><code>67fcce6</code></a>
fix: CHANGELOG about braces &amp; CVE-2024-4068, v4.0.5</li>
<li><a
href="113f2e3fa7"><code>113f2e3</code></a>
fix: CVE numbers in CHANGELOG</li>
<li><a
href="d9dbd9a266"><code>d9dbd9a</code></a>
feat: updated CHANGELOG</li>
<li><a
href="2ab13157f4"><code>2ab1315</code></a>
fix: use actions/setup-node@v4</li>
<li><a
href="1406ea38f3"><code>1406ea3</code></a>
feat: rework test to work on macos with node 10,12 and 14</li>
<li>Additional commits viewable in <a
href="https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=micromatch&package-manager=npm_and_yarn&previous-version=4.0.5&new-version=4.0.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/facebook/react/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-11 16:29:34 -04:00
dependabot[bot]
2011074ab8
Bump json5 from 2.2.1 to 2.2.3 in /compiler (#31185)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/json5/json5/releases">json5's
releases</a>.</em></p>
<blockquote>
<h2>v2.2.3</h2>
<ul>
<li>Fix: json5@2.2.3 is now the 'latest' release according to npm
instead of v1.0.2. (<a
href="https://redirect.github.com/json5/json5/issues/299">#299</a>)</li>
</ul>
<h2>v2.2.2</h2>
<ul>
<li>Fix: Properties with the name <code>__proto__</code> are added to
objects and arrays.
(<a href="https://redirect.github.com/json5/json5/issues/199">#199</a>)
This also fixes a prototype pollution vulnerability reported by
Jonathan Gregson! (<a
href="https://redirect.github.com/json5/json5/issues/295">#295</a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/json5/json5/blob/main/CHANGELOG.md">json5's
changelog</a>.</em></p>
<blockquote>
<h3>v2.2.3 [<a
href="https://github.com/json5/json5/tree/v2.2.3">code</a>, <a
href="https://github.com/json5/json5/compare/v2.2.2...v2.2.3">diff</a>]</h3>
<ul>
<li>Fix: json5@2.2.3 is now the 'latest' release according to npm
instead of
v1.0.2. (<a
href="https://redirect.github.com/json5/json5/issues/299">#299</a>)</li>
</ul>
<h3>v2.2.2 [<a
href="https://github.com/json5/json5/tree/v2.2.2">code</a>, <a
href="https://github.com/json5/json5/compare/v2.2.1...v2.2.2">diff</a>]</h3>
<ul>
<li>Fix: Properties with the name <code>__proto__</code> are added to
objects and arrays.
(<a href="https://redirect.github.com/json5/json5/issues/199">#199</a>)
This also fixes a prototype pollution vulnerability reported by
Jonathan Gregson! (<a
href="https://redirect.github.com/json5/json5/issues/295">#295</a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c3a7524277"><code>c3a7524</code></a>
2.2.3</li>
<li><a
href="94fd06d82e"><code>94fd06d</code></a>
docs: update CHANGELOG for v2.2.3</li>
<li><a
href="3b8cebf0c4"><code>3b8cebf</code></a>
docs(security): use GitHub security advisories</li>
<li><a
href="f0fd9e194d"><code>f0fd9e1</code></a>
docs: publish a security policy</li>
<li><a
href="6a91a05fff"><code>6a91a05</code></a>
docs(template): bug -&gt; bug report</li>
<li><a
href="14f8cb186e"><code>14f8cb1</code></a>
2.2.2</li>
<li><a
href="10cc7ca916"><code>10cc7ca</code></a>
docs: update CHANGELOG for v2.2.2</li>
<li><a
href="7774c10979"><code>7774c10</code></a>
fix: add <strong>proto</strong> to objects and arrays</li>
<li><a
href="edde30abd8"><code>edde30a</code></a>
Readme: slight tweak to intro</li>
<li><a
href="97286f8bd5"><code>97286f8</code></a>
Improve example in readme</li>
<li>Additional commits viewable in <a
href="https://github.com/json5/json5/compare/v2.2.1...v2.2.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=json5&package-manager=npm_and_yarn&previous-version=2.2.1&new-version=2.2.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/facebook/react/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-11 16:29:18 -04:00
Mike Vitousek
7b7fac073d [compiler] Represent phis with places rather than identifiers
Summary:
The fact that phis are identifiers rather than places is unfortunate in a few cases. In some later analyses, we might wish to know whether a phi is reactive, but we don't have an easy way to do that currently.

Most of the changes here is just replacing phi.id with phi.place.identifier and such. Interesting bits are EnterSSA (several functions now take places rather than identifiers, and InferReactivePlaces now needs to mark places as reactive explicitly.

ghstack-source-id: 5f4fb396cd86b421008c37832a5735ac40f8806e
Pull Request resolved: https://github.com/facebook/react/pull/31171
2024-10-10 12:41:03 -07:00
mofeiZ
fbfe37ee40
[compiler] Test fixture: non-reactive phi creates 'dangling ref' scope (#31103) 2024-10-10 12:23:44 -04:00
lauren
77f438931f
[compiler] Consume compiled lib in react 19 app (#31167)
it works
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31167).
* __->__ #31167
* #31166
* #31165
2024-10-10 11:40:06 -04:00
lauren
0a1fdeee9e
[compiler] Consume compiled lib in react 18 app (#31166)
`yarn dev` doesn't work quite correctly because of an outdated
assumption in vite-plugin-react, I have a [PR
open](https://github.com/vitejs/vite-plugin-react/pull/374) to address.

However `yarn build` and `yarn preview` does work as expected.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31166).
* #31167
* __->__ #31166
* #31165
2024-10-10 11:39:54 -04:00
lauren
eb0e265cd9
[compiler] Compile lib (#31165)
Add and compile a simple hook with rollup and babel.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31165).
* #31167
* #31166
* __->__ #31165
2024-10-10 11:39:42 -04:00
lauren
2ef407937b
[compiler] Scaffold fixture apps (#31164)
Scaffold empty apps to consume the fixture lib.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31164).
* #31167
* #31166
* #31165
* __->__ #31164
* #31148
* #31168
2024-10-10 11:33:02 -04:00
lauren
b781c9f564
[compiler] Scaffold fixture library (#31148)
Scaffolds an empty library to test backwards compatibility with the
compiler enabled.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/31148).
* #31167
* #31166
* #31165
* #31164
* __->__ #31148
* #31168
2024-10-10 10:53:58 -04:00
Mike Vitousek
131ae818a1 [compiler][ez] Include phi identifier in AssertValidMutableRanges
Summary:
Looks like we accidentally skipped validating this identifier.

ghstack-source-id: 05964331a8
Pull Request resolved: https://github.com/facebook/react/pull/31170
2024-10-09 22:15:41 -07:00
lauren
ed966dac4a
[compiler] Fix busted postinstall script (#31147) 2024-10-07 20:37:41 -04:00
lauren
f74f6cd945
[rcr] Publish react-compiler-runtime to npm (#31146)
Updates our publishing scripts to also publish react-compiler-runtime.
2024-10-07 18:50:07 -04:00
lauren
23cd3aca28
[rcr] Remove runtimeModule compiler option (#31145)
Now that the compiler always injects `react-compiler-runtime`, this
option is unnecessary.
2024-10-07 18:07:12 -04:00
lauren
3fd3364107
[rcr] Update default runtimeModule to react-compiler-runtime (#31144)
Updates the compiler to always import from `react-compiler-runtime` by
default. The runtime then decides whether to use the official or
userspace implementation of useMemoCache.
2024-10-07 17:59:33 -04:00
lauren
8dd4cda380
[rcr] Add target flag to compiler (#31143) 2024-10-07 17:50:53 -04:00
lauren
68d5288359
[snap] Add react-compiler-runtime as a dependency (#31142)
We need `react-compiler-runtime` to use the same version of React as
snap
2024-10-07 16:38:06 -04:00
lauren
0e43aa7f7a
[snap] Remove unnecessary React.c override (#31141) 2024-10-07 16:31:59 -04:00
lauren
d2367f17d9
[rcr] Reexport React.__COMPILER_RUNTIME.c or fallback to polyfill (#31140)
This PR updates the standalone `react-compiler-runtime` package to
either re-export `React.__COMPILER_RUNTIME.c` or to use a userspace
polyfill.
2024-10-07 16:31:20 -04:00
mofeiZ
68d59d43d5
[compiler][ez] Fix reanimated custom type defs for imports (#31137)
When we added support for Reanimated, we didn't distinguish between true
globals (i.e. identifiers with no static resolutions), module types, and
imports #29188. For the past 3-4 months, Reanimated imports were not
being matched to the correct hook / function shape we match globals and
module imports against two different registries.

This PR fixes our support for Reanimated library functions imported
under `react-native-reanimated`. See test fixtures for details
2024-10-07 13:09:39 -04:00
lauren
91c42a14c7
[rcr][ez] Clean up unused $read from rcr (#31136) 2024-10-07 12:39:14 -04:00
mofeiZ
1460d67c5b
[compiler][hir] Only hoist always-accessed PropertyLoads from function decls (#31066)
Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at
bottom):
* __->__ #31066
* #31032

Prior to this PR, we consider all of a nested function's accessed paths
as 'hoistable' (to the basic block in which the function was defined).
Now, we traverse nested functions and find all paths hoistable to their
*entry block*.

Note that this only replaces the *hoisting* part of function
declarations, not dependencies. This realistically only affects optional
chains within functions, which always get truncated to its inner
non-optional path (see
[todo-infer-function-uncond-optionals-hoisted.tsx](576f3c0aa8/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.tsx))

See newly added test fixtures for details

Update: Note that toggling `enableTreatFunctionDepsAsConditional` makes
a non-trivial impact on granularity of inferred deps (i.e. we find that
function declarations uniquely identify some paths as hoistable).
Snapshot comparison of internal code shows ~2.5% of files get worse
dependencies ([internal
link](https://www.internalfb.com/phabricator/paste/view/P1625792186))
2024-10-03 14:41:32 -04:00
mofeiZ
edacbde73f
[compiler][hir-rewrite] Check mutability of base identifier when hoisting (#31032)
Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at
bottom):
* #31066
* __->__ #31032

Prior to this PR, we check whether the property load source (e.g. the
evaluation of `<base>` in `<base>.property`) is mutable + scoped to
determine whether the property load itself is eligible for hoisting.
This changes to check the base identifier of the load.
- This is needed for the next PR #31066. We want to evaluate whether the
base identifier is mutable within the context of the *outermost
function*. This is because all LoadLocals and PropertyLoads within a
nested function declaration have mutable-ranges within the context of
the function, but the base identifier is a context variable.
- A side effect is that we no longer infer loads from props / other
function arguments as mutable in edge cases (e.g. props escaping out of
try-blocks or being assigned to context variables)
2024-10-03 13:55:59 -04:00
Mofei Zhang
0751fac747 [compiler] Optional chaining for dependencies (HIR rewrite)
Adds HIR version of `PropagateScopeDeps` to handle optional chaining.

Internally, this improves memoization on ~4% of compiled files (internal links: [1](https://www.internalfb.com/intern/paste/P1610406497/))

Summarizing the changes in this PR.
1. `CollectOptionalChainDependencies` recursively traverses optional blocks down to the base. From the base, we build up a set of `baseIdentifier.propertyA?.propertyB` mappings.
The tricky bit here is that optional blocks sometimes reference other optional blocks that are *not* part of the same chain e.g. a(c?.d)?.d. See code + comments in `traverseOptionalBlock` for how we avoid concatenating unrelated blocks.

2. Adding optional chains into non-null object calculation.
(Note that marking `a?.b` as 'non-null' means that `a?.b.c` is safe to evaluate, *not* `(a?.b).c`. Happy to rename this / reword comments accordingly if there's a better term)
This pass is split into two stages. (1) collecting non-null objects by block and (2) propagating non-null objects across blocks. The only significant change here was to (2). We add an extra reduce step `X=Reduce(Union(X, Intersect(X_neighbors)))` to merge optional and non-optional nodes (e.g. nonNulls=`{a, a?.b}` reduces to `{a, a.b}`)

3. Adding optional chains into dependency calculation.
This was the trickiest. We need to take the "maximal" property chain as a dependency. Prior to this PR, we avoided taking subpaths e.g. `a.b` of `a.b.c` as dependencies by only visiting non-PropertyLoad/LoadLocal instructions. This effectively only recorded the property-path at site-of-use.

    Unfortunately, this *quite* doesn't work for optional chains for a few reasons:
    - We would need to skip relevant `StoreLocal`/`Branch terminal` instructions (but only those within optional blocks that have been successfully read).
    - Given an optional chain, either (1) only a subpath or (2) the entire path can be represented as a PropertyLoad. We cannot directly add the last hoistable optional-block as a dependency as MethodCalls are an edge case e.g. given a?.b.c(), we should depend on `a?.b`, not `a?.b.c`
      This means that we add its dependency at either the innermost unhoistable optional-block or when encountering it within its phi-join.

4. Handle optional chains in DeriveMinimalDependenciesHIR.
This was also a bit tricky to formulate. Ideally, we would avoid a 2^3 case join (cond | uncond cfg, optional | not optional load, access | dependency). This PR attempts to simplify by building two trees
    1. First add each hoistable path into a tree containing `Optional | NonOptional` nodes.
    2. Then add each dependency into another tree containing `Optional | NonOptional`, `Access | Dependency` nodes, truncating the dependency at the earliest non-hoistable node (i.e. non-matching pair when walking the hoistable tree)

ghstack-source-id: a2170f26280dfbf65a4893d8a658f863a0fd0c88
Pull Request resolved: https://github.com/facebook/react/pull/31037
2024-10-02 13:30:55 -04:00
Mofei Zhang
c67e241c16 [compiler] Renames and no-op refactor for next PR
Rename for clarity:
- `CollectHoistablePropertyLoads:Tree` -> `CollectHoistablePropertyLoads:PropertyPathRegistry`
    - `getPropertyLoadNode` -> `getOrCreateProperty`
    - `getOrCreateRoot` -> `getOrCreateIdentifier`
- `PropertyLoadNode` -> `PropertyPathNode`

Refactor to CFG joining logic for `CollectHoistablePropertyLoads`. We now write to the same set of inferredNonNullObjects when traversing from entry and exit blocks. This is more correct, as non-nulls inferred from a forward traversal should be included when computing the backward traversal (and vice versa). This fix is needed by an edge case in #31036

Added invariant into fixed-point iteration to terminate (instead of infinite looping).

ghstack-source-id: 1e8eb2d566b649ede93de9a9c13dad09b96416a5
Pull Request resolved: https://github.com/facebook/react/pull/31036
2024-09-30 12:35:16 -04:00
Mofei Zhang
2cbea245cc [compiler][fixtures] Patch error-handling edge case in snap evaluator
Fix edge case in which we incorrectly returned a cached exception instead of trying to rerender with new props.
ghstack-source-id: 843fb85df4a2ae7a88f296104fb16b5f9a34c76e
Pull Request resolved: https://github.com/facebook/react/pull/31082
2024-09-30 12:35:16 -04:00
Mofei Zhang
5d12e9e10b [compiler] repro for dep merging edge case (non-hir)
Found when writing #31037, summary copied from comments:

This is an extreme edge case and not code we'd expect any reasonable developer to write. In most cases e.g. `(a?.b != null ? a.b : DEFAULT)`, we do want to take a dependency on `a?.b`.

I found this trying to come up with edge cases that break the current dependency + CFG merging logic. I think it makes sense to error on the side of correctness. After all, we still take `a` as a dependency if users write `a != null ? a.b : DEFAULT`, and the same fix (understanding the `<hoistable> != null` test expression) works for both. Can be convinced otherwise though!

ghstack-source-id: cc06afda59f7681e228495f5e35a596c20f875f5
Pull Request resolved: https://github.com/facebook/react/pull/31035
2024-09-30 12:35:16 -04:00
Mofei Zhang
58a3ca3b47 [compiler][hir-rewrite] Cleanup Identifier -> IdentifierId
Since removing ExitSSA, Identifier and IdentifierId should mean the same thing

ghstack-source-id: 076cacbe8360e716b0555088043502823f9ee72e
Pull Request resolved: https://github.com/facebook/react/pull/31034
2024-09-30 12:35:16 -04:00
Mofei Zhang
8c89fa7643 [compiler][hir-rewrite] Infer non-null props, destructure source
Followup from #30894.
This adds a new flagged mode `enablePropagateScopeDepsInHIR: "enabled_with_optimizations"`, under which we infer more hoistable loads:
- it's always safe to evaluate loads from `props` (i.e. first parameter of a `component`)
- destructuring sources are safe to evaluate loads from (e.g. given `{x} = obj`, we infer that it's safe to evaluate obj.y)
- computed load sources are safe to evaluate loads from (e.g. given `arr[0]`, we can infer that it's safe to evaluate arr.length)

ghstack-source-id: 32f3bb72e9f85922825579bd785d636f4ccf724d
Pull Request resolved: https://github.com/facebook/react/pull/31033
2024-09-30 12:35:16 -04:00
Mofei Zhang
1a779207a7 [compiler][test fixtures] Add enablePropagateDepsInHIR to forked tests
Annotates fixtures added in #31030 with `@enablePropagateDepsInHIR` to fork behavior (and commit snapshot differences)
ghstack-source-id: e423e8c42db62f1bb87562b770761be09fc8ffc6
Pull Request resolved: https://github.com/facebook/react/pull/31031
2024-09-30 12:35:15 -04:00
Mofei Zhang
943e45e910 [compiler][test fixtures] Fork more fixtures for hir-rewrite
Followup from #30894 , not sure how these got missed. Note that this PR just copies the fixtures without adding `@enablePropagateDepsInHIR`. #31032 follows and actually enables the HIR-version of propagateScopeDeps to run. I split this out into two PRs to make snapshot differences easier to review, but also happy to merge

Fixtures found from locally setting snap test runner to default to `enablePropagateDepsInHIR: 'enabled_baseline'` and forking fixtures files with different output.

ghstack-source-id: 7d7cf41aa923d83ad49f89079171b0411923ce6b
Pull Request resolved: https://github.com/facebook/react/pull/31030
2024-09-30 12:35:15 -04:00
Lauren Tan
db240980a3
[playground] Decouple playground from compiler
Currently the playground is setup as a linked workspace for the
compiler which complicates our yarn workspace setup and means that snap
can sometimes pull in a different version of react than was otherwise
specified.

There's no real reason to have these workspaces combined so let's split
them up.

ghstack-source-id: 56ab064b2f
Pull Request resolved: https://github.com/facebook/react/pull/31081
2024-09-27 15:25:07 -04:00
Lauren Tan
3edc000d77
[compiler] Fix broken tests
ghstack-source-id: 000a37ae1f819eef676dcd52410d5231cd2d50fe
Pull Request resolved: https://github.com/facebook/react/pull/31078
2024-09-26 17:44:28 -04:00
dependabot[bot]
d0772d5866
Bump axios from 1.7.1 to 1.7.4 in /compiler (#30694)
Bumps [axios](https://github.com/axios/axios) from 1.7.1 to 1.7.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.7.4</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>sec:</strong> CVE-2024-39338 (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>)
(<a
href="6b6b605eaf">6b6b605</a>)</li>
<li><strong>sec:</strong> disregard protocol-relative URL to remediate
SSRF (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)
(<a
href="07a661a2a6">07a661a</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/levpachmanov"
title="+47/-11 ([#6543](https://github.com/axios/axios/issues/6543)
)">Lev Pachmanov</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/hainenber"
title="+49/-4 ([#6539](https://github.com/axios/axios/issues/6539) )">Đỗ
Trọng Hải</a></li>
</ul>
<h2>Release v1.7.3</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>adapter:</strong> fix progress event emitting; (<a
href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>)
(<a
href="e3c76fc9bd">e3c76fc</a>)</li>
<li><strong>fetch:</strong> fix withCredentials request config (<a
href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>)
(<a
href="85d4d0ea0a">85d4d0e</a>)</li>
<li><strong>xhr:</strong> return original config on errors from XHR
adapter (<a
href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>)
(<a
href="8966ee7ea6">8966ee7</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+211/-159
([#6518](https://github.com/axios/axios/issues/6518)
[#6519](https://github.com/axios/axios/issues/6519) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ValeraS"
title="+3/-3 ([#6515](https://github.com/axios/axios/issues/6515)
)">Valerii Sidorenko</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/prianyu"
title="+2/-2 ([#6505](https://github.com/axios/axios/issues/6505)
)">prianYu</a></li>
</ul>
<h2>Release v1.7.2</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>fetch:</strong> enhance fetch API detection; (<a
href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>)
(<a
href="4f79aef81b">4f79aef</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+3/-3
([#6413](https://github.com/axios/axios/issues/6413) )">Dmitriy
Mozgovoy</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/axios/axios/compare/v1.7.3...v1.7.4">1.7.4</a>
(2024-08-13)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>sec:</strong> CVE-2024-39338 (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>)
(<a
href="6b6b605eaf">6b6b605</a>)</li>
<li><strong>sec:</strong> disregard protocol-relative URL to remediate
SSRF (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)
(<a
href="07a661a2a6">07a661a</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/levpachmanov"
title="+47/-11 ([#6543](https://github.com/axios/axios/issues/6543)
)">Lev Pachmanov</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/hainenber"
title="+49/-4 ([#6539](https://github.com/axios/axios/issues/6539) )">Đỗ
Trọng Hải</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.7.2...v1.7.3">1.7.3</a>
(2024-08-01)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>adapter:</strong> fix progress event emitting; (<a
href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>)
(<a
href="e3c76fc9bd">e3c76fc</a>)</li>
<li><strong>fetch:</strong> fix withCredentials request config (<a
href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>)
(<a
href="85d4d0ea0a">85d4d0e</a>)</li>
<li><strong>xhr:</strong> return original config on errors from XHR
adapter (<a
href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>)
(<a
href="8966ee7ea6">8966ee7</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+211/-159
([#6518](https://github.com/axios/axios/issues/6518)
[#6519](https://github.com/axios/axios/issues/6519) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ValeraS"
title="+3/-3 ([#6515](https://github.com/axios/axios/issues/6515)
)">Valerii Sidorenko</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/prianyu"
title="+2/-2 ([#6505](https://github.com/axios/axios/issues/6505)
)">prianYu</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.7.1...v1.7.2">1.7.2</a>
(2024-05-21)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>fetch:</strong> enhance fetch API detection; (<a
href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>)
(<a
href="4f79aef81b">4f79aef</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+3/-3
([#6413](https://github.com/axios/axios/issues/6413) )">Dmitriy
Mozgovoy</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="abd24a7367"><code>abd24a7</code></a>
chore(release): v1.7.4 (<a
href="https://redirect.github.com/axios/axios/issues/6544">#6544</a>)</li>
<li><a
href="6b6b605eaf"><code>6b6b605</code></a>
fix(sec): CVE-2024-39338 (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>)</li>
<li><a
href="07a661a2a6"><code>07a661a</code></a>
fix(sec): disregard protocol-relative URL to remediate SSRF (<a
href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)</li>
<li><a
href="c6cce43cd9"><code>c6cce43</code></a>
chore(release): v1.7.3 (<a
href="https://redirect.github.com/axios/axios/issues/6521">#6521</a>)</li>
<li><a
href="e3c76fc9bd"><code>e3c76fc</code></a>
fix(adapter): fix progress event emitting; (<a
href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>)</li>
<li><a
href="85d4d0ea0a"><code>85d4d0e</code></a>
fix(fetch): fix withCredentials request config (<a
href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>)</li>
<li><a
href="92cd8ed943"><code>92cd8ed</code></a>
chore(github): update ISSUE_TEMPLATE.md (<a
href="https://redirect.github.com/axios/axios/issues/6519">#6519</a>)</li>
<li><a
href="8966ee7ea6"><code>8966ee7</code></a>
fix(xhr): return original config on errors from XHR adapter (<a
href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>)</li>
<li><a
href="0e4f9fa290"><code>0e4f9fa</code></a>
chore(release): v1.7.2 (<a
href="https://redirect.github.com/axios/axios/issues/6414">#6414</a>)</li>
<li><a
href="4f79aef81b"><code>4f79aef</code></a>
fix(fetch): enhance fetch API detection; (<a
href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>)</li>
<li>See full diff in <a
href="https://github.com/axios/axios/compare/v1.7.1...v1.7.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.7.1&new-version=1.7.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/facebook/react/network/alerts).

</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-26 09:51:12 -04:00
dependabot[bot]
9927ab238b
Bump rollup from 4.13.2 to 4.22.4 in /compiler (#31039)
Bumps [rollup](https://github.com/rollup/rollup) from 4.13.2 to 4.22.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/releases">rollup's
releases</a>.</em></p>
<blockquote>
<h2>v4.22.4</h2>
<h2>4.22.4</h2>
<p><em>2024-09-21</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Fix a vulnerability in generated code that affects IIFE, UMD and CJS
bundles when run in a browser context (<a
href="https://redirect.github.com/rollup/rollup/issues/5671">#5671</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5670">#5670</a>:
refactor: Use object.prototype to check for reserved properties (<a
href="https://github.com/YuHyeonWook"><code>@​YuHyeonWook</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5671">#5671</a>:
Fix DOM Clobbering CVE (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.22.3</h2>
<h2>4.22.3</h2>
<p><em>2024-09-21</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Ensure that mutations in modules without side effects are observed
while properly handling transitive dependencies (<a
href="https://redirect.github.com/rollup/rollup/issues/5669">#5669</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5669">#5669</a>:
Ensure impure dependencies of pure modules are added (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.22.2</h2>
<h2>4.22.2</h2>
<p><em>2024-09-20</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Revert fix for side effect free modules until other issues are
investigated (<a
href="https://redirect.github.com/rollup/rollup/issues/5667">#5667</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5667">#5667</a>:
Partially revert <a
href="https://redirect.github.com/rollup/rollup/issues/5658">#5658</a>
and re-apply <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a>
(<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.22.1</h2>
<h2>4.22.1</h2>
<p><em>2024-09-20</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Revert <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a>
&quot;stable chunk hashes&quot; while issues are being investigated</li>
</ul>
<h3>Pull Requests</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/blob/master/CHANGELOG.md">rollup's
changelog</a>.</em></p>
<blockquote>
<h2>4.22.4</h2>
<p><em>2024-09-21</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Fix a vulnerability in generated code that affects IIFE, UMD and CJS
bundles when run in a browser context (<a
href="https://redirect.github.com/rollup/rollup/issues/5671">#5671</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5670">#5670</a>:
refactor: Use object.prototype to check for reserved properties (<a
href="https://github.com/YuHyeonWook"><code>@​YuHyeonWook</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5671">#5671</a>:
Fix DOM Clobbering CVE (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.22.3</h2>
<p><em>2024-09-21</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Ensure that mutations in modules without side effects are observed
while properly handling transitive dependencies (<a
href="https://redirect.github.com/rollup/rollup/issues/5669">#5669</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5669">#5669</a>:
Ensure impure dependencies of pure modules are added (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.22.2</h2>
<p><em>2024-09-20</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Revert fix for side effect free modules until other issues are
investigated (<a
href="https://redirect.github.com/rollup/rollup/issues/5667">#5667</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5667">#5667</a>:
Partially revert <a
href="https://redirect.github.com/rollup/rollup/issues/5658">#5658</a>
and re-apply <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a>
(<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.22.1</h2>
<p><em>2024-09-20</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Revert <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a>
&quot;stable chunk hashes&quot; while issues are being investigated</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5663">#5663</a>:
chore(deps): update dependency inquirer to v11 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5664">#5664</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/5665">#5665</a>:
fix: type in CI file (<a
href="https://github.com/YuHyeonWook"><code>@​YuHyeonWook</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="79c0aba353"><code>79c0aba</code></a>
4.22.4</li>
<li><a
href="e2552c9e95"><code>e2552c9</code></a>
Fix DOM Clobbering CVE (<a
href="https://redirect.github.com/rollup/rollup/issues/5671">#5671</a>)</li>
<li><a
href="10ab90ea61"><code>10ab90e</code></a>
refactor: Use object.prototype to check for reserved properties (<a
href="https://redirect.github.com/rollup/rollup/issues/5670">#5670</a>)</li>
<li><a
href="e1cba8e84a"><code>e1cba8e</code></a>
4.22.3</li>
<li><a
href="59cec3e867"><code>59cec3e</code></a>
Ensure impure dependencies of pure modules are added (<a
href="https://redirect.github.com/rollup/rollup/issues/5669">#5669</a>)</li>
<li><a
href="b86ffd776c"><code>b86ffd7</code></a>
4.22.2</li>
<li><a
href="d5ff63de9e"><code>d5ff63d</code></a>
Partially revert <a
href="https://redirect.github.com/rollup/rollup/issues/5658">#5658</a>
and re-apply <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a>
(<a
href="https://redirect.github.com/rollup/rollup/issues/5667">#5667</a>)</li>
<li><a
href="0a821d9318"><code>0a821d9</code></a>
Create SECURITY.md</li>
<li><a
href="76e962daca"><code>76e962d</code></a>
4.22.1</li>
<li><a
href="68c23da882"><code>68c23da</code></a>
Partially revert <a
href="https://redirect.github.com/rollup/rollup/issues/5644">#5644</a></li>
<li>Additional commits viewable in <a
href="https://github.com/rollup/rollup/compare/v4.13.2...v4.22.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rollup&package-manager=npm_and_yarn&previous-version=4.13.2&new-version=4.22.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/facebook/react/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-26 09:45:02 -04:00
Jack Pope
632f88df11
[compiler] Allow ReactElement symbol to be configured when inlining jsx (#30996)
Based on https://github.com/facebook/react/pull/30995 ([rendered
diff](https://github.com/jackpope/react/compare/inline-jsx-2...jackpope:react:inline-jsx-3?expand=1))

____

Some apps still use `react.element` symbols. Not only do we want to test
there but we also want to be able to upgrade those sites to
`react.transitional.element` without blocking on the compiler (we can
change the symbol feature flag and compiler config at the same time).

The compiler runtime uses `react.transitional.element`, so the snap
fixture will fail if we change the default here. However I confirmed
that commenting out the fixture entrypoint and running snap with
`react.element` will update the fixture symbols as expected.
2024-09-19 10:34:24 -04:00
Jack Pope
d5e955d3c0
[compiler] Pass through unmodified props spread when inlining jsx (#30995)
If JSX receives a props spread without additional attributes (besides
`ref` and `key`), we can pass the spread object as a property directly
to avoid the extra object copy.

```
<Test {...propsToSpread} />
// {props: propsToSpread}
<Test {...propsToSpread} a="z" />
// {props: {...propsToSpread, a: "z"}}
```
2024-09-19 10:07:29 -04:00
Jack Pope
5dcb009760
[compiler] Add JSX inlining optimization (#30867)
This adds an `InlineJsxTransform` optimization pass, toggled by the
`enableInlineJsxTransform` flag. When enabled, JSX will be transformed
into React Element object literals, preventing runtime overhead during
element creation.

TODO:
- [ ] Add conditionals to make transform PROD-only
- [ ] Make the React element symbol configurable so this works with
runtimes that support `react.element` or `react.transitional.element`
- [ ] Look into additional optimization to pass props spread through
directly if none of the properties are mutated
2024-09-18 11:51:36 -04:00
Mike Vitousek
7b56a54298 [compiler][playground] create playground API in pipeline, and allow spaces in pass names
Summary:
1. Minor refactor to provide a stable API for calling the compiler from the playground
2. Allows spaces in pass names without breaking the appearance of the playground by replacing spaces with &nbsp; in pass tabs

ghstack-source-id: 12a43ad86c16c0e21f3e6b4086d531cdefd893eb
Pull Request resolved: https://github.com/facebook/react/pull/30988
2024-09-17 11:05:59 -07:00
mofeiZ
a99d8e8d97
[compiler][eslint] Report bailout diagnostics with correct column # (#30977)
Compiler bailout diagnostics should now highlight only the first line of
the source location span.

(Resubmission of #30423 which was reverted due to invalid column
number.)
2024-09-16 15:56:24 -04:00
Mike Vitousek
d7167c3505 [compiler] Implement support for hoisted and recursive functions
Summary:
Introduces a new binding kind for functions that allows them to be hoisted. Also has the result of causing all nested function declarations to be outputted as function declarations, not as let bindings.

ghstack-source-id: fa40d4909fb3d30c23691e36510ebb3c3cc41053
Pull Request resolved: https://github.com/facebook/react/pull/30922
2024-09-16 11:12:58 -07:00
Mike Vitousek
e78c9362c0 [compiler] Allow all hooks to take callbacks which access refs, but ban hooks from taking direct ref value arguments
Summary:
This brings the behavior of ref mutation within hook callbacks into alignment with the behavior of global mutations--that is, we allow all hooks to take callbacks that may mutate a ref. This is potentially unsafe if the hook eagerly calls its callback, but the alternative is excessively limiting (and inconsistent with other enforcement).

This also bans *directly* passing a ref.current value to a hook, which was previously allowed.

ghstack-source-id: e66ce7123e
Pull Request resolved: https://github.com/facebook/react/pull/30917
2024-09-16 10:53:34 -07:00
Mike Vitousek
1e68a0a3ae [compiler] Improve handling of refs
Summary:
This change expands our handling of refs to build an understanding of nested refs within objects and functions that may return refs. It builds a special-purpose type system within the ref analysis that gives a very lightweight structural type to objects and array expressions (merging the types of all their members), and then propagating those types throughout the analysis (e.g., if `ref` has type `Ref`, then `{ x: ref }` and `[ref]` have type `Structural(value=Ref)` and `{x: ref}.anything` and `[ref][anything]` have type `Ref`).

This allows us to support structures that contain refs, and functions that operate over them, being created and passed around during rendering without at runtime accessing a ref value.

The analysis here uses a fixpoint to allow types to be fully propagated through the system, and we defend against diverging by widening the type of a variable if it could grow infinitely: so, in something like
```
let x = ref;
while (condition) {
  x = [x]
}
```
we end up giving `x` the type `Structural(value=Ref)`.

ghstack-source-id: afb0b0cb01
Pull Request resolved: https://github.com/facebook/react/pull/30902
2024-09-16 10:53:32 -07:00
Mike Vitousek
c8a7cab13f [compiler] Fix issue where second argument of all functions was considered to be a ref
ghstack-source-id: 1817f3b816
Pull Request resolved: https://github.com/facebook/react/pull/30912
2024-09-16 10:53:29 -07:00
Mike Vitousek
633a0fe536 [compiler] Factor out function effects from reference effects
Summary:
This PR performs a major refactor of InferReferenceEffects to separate out the work on marking places with Effects from inferring FunctionEffects. The behavior should be identical after this change (see [internal sync](https://www.internalfb.com/intern/everpaste/?handle=GN74VxscnUaztTYDAL8q0CRWBIxibsIXAAAB)) but the FunctionEffect logic should be easier to work with.

These analyses are unfortunately still deeply linked--the FunctionEffect analysis needs to reason about the "current" value kind for each point in the program, while the InferReferenceEffects algorithm performs global updates on the state of the program (e.g. freezing). In the future, it might be possible to make these entirely separate passes if we store the ValueKind directly on places.

For the most part, the logic of reference effects and function effects can be cleanly separated: for each instruction and terminal, we visit its places and infer their effects, and then we visit its places and infer any function effects that they cause. The biggest wrinkle here is that when a transitive function freeze operation occurs, it has to happen *after* inferring the function effects on the place, because otherwise we may convert a value from Context to Frozen, which will cause the ContextualMutation function effect to be converted to a ReactMutation effect too early. This can be observed in a case like this:

```
export default component C() {
  foo(() => {
    const p = {};
    return () => {
      p['a'] = 1
    };
  });
}
```
Here when the outer function returns the inner function, it freezes the inner function which transitively freezes `p`. But before that freeze happens, we need to replay the ContextualMutation on the inner function to determine that the value is mutable in the outer context. If we froze `p` first, we would instead convert the ContextualMutation to a ReactMutation and error.

To handle this, InferReferenceEffects now delays the exection of the freezeValue action until after it's called the helper functions that generate function effects. So the order of operations on a given place is now

set effect --> generate function effects --> transitively freeze dependencies, if applicable

ghstack-source-id: 21cb50c14054e7e7a307acb595ef30b54c2f2a52
Pull Request resolved: https://github.com/facebook/react/pull/30920
2024-09-13 12:38:17 -07:00
Mofei Zhang
206df66e70 [compiler][rewrite] PropagateScopeDeps hir rewrite
Resubmission of #30079 -- core logic unchanged, but needed to rebase past #30573

### Quick background
#### Temporaries

The compiler currently treats temporaries and named variables (e.g. `x`) differently in this pass.
- named variables may be reassigned (in fact, since we're running after LeaveSSA, a single named identifier's IdentifierId may map to multiple `Identifier` instances -- each with its own scope and mutable range)
- temporaries are replaced with their represented expressions during codegen. This is correct (mostly correct, see #29878) as we're careful to always lower the correct evaluation semantics. However, since we rewrite reactive scopes entirely (to if/else blocks), we need to track temporaries that a scope produces in `ReactiveScope.declarations` and later promote them to named variables.
In the same example, $4, $5, and $6 need to be promoted: $2 ->`t0`,  $5 ->`t1`, and $6 ->`t2`.
```js
[1] $2 = LoadGlobal(global) foo
[2] $3 = LoadLocal bar$1
scope 0:
  [3] $4 = Call $2(<unknown> $3)
scope 1:
  [4] $5 = Object {  }
scope 2:
  [5] $6 = Object { a: $4, b: $5 }
[6] $8 = StoreLocal Const x$7 = $6
```

#### Dependencies
`ReactiveScope.dependencies` records the set of (read-only) values that a reactive scope is dependent on. This is currently limited to just variables (named variables from source and promoted temporaries) and property-loads.
All dependencies we record need to be hoistable -- i.e. reordered to just before the ReactiveScope begins. Not all PropertyLoads are hoistable.

In this example, we should not evaluate `obj.a.b` without before creating x and checking `objIsNull`.
```js
// reduce-reactive-deps/no-uncond.js
function useFoo({ obj, objIsNull }) {
  const x = [];
  if (isFalse(objIsNull)) {
    x.push(obj.a.b);
  }
  return x;
}
```

While other memoization strategies with different constraints exist, the current compiler requires that `ReactiveScope.dependencies` be re-orderable to the beginning of the reactive scope. But.. `PropertyLoad`s from null values will throw `TypeError`. This means that evaluating hoisted dependencies should throw if and only if the source program throws. (It is also a bug if source throws and compiler output does not throw. See https://github.com/facebook/react-forget/pull/2709)

---
### Rough high level overview
1. Pass 1
Walk over instructions to gather every temporary used outside of its defining scope (same as ReactiveFunction version). These determine the sidemaps we produce, as temporaries used outside of their declaring scopes get promoted to named variables later (and are not considered hoistable rvals).
2. Pass 2 (collectTemporariesSidemap)
Walk over instructions to generate a sidemap of temporary identifier -> named variable and property path (e.g. `$3 -> {obj: props, path: ["a", "b"]}`)
2. Pass 2 (collectHoistablePropertyLoads)
  a. Build a sidemap of block -> accessed variables and properties (e.g. `bb0 -> [ {obj: props, path: ["a", "b"]} ]`)
  b. Propagate "non-nullness" i.e. variables and properties for which we can safely evaluate `PropertyLoad`.
  A basic block can unconditionally read from identifier X if any of the following applies:
    - the block itself reads from identifier X
    - all predecessors of the block read from identifier X
    - all successors of the block read from identifier X
4. Pass 3: (collectDependencies)
Walks over instructions again to record dependencies and declarations, using the previously produced sidemaps. We do not record any control-flow here
5. Merge every scope's recorded dependencies with the set of hoistable PropertyLoads

Tested by syncing internally and (1) checking compilation output differences ([internal link](https://www.internalfb.com/intern/everpaste/?handle=GPCfUBt_HCoy_S4EAJDVFJyJJMR0bsIXAAAB)), running internally e2e tests ([internal link](https://fburl.com/sandcastle/cs5mlkxq))

---
### Followups:
1. Rewrite function expression deps
This change produces much more optimal output as the compiler now uses the function CFG to understand which variables / paths are assumed to be non-null. However, it may exacerbate [this function-expr hoisting bug](https://github.com/facebook/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-hoisting-functionexpr.tsx). A short term fix here is to simply call some form of `collectNonNullObjects` on every function expression to find hoistable variable / paths. In the longer term, we should refactor out `FunctionExpression.deps`.

2. Enable optional paths
(a) don't count optional load temporaries as dependencies (e.g. `collectOptionalLoadRValues(...)`).
(b) record optional paths in both collectHoistablePropertyLoads and dependency collection

ghstack-source-id: 2507f6ea751dce09ad1dccd353ae6fc7cf411582
Pull Request resolved: https://github.com/facebook/react/pull/30894
2024-09-12 17:40:57 -04:00
Mofei Zhang
5ac4034e14 [compiler] Fork fixtures for enablePropagateDepsInHIR
- flip `enablePropagateDepsInHIR` to off by default
- fork fixtures which produce compilation differences in #30894 to separate directory `propagate-scope-deps-hir-fork`, to be cleaned up when we remove this flag

ghstack-source-id: 7d5b8dc29788a65c272c846af9877b09fbf2cd60
Pull Request resolved: https://github.com/facebook/react/pull/30949
2024-09-12 17:40:57 -04:00
Mofei Zhang
f6dcce5199 [compiler][ez] Add entrypoints to ssa fixtures
Adds evaluator support for a few compiler test fixtures

ghstack-source-id: 202654992a9876cea59885b54a338c908e369ddb
Pull Request resolved: https://github.com/facebook/react/pull/30948
2024-09-12 17:40:57 -04:00
Joe Savona
d724ba96ff [compiler] Validate type configs for hooks/non-hooks
Alternative to #30868. The goal is to ensure that the types coming out of moduleTypeProvider are valid wrt to hook typing. If something is named like a hook, then it must be typed as a hook (or don't type it).

ghstack-source-id: 3e8b5a0a7010d0c484bbb417fb258e76bf4e32bc
Pull Request resolved: https://github.com/facebook/react/pull/30888
2024-09-10 09:25:28 -07:00
Mike Vitousek
a8fc4b1ef8 [compiler][playground] Fix displayed naming of outlined functions
ghstack-source-id: 20c8e9eeba1620b061e41119dfb1a0e15c36645e
Pull Request resolved: https://github.com/facebook/react/pull/30907
2024-09-07 17:50:19 -07:00
Mofei Zhang
bd788b4180 [compiler] Add enablePropagateDepsInHIR flag
Adding new feature flag in preparation for #30894

ghstack-source-id: 59278028cf178d6b2c28732ded751e9c838183d2
Pull Request resolved: https://github.com/facebook/react/pull/30893
2024-09-06 13:02:08 -04:00
Mofei Zhang
7b98a168fd [compiler][cleanup] Delete now-unused reactive scope fork
Followup to #30891

ghstack-source-id: 6b42055b5d28da39d99a235bcd86a82eb7c270f4
Pull Request resolved: https://github.com/facebook/react/pull/30892
2024-09-06 13:02:08 -04:00
Mofei Zhang
43264a61d0 [compiler][cleanup] Remove unused enableReactiveScopesInHIR flag
Reactive scopes in HIR has been stable for over 3 months now and is the future direction of react compiler, removing this flag to reduce implementation forks.

ghstack-source-id: 65cdf63cf76029fa22d40fd85aba0ac976dcfc08
Pull Request resolved: https://github.com/facebook/react/pull/30891
2024-09-06 13:02:08 -04:00
Joe Savona
f820f5a8b6 [compiler] Type inference for tagged template literals
At Meta we have a pattern of using tagged template literals for features that are compiled away:

```
// Relay:
graphql`...graphql text...`
```

In many cases these tags produce a primitive value, and we can get even more optimal output if we can tell the compiler about these types. The new moduleTypeProvider gives us the ability to declare such types, this PR extends the compiler to use this type information for TaggedTemplateExpression values.

ghstack-source-id: 3cd6511b7f4e708bcb86f3f3fde5773bc51c7197
Pull Request resolved: https://github.com/facebook/react/pull/30869
2024-09-04 13:28:33 -07:00
Joe Savona
071dd00366 [compiler] Errors in earlier functions dont stop subsequent compilation
Errors in an earlier component/hook shouldn't stop later components from compiling.

ghstack-source-id: 6e04a5bb2e2045303cbddad6d6d4bd38d5f7990b
Pull Request resolved: https://github.com/facebook/react/pull/30844
2024-08-29 22:41:53 -07:00
Joe Savona
fc0df475c4 [compiler] Inferred deps must match exact optionality of manual deps
To prevent any difference in behavior, we check that the optionality of the inferred deps exactly matches the optionality of the manual dependencies. This required a fix, I was incorrectly inferring optionality of manual deps (they're only optional if OptionalTerminal.optional is true) - for nested cases of mixed optional/non-optional.

ghstack-source-id: afd49e89cc
Pull Request resolved: https://github.com/facebook/react/pull/30840
2024-08-28 15:59:26 -07:00
Joe Savona
3a45ba241c [compiler] Enable optional dependencies by default
Per title. This gives us much more granular memoization when the source used optional member expressions. Note that we only infer optional deps when the source used optionals: we don't (yet) infer optional dependencies from conditionals.

ghstack-source-id: 104d0b712d
Pull Request resolved: https://github.com/facebook/react/pull/30838
2024-08-28 15:59:26 -07:00
Joe Savona
99a4b26e18 [compiler] Handle optional where innermost property access is non-optional
Handles an additional case as part of testing combinations of the same path being accessed in different places with different segments as optional/unconditional.

ghstack-source-id: ace777fcbb
Pull Request resolved: https://github.com/facebook/react/pull/30836
2024-08-28 15:59:25 -07:00
Joe Savona
7475d568da [wip][compiler] Infer optional dependencies
Updates PropagateScopeDeps and DeriveMinimalDeps to understand optional dependency paths (`a?.b`). There a few key pieces to this:

In PropagateScopeDeps we jump through some hoops to work around the awkward structure of nested OptionalExpressions. This is much easier in HIR form, but I managed to get this pretty close and i think it will be landable with further cleanup. A good chunk of this is avoiding prematurely registering a value as a dependency - there are a bunch of indirections in the ReactiveFunction structure:

```
t0 = OptionalExpression
  SequenceExpression
    t0 = Sequence
      ...
    LoadLocal t0
```

Where if at any point we call `visitOperand()` we'll prematurely register a dependency instead of declareProperty(). The other bit is that optionals can be optional=false for nested member expressions where not all the parts are actually optional (`foo.bar?.bar.call()`). And of course, parts of an optional chain can still be conditional even when optional=true (for example the `x` in `foo.bar?.[x]?.baz`). Not all of this is tested yet so there are likely bugs still.

The other bit is DeriveMinimalDeps, which is thankfully easier. We add OptionalAccess and OptionalDep and update the merge and reducing logic for these cases. There is probably still more to update though, for things like merging subtrees. There are a lot of ternaries that assume a result can be exactly one of two states (conditional/unconditional, dependency/access) and these assumptions don't hold anymore. I'd like to refactor to dependency/access separate from conditional/optional/unconditional. Also, the reducing logic isn't quite right: once a child is optional we keep inferring all the parents as optional too, losing some precision. I need to adjust the reducing logic to let children decide whether their path token is optional or not.

ghstack-source-id: 207842ac64
Pull Request resolved: https://github.com/facebook/react/pull/30819
2024-08-28 15:59:25 -07:00
Joe Savona
9180a37fba [compiler] Allow inferred non-optional paths when manual deps were optional
If the inferred deps are more precise (non-optional) than the manual deps (optional) it should pass validation.

The other direction also seems like it would be fine - inferring optional deps when the original was non-optional - but for now let's keep the "at least as precise" rule.

ghstack-source-id: 9f7a99ee5f
Pull Request resolved: https://github.com/facebook/react/pull/30816
2024-08-28 15:59:25 -07:00
Joe Savona
925c20a206 [compiler] Add fallthrough to branch terminal
Branch terminals didn't have a fallthrough because they correspond to an outer terminal (optional, logical, etc) that has the "real" fallthrough. But understanding how branch terminals correspond to these outer terminals requires knowing the branch fallthrough. For example, `foo?.bar?.baz` creates terminals along the lines of:

```
bb0:
  optional fallthrough=bb4
bb1:
  optional fallthrough=bb3
bb2:
  ...
  branch ... (fallthrough=bb3)

...

bb3:
  ...
  branch ... (fallthrough=bb4)

...

bb4:
  ...
```

Without a fallthrough on `branch` terminals, it's unclear that the optional from bb0 has its branch node in bb3. With the fallthroughs, we can see look for a branch with the same fallthrough as the outer optional terminal to match them up.

ghstack-source-id: d48c623289
Pull Request resolved: https://github.com/facebook/react/pull/30814
2024-08-28 15:59:25 -07:00
Joe Savona
a718da0b23 [compiler] Add DependencyPath optional property
Adds an `optional: boolean` property to each token in a DependencyPath, currently always set to false. Also updates the equality and printing logic for paths to account for this field.

Subsequent PRs will update our logic to determine which manual dependencies were optional, then we can start inferring optional deps as well.

ghstack-source-id: 66c2da2cfa
Pull Request resolved: https://github.com/facebook/react/pull/30813
2024-08-28 15:59:25 -07:00
Joe Savona
4759161ed8 [compiler] Wrap ReactiveScopeDep path tokens in object
Previously the path of a ReactiveScopeDependency was `Array<string>`. We need to track whether each property access is optional or not, so as a first step we change this to `Array<{property: string}>`, making space for an additional property in a subsequent PR.

ghstack-source-id: c5d38d72f6
Pull Request resolved: https://github.com/facebook/react/pull/30812
2024-08-28 15:59:25 -07:00
Joe Savona
5e51d767d1 [compiler] Stop reusing ScopeDep type in AnalyzeFunctions
AnalyzeFunctions was reusing the `ReactiveScopeDependency` type since it happened to have a convenient shape, but we need to change this type to represent optionality. We now use a locally defined type instead.

ghstack-source-id: e305c6ede4
Pull Request resolved: https://github.com/facebook/react/pull/30811
2024-08-28 15:59:25 -07:00
Mike Vitousek
7771d3a797 [compiler] Track refs through object expressions and property lookups
Summary:
This addresses the issue of the compiler being overly restrictive about refs escaping into object expressions. Rather than erroring whenever a ref flows into an object, we will now treat the object itself as a ref, and apply the same escape rules to it. Whenever we look up a property from a ref value, we now don't know whether that value is itself a ref or a ref value, so we assume it's both.

The same logic applies to ref-accessing functions--if such a function is stored in an object, we'll propagate that property to the object itself and any properties looked up from it.

ghstack-source-id: 5c6fcb895d4a1658ce9dddec286aad3a57a4c9f1
Pull Request resolved: https://github.com/facebook/react/pull/30821
2024-08-27 10:11:50 -07:00
Mike Vitousek
f2841c2a49 [compiler] Fixture to demonstrate issue with returning object containing ref
Summary:
We currently can return a ref from a hook but not an object containing a ref.

ghstack-source-id: 8b1de4991eb2731b7f758e685ba62d9f07d584b2
Pull Request resolved: https://github.com/facebook/react/pull/30820
2024-08-27 10:11:50 -07:00
Joe Savona
1b7478246d [compiler] Special-case phi inference for mixed readonly type
This allows us to handle common operations such as `useFragment(...).edges.nodes ?? []` where we have a `Phi(MixedReadonly, Array)`. The underlying pattern remains general-purpose and not Relay-specific, and any API that returns transitively "mixed" data (primitives, arrays, plain objects) can benefit from the same type refinement.

ghstack-source-id: 51283108942002a14d032613a9d0b8b665ee3a94
Pull Request resolved: https://github.com/facebook/react/pull/30797
2024-08-23 15:24:44 -07:00
Joe Savona
4f54674078 [compiler] Infer phi types, extend mutable ranges to account for Store effects
Redo of an earlier (pre-OSS) PR to infer types of phi nodes. There are a few pieces to this:

1. Update InferTypes to infer the type of `phi.id.type`, not the unused `phi.type`.
2. Update the algorithm to verify that all the phi types are actually equal, not just have the same kind.
3. Handle circular types by removing the cycle.

However, that reveals another issue: InferMutableRanges currently infers the results of `Store` effects _after_ its fixpoint loop. That was fine when a Store could never occur on a phi (since they wouldn't have a type to get a function signature from). Now though, we can have Store effects occur on phis, and we need to ensure that this correctly updates the mutable range of the phi operands - recursively. See new test that fails without the fixpoint loop.

ghstack-source-id: 2e1b02844d3a814dce094b7e3812df799e54343f
Pull Request resolved: https://github.com/facebook/react/pull/30796
2024-08-23 15:24:44 -07:00
Joe Savona
c9c170b63b [compiler] Remove phi type, infer phi.id.type
ghstack-source-id: 0c26bb224c6d5431898e683891df9b1a5c2e5b63
Pull Request resolved: https://github.com/facebook/react/pull/30795
2024-08-23 15:24:44 -07:00
Joe Savona
37c6ea849c [compiler] Typedefs for Array.prototype.flatMap
ghstack-source-id: af4c7ac2fd26f6ff332a1af0055c80b70838efee
Pull Request resolved: https://github.com/facebook/react/pull/30794
2024-08-23 15:24:44 -07:00
Joe Savona
039c5c08fa [compiler] Repros for missing memoization due to lack of phi type inference
This is a complex case: we not only need phi type inference but also need to be able infer the union of `MixedReadonly | Array`.

ghstack-source-id: 935088910dd8c210b3253cf8ff1f4b935f5081b7
Pull Request resolved: https://github.com/facebook/react/pull/30793
2024-08-23 15:24:44 -07:00
Lauren Tan
b57d282369
Revert "[compiler][eslint] remove compilationMode override; report bailouts on first line"
This reverts commit b34b750729.

This hack doesn't play well internally so I'm reverting this for now
(but keeping the compilationMode override). I'll audit the locations we
report later and try to make them more accurate so we won't need this
workaround.

ghstack-source-id: b6be29c11d
Pull Request resolved: https://github.com/facebook/react/pull/30792
2024-08-22 15:04:39 -04:00
Joe Savona
7a3fcc9898 [compiler] Flatten returnIdentifier to just returnType
We don't a full Identifier object for the return type, we can just store the type.

ghstack-source-id: 4594d64ce3900ced3e461945697926489898318e
Pull Request resolved: https://github.com/facebook/react/pull/30790
2024-08-22 09:33:09 -07:00
Joe Savona
98b5740821 [compiler] Rename HIRFunction.returnType
Rename this field so we can use it for the actual return type.

ghstack-source-id: 118d7dcfbbcc40911bf6d13f14e70053e436738d
Pull Request resolved: https://github.com/facebook/react/pull/30789
2024-08-22 09:33:09 -07:00
Joe Savona
8410c8b959 [compiler] Infer return types of function expressions
Uses the returnIdentifier added in the previous PR to provide a stable identifier for which we can infer a return type for functions, then wires up the equations in InferTypes to infer the type.

ghstack-source-id: 22c0a9ea096daa5f72821fca2a5ff5b199f65c8b
Pull Request resolved: https://github.com/facebook/react/pull/30785
2024-08-22 09:33:09 -07:00
Joe Savona
217a0efcd9 [compiler] Add returnIdentifier to function expressions
This gives us a place to store type information, used in follow-up PRs.

ghstack-source-id: ee0bfa253f63c30ccaac083b9f1f72b76617f19c
Pull Request resolved: https://github.com/facebook/react/pull/30784
2024-08-22 09:33:09 -07:00
Joe Savona
8a20fc3b19 [compiler] Repro of missing memoization due to capturing w/o mutation
If you have a function expression which _captures_ a mutable value (but does not mutate it), and that function is invoked during render, we infer the invocation as a mutation of the captured value. But in some circumstances we can prove that the captured value cannot have been mutated, and could in theory avoid inferring a mutation.

ghstack-source-id: 47664e48ce8c51a6edf4d714d1acd1ec4781df80
Pull Request resolved: https://github.com/facebook/react/pull/30783
2024-08-22 09:33:09 -07:00
Joe Savona
689c6bd3fd [compiler][wip] Environment option for resolving imported module types
Adds a new Environment config option which allows specifying a function that is called to resolve types of imported modules. The function is passed the name of the imported module (the RHS of the import stmt) and can return a TypeConfig, which is a recursive type of the following form:

* Object of valid identifier keys (or "*" for wildcard) and values that are TypeConfigs
* Function with various properties, whose return type is a TypeConfig
* or a reference to a builtin type using one of a small list (currently Ref, Array, MixedReadonly, Primitive)

Rather than have to eagerly supply all known types (most of which may not be used) when creating the config, this function can do so lazily. During InferTypes we call `getGlobalDeclaration()` to resolve global types. Originally this was just for known react modules, but if the new config option is passed we also call it to see if it can resolve a type. For `import {name} from 'module'` syntax, we first resolve the module type and then call `getPropertyType(moduleType, 'name')` to attempt to retrieve the property of the module (the module would obviously have to be typed as an object type for this to have a chance of yielding a result). If the module type is returned as null, or the property doesn't exist, we fall through to the original checking of whether the name was hook-like.

TODO:
* testing
* cache the results of modules so we don't have to re-parse/install their types on each LoadGlobal of the same module
* decide what to do if the module types are invalid. probably better to fatal rather than bail out, since this would indicate an invalid configuration.

ghstack-source-id: bfdbf67e3dd0cbfd511bed0bd6ba92266cf99ab8
Pull Request resolved: https://github.com/facebook/react/pull/30771
2024-08-22 09:33:09 -07:00
Joe Savona
0ef00b3e17 [compiler] Transitively freezing functions marks values as frozen, not effects
The fixture from the previous PR was getting inconsistent behavior because of the following:
1. Create an object in a useMemo
2. Create a callback in a useCallback, where the callback captures the object from (1) into a local object, then passes that local object into a logging method. We have to assume the logging method could modify the local object, and transitively, the object from (1).
3. Call the callback during render.
4. Pass the callback to JSX.

We correctly infer that the object from (1) is captured and modified in (2). However, in (4) we transitively freeze the callback. When transitively freezing functions we were previously doing two things: updating our internal abstract model of the program values to reflect the values as being frozen *and* also updating function operands to change their effects to freeze.

As the case above demonstrates, that can clobber over information about real potential mutability. The potential fix here is to only walk our abstract value model to mark values as frozen, but _not_ override operand effects. Conceptually, this is a forward data flow propagation — but walking backward to update effects is pushing information backwards in the algorithm. An alternative would be to mark that data was propagated backwards, and trigger another loop over the CFG to propagate information forward again given the updated effects. But the fix in this PR is more correct.

ghstack-source-id: c05e716f37827cb5515a059a1f0e8e8ff94b91df
Pull Request resolved: https://github.com/facebook/react/pull/30766
2024-08-22 09:33:08 -07:00
Joe Savona
f7bb717e9e [compiler] Repro for missing memoization due to inferred mutation
This fixture bails out on ValidatePreserveExistingMemo but would ideally memoize since the original memoization is safe. It's trivial to make it pass by commenting out the commented line (`LogEvent.log(() => object)`). I would expect the compiler to infer this as possible mutation of `logData`, since `object` captures a reference to `logData`. But somehow `logData` is getting memoized successfully, but we still infer the callback, `setCurrentIndex`, as having a mutable range that extends to the `setCurrentIndex()` call after the useCallback.

ghstack-source-id: 4f82e345102f82f6da74de3f9014af263d016762
Pull Request resolved: https://github.com/facebook/react/pull/30764
2024-08-22 09:33:08 -07:00
Joe Savona
d2413bf377 [compiler] Validate against JSX in try statements
Per comments on the new validation pass, this disallows creating JSX (expression/fragment) within a try statement. Developers sometimes use this pattern thinking that they can catch errors during the rendering of the element, without realizing that rendering is lazy. The validation allows us to teach developers about the error boundary pattern.

ghstack-source-id: 0bc722aeaed426ddd40e075c008f0ff2576e0c33
Pull Request resolved: https://github.com/facebook/react/pull/30725
2024-08-19 11:24:23 -07:00
Joe Savona
177b2419b2 [compiler] Validate environment config while parsing plugin opts
Addresses a todo from a while back. We now validate environment options when parsing the plugin options, which means we can stop re-parsing/validating in later phases.

ghstack-source-id: b19806e843e1254716705b33dcf86afb7223f6c7
Pull Request resolved: https://github.com/facebook/react/pull/30726
2024-08-16 17:05:03 -07:00
Lauren Tan
a58276cbc3
[playground] Allow (Arrow)FunctionExpressions
This was a pet peeve where our playground could only compile top level
FunctionDeclarations. Just synthesize a fake identifier if it doesn't
have one.

ghstack-source-id: 882483c79c
Pull Request resolved: https://github.com/facebook/react/pull/30729
2024-08-16 18:12:05 -04:00
Lauren Tan
34edf3b684
[compiler] Surface unused opt out directives in eslint
This PR updates the eslint plugin to report unused opt out directives.
One of the downsides of the opt out directive is that it opts the
component/hook out of compilation forever, even if the underlying issue
was fixed in product code or fixed in the compiler.

ghstack-source-id: 81deb5c11b
Pull Request resolved: https://github.com/facebook/react/pull/30721
2024-08-16 18:12:05 -04:00
Lauren Tan
e9a869fbb5
[compiler] Run compiler pipeline on 'use no forget'
This PR updates the babel plugin to continue the compilation pipeline as
normal on components/hooks that have been opted out using a directive.
Instead, we no longer emit the compiled function when the directive is
present.

Previously, we would skip over the entire pipeline. By continuing to
enter the pipeline, we'll be able to detect if there are unused
directives.

The end result is:

- (no change) 'use forget' will always opt into compilation
- (new) 'use no forget' will opt out of compilation but continue to log
  errors without throwing them. This means that a Program containing
multiple functions (some of which are opted out) will continue to
compile correctly

ghstack-source-id: 5bd85df2f8
Pull Request resolved: https://github.com/facebook/react/pull/30720
2024-08-16 18:12:04 -04:00
Mike Vitousek
5edbe29dbe [compiler] Make ref enforcement on by default
Summary:
The change earlier in this stack makes it less safe to have ref enforcement disabled. This diff enables it by default.

ghstack-source-id: d3ab5f1b28b7aed0f0d6d69547bb638a1e326b66
Pull Request resolved: https://github.com/facebook/react/pull/30716
2024-08-16 13:27:14 -04:00
Mike Vitousek
21a95239e1 [compiler] Allow functions containing refs to be returned
Summary:
We previously were excessively strict about preventing functions that access refs from being returned--doing so is potentially valid for hooks, because the return value may only be used in an event or effect.

ghstack-source-id: cfa8bb1b54e8eb365f2de50d051bd09e09162d7b
Pull Request resolved: https://github.com/facebook/react/pull/30724
2024-08-16 13:27:14 -04:00
Mike Vitousek
1016174af5 [compiler] Reposition ref-in-render errors to the read location of .current
Summary:
Since we want to make ref-in-render errors enabled by default, we should position those errors at the location of the read. Not only will this be a better experience, but it also aligns the behavior of Forget and Flow.

This PR also cleans up the resulting error messages to not emit implementation details about place values.

ghstack-source-id: 1d1131706867a6fc88efddd631c4d16d2181e592
Pull Request resolved: https://github.com/facebook/react/pull/30723
2024-08-16 13:27:13 -04:00
Mike Vitousek
8a53160111 [compiler] Don't error on ref-in-render on StartMemoize
Test Plan:
Fixes the previous issue: ref enforcement ignores memoization marker instructions

ghstack-source-id: f35d6a611c5e740e9ea354ec80c3d7cdb3c0d658
Pull Request resolved: https://github.com/facebook/react/pull/30715
2024-08-16 13:27:13 -04:00
Mike Vitousek
7468ac530e [compiler] Fixture to show ref-in-render enforcement issue with useCallback
Test Plan:
Documents that useCallback calls interfere with it being ok for refs to escape as part of functions into jsx

ghstack-source-id: a5df427981ca32406fb2325e583b64bbe26b1cdd
Pull Request resolved: https://github.com/facebook/react/pull/30714
2024-08-16 13:27:13 -04:00
Mike Vitousek
5030e08575 [compiler] Exclude refs and ref values from having mutable ranges
Summary:
Refs, as stable values that the rules of react around mutability do not apply to, currently are treated as having mutable ranges, and through aliasing, this can extend the mutable range for other values and disrupt good memoization for those values. This PR excludes refs and their .current values from having mutable ranges.

Note that this is unsafe if ref access is allowed in render: if a mutable value is assigned to ref.current and then ref.current is mutated later, we won't realize that the original mutable value's range extends.

ghstack-source-id: e8f36ac25e2c9aadb0bf13bd8142e4593ee9f984
Pull Request resolved: https://github.com/facebook/react/pull/30713
2024-08-16 13:27:13 -04:00
Mike Vitousek
50d2197dd5 [compiler] Support for member expression inc/decrement
Test Plan:
Builds support for a.x++ and friends. Similar to a.x += y, emits it as an assignment expression.

ghstack-source-id: 8f3979913aad561cdba70464c3cc5f0ee95887b5
Pull Request resolved: https://github.com/facebook/react/pull/30697
2024-08-15 15:00:36 -04:00
Mike Vitousek
bb6acc20af [compiler] Allow hoisting of destructured variable declarations
Summary:
It doesn't seem as though this invariant was necessary

ghstack-source-id: b27e76525911d5cfc1991b5cfdb7b2074c039e21
Pull Request resolved: https://github.com/facebook/react/pull/30699
2024-08-15 14:27:38 -04:00
Joe Savona
c39da3e4de [compiler] Off-by-default validation against setState directly in passive effect
Per discussion today, adds validation against calling setState "during" passive effects. Basically, it's fine to _schedule_ setState to be called (via a timeout, listener, etc) but generally not recommended to call setState during the effect since that will trigger a cascading render.

This validation is off by default, i'm putting this up for discussion and to experiment with it internally.

ghstack-source-id: 5f385ddab59561ec3939ae5ece265dfee4f2cb56
Pull Request resolved: https://github.com/facebook/react/pull/30685
2024-08-15 10:38:23 -04:00
Mike Vitousek
dd8e0ba857 [compiler] Support for useTransition
Summary:
UseTransition is a builtin hook that returns a stable value, like useState. This PR represents that in Forget, and marks the startTransition function as stable.

ghstack-source-id: 0e76a64f2d0c86a4eb55c620922b4698250bb5c3
Pull Request resolved: https://github.com/facebook/react/pull/30681
2024-08-14 13:54:39 -04:00
Mike Vitousek
179197a22a [compiler] Allow different dependencies from explicit memoization when dependency is a ref
Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: 685d859d1eed5d1e19dbbbfadc75be3875ddb6ea
Pull Request resolved: https://github.com/facebook/react/pull/30679
2024-08-14 13:54:39 -04:00
Mike Vitousek
8e60bacd08 [compiler] Reordering of logical expressions
ghstack-source-id: ad484f97451c65a2642618bfb9d540d6a53a19a6
Pull Request resolved: https://github.com/facebook/react/pull/30678
2024-08-13 16:57:45 -04:00
Mike Vitousek
a601d1da36 [compiler] Allow lets to be hoisted
ghstack-source-id: 02f4698bd98705a855deb0d4bc30b9829afdddc0
Pull Request resolved: https://github.com/facebook/react/pull/30674
2024-08-13 16:35:56 -04:00
Mike Vitousek
0d7c12c779 [compiler][ez] Enable some sprout tests that no longer need to be disabled
Summary:
As title. Better support for flow typing, bugfixes, etc fixes these

ghstack-source-id: 6326653ce42b33b6c1c76a494434d133382ca80a
Pull Request resolved: https://github.com/facebook/react/pull/30591
2024-08-12 12:55:55 -07:00
Mike Vitousek
6532c41256 [compiler] Allow macro methods
Summary:
Builds support for macros that are invoked as methods rather than just function calls or jsx.

We now record macros as a schema that represents arbitrary member expressions including wildcards (so we can support, e.g., myMacro.*.foo.bar). When examining PropertyLoads in the macro memoization stage, we build up a map of partially-satisfied macro patterns until we determine that the pattern has been fully satisfied, at which point we treat the result of the PropertyLoad as a macro value.

ghstack-source-id: d78d9ba7041968c861ffa110fb7882b339a0e257
Pull Request resolved: https://github.com/facebook/react/pull/30589
2024-08-12 12:55:55 -07:00
Mike Vitousek
d50e024fd4 [compiler] Promote temporaries when necessary to prevent codegen reordering over side-effectful operations
ghstack-source-id: 639191e63a
Pull Request resolved: https://github.com/facebook/react/pull/30554
2024-08-12 12:36:49 -07:00
Lauren Tan
fbe81b214a
[compiler] Publish to latest tag
> [!NOTE]
> The `latest` tag is published by default if no tag is specified, which
> is what we had done since the first release of the compiler

In my last PR to auto publish compiler releases I had added the
experimental tag to be used in publishing. However because we had
already previously published to the latest tag (which is non-removable)
this means that the `latest` tag is pinned to an old version. That makes
untagged installs of the compiler default to that old version instead of
whatever is the latest.

This changes the behavior back to what it was before. Since we are still
in the experimental release of the compiler anyway it seems fine to use
the latest tag. When we reach stable, we can update this to only push to
latest for stable releases.

ghstack-source-id: 1809481b45
Pull Request resolved: https://github.com/facebook/react/pull/30666
2024-08-12 14:41:11 -04:00
Mofei Zhang
8d74e8c73a [compiler] Patch error reporting for blocklisted imports
ghstack-source-id: 614c1e9c04828bfa2da13a6abaeff7ce3e67cb9b
Pull Request resolved: https://github.com/facebook/react/pull/30652
2024-08-09 15:19:07 -07:00
hylinz
2504dbd669
Punctuation & correcting spelling mistakes (#30592) 2024-08-09 14:53:53 -07:00
Joe Savona
54a150dc6e [compiler][be] Remove completed todo comment
We made block types explicit a long time ago, this comment is super stale

ghstack-source-id: 810a34bb4c14a3f4541003db23ffb7ad91aecc8c
Pull Request resolved: https://github.com/facebook/react/pull/30633
2024-08-09 14:11:01 -07:00
Joe Savona
229038eab8 [compiler][be] Cleanup class naming in PromoteUsedTemporaries
I forgot to clean this up before landing #30573.

ghstack-source-id: 2141471912e410aa12545dcf7989f45447007ba9
Pull Request resolved: https://github.com/facebook/react/pull/30632
2024-08-09 14:11:01 -07:00
Mofei Zhang
2d2cc042d7 [compiler][ez] Option to bail out on blocklisted imports
ghstack-source-id: 540d154b25e49a83683a05fc9326dbd0ad59a6bd
Pull Request resolved: https://github.com/facebook/react/pull/30643
2024-08-09 09:10:01 -07:00
Mofei Zhang
3871fdadaa [compiler][be] Clean up compilation skipping logic in Program
ghstack-source-id: fe2c81de9d4f41a787c690b722cbcff55eb18ac3
Pull Request resolved: https://github.com/facebook/react/pull/30642
2024-08-09 09:10:01 -07:00
Mofei Zhang
0fb03c4952 [compiler][ez] Add types for Math.min, recursive global
ghstack-source-id: 9940b8f96eec3fb2b411af8a7c92d93aae6da85e
Pull Request resolved: https://github.com/facebook/react/pull/30641
2024-08-09 09:10:01 -07:00
Jan Kassens
fb1c63fb76
[compiler] remove duplicate root files (#30639)
These files are duplicates from the root from a time when React Compiler
was in a different repo.
2024-08-08 12:42:45 -04:00
Sathya Gunsasekaran
9d2da5913a [compiler] Add context callee import if required
Previously the compiler would add an import for the specified context
callee even if the context access was not lowered, leading to unused
imports.

This PR tracks if lowering has happened and adds the import only when
necessary.

ghstack-source-id: 6ad794da41116e1034783b6c4a58fbfe7790343e
Pull Request resolved: https://github.com/facebook/react/pull/30628
2024-08-08 15:53:13 +01:00
Sathya Gunsasekaran
83cc13f746 [compiler] Rewrite useContext callee
If a value is specified for the LowerContextAccess environment config,
we rewrite the callee from 'useContext' to the specificed value.

This will allow us run an experiment internally.

ghstack-source-id: 00e161b988c8f8a1cf96efff8095f050cb534cc1
Pull Request resolved: https://github.com/facebook/react/pull/30612
2024-08-08 15:53:13 +01:00
Sol Lee
8b31835fc0
[compiler] Replace for...in with for...of for array of strings (#30631)
closes https://github.com/facebook/react/issues/30627

Thanks!
2024-08-07 22:07:04 -07:00
Mofei Zhang
a037dabd42 [compiler] Patch ValidatePreserveMemo to bailout correctly for refs
ghstack-source-id: b9c13bf5f8
Pull Request resolved: https://github.com/facebook/react/pull/30603
2024-08-07 18:57:57 -07:00
Mofei Zhang
53194c8792 [compiler] Remove transitive memo check in validatePreserveMemo
ghstack-source-id: 45521370e4
Pull Request resolved: https://github.com/facebook/react/pull/30630
2024-08-07 18:57:56 -07:00
Mofei Zhang
2f8ff3deb2 [compiler][repro] False positives for ValidatePreserveMemo
ghstack-source-id: 7fa94fea86
Pull Request resolved: https://github.com/facebook/react/pull/30629
2024-08-07 18:57:56 -07:00
Mofei Zhang
2bd415355e [compiler][repro] ValidatePreserveMemo x useRef bug
ghstack-source-id: 6ac5d58e97
Pull Request resolved: https://github.com/facebook/react/pull/30602
2024-08-07 18:57:56 -07:00
Mofei Zhang
e662b0a24b [compiler][be] Less ambiguous error messages for validateMemo bailout
ghstack-source-id: 312093ec74
Pull Request resolved: https://github.com/facebook/react/pull/30601
2024-08-07 18:57:56 -07:00
Sathya Gunsasekaran
e948a5ac68 [compiler] Add lowerContextAccess pass
*This is only for internal profiling, not intended to ship.*

This pass is intended to be used with https://github.com/facebook/react/pull/30407.

This pass synthesizes selector functions by collecting immediately
destructured context acesses. We bailout for other types of context
access.

This pass lowers context access to use a selector function by passing
the synthesized selector function as the second argument.

ghstack-source-id: 92d0f6ff2f
Pull Request resolved: https://github.com/facebook/react/pull/30548
2024-08-07 16:30:11 +01:00
Mike Vitousek
9eb288e657 [compiler][ez] Default to using flow suppressions
ghstack-source-id: b6592650e0
Pull Request resolved: https://github.com/facebook/react/pull/30622
2024-08-06 23:47:09 -07:00
Lauren Tan
838da52d67
[ci] Fix incorrect tags being pushed for compiler releases
ghstack-source-id: 812e49333c
Pull Request resolved: https://github.com/facebook/react/pull/30620
2024-08-06 17:27:27 -04:00
Lauren Tan
030d83bab4
[ci] Fix dist-tag command
ghstack-source-id: bdbcc12b28
Pull Request resolved: https://github.com/facebook/react/pull/30619
2024-08-06 15:35:38 -04:00
Joe Savona
3d61b9b4cd [compiler] Stay in SSA form through entire pipeline
This PR updates to use SSA form through the entire compilation pipeline. This means that in both HIR form and ReactiveFunction form, `Identifier` instances map 1:1 to `IdentifierId` values. If two identifiers have the same IdentifierId, they are the same instance. What this means is that all our passes can use this more precise information to determine if two particular identifiers are not just the same variable, but the same SSA "version" of that variable.

However, some parts of our analysis really care about program variables as opposed to SSA versions, and were relying on LeaveSSA to reset identifiers such that all Identifier instances for a particular program variable would have the same IdentifierId (though not necessarily the same Identifier instance). With LeaveSSA removed, those analysis passes can now use DeclarationId instead to uniquely identify a program variable.

Note that this PR surfaces some opportunties to improve edge-cases around reassigned values being declared/reassigned/depended-upon across multiple scopes. Several passes could/should use IdentifierId to more precisely identify exactly which values are accessed - for example, a scope that reassigns `x` but doesn't use `x` prior to reassignment doesn't have to take a dependency on `x`. But today we take a dependnecy.

My approach for these cases was to add a "TODO LeaveSSA" comment with notes and the name of the fixture demonstrating the difference, but to intentionally preserve the existing behavior (generally, switching to use DeclarationId when IdentifierId would have been more precise).

Beyond updating passes to use DeclarationId instead of Identifier/IdentifierId, the other change here is to extract out the remaining necessary bits of LeaveSSA into a new pass that rewrites InstructionKind (const/let/reassign/etc) based on whether a value is actually const or has reassignments and should be let.

ghstack-source-id: 69afdaee5fadf3fdc98ce97549da805f288218b4
Pull Request resolved: https://github.com/facebook/react/pull/30573
2024-08-06 12:02:50 -07:00
Joe Savona
22360089b5 [compiler] Add Identifier.declarationId
Adds `Identifier.declarationId` and the new `DeclarationId` (simulated) opaque type. DeclarationId allows uniquely identifying a variable in the original source, ie regardless of reassignments. This allows us to stay in SSA form throughout compilation (see next diff) while still being able to distinguish SSA versions (via IdentifierId) and non-SSA versions (DeclarationId).

ghstack-source-id: f2547a58aa7b30cea29fcfe23d5cb45583858a4e
Pull Request resolved: https://github.com/facebook/react/pull/30569
2024-08-06 12:02:50 -07:00
Lauren Tan
02217c9e12
[ci] Make compiler publish script runnable
ghstack-source-id: 309bda2bc3
Pull Request resolved: https://github.com/facebook/react/pull/30617
2024-08-06 14:59:19 -04:00
Lauren Tan
47d85282bc
[ci] Add prerelease nightly and manual script for compiler
Publishes the compiler packages on the same schedule as the React ones.
For now the manual script can only build from `main` but in the future
we can add support for building specific commits

ghstack-source-id: 66676c578b795b90bf3c5715be8900438868b6ee
Pull Request resolved: https://github.com/facebook/react/pull/30615
2024-08-06 14:48:33 -04:00
Lauren Tan
c9143b98d0
[compiler] Refactor release script
Updates the release script to publish tags as well as take a `--ci`
option

Test plan:
```
$ yarn npm:publish --debug --frfr

yarn run v1.22.22
$ node scripts/release/publish --debug --frfr
ℹ Preparing to publish (for real) [debug=true]
ℹ Building packages
✔ Successfully built babel-plugin-react-compiler
✔ Successfully built eslint-plugin-react-compiler
✔ Successfully built react-compiler-healthcheck
NPM 2-factor auth code: ******
✔ Wrote package.json for babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806

========== babel-plugin-react-compiler ==========

⠧ Publishing babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 to npm
+ babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806

✔ Successfully published babel-plugin-react-compiler to npm
ℹ dry-run: npm dist-tag add babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 experimental --otp=******
✔ Successfully pushed dist-tag experimental for babel-plugin-react-compiler to npm
✔ Wrote package.json for eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806

========== eslint-plugin-react-compiler ==========

⠹ Publishing eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 to npm
+ eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806

✔ Successfully published eslint-plugin-react-compiler to npm
ℹ dry-run: npm dist-tag add eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 experimental --otp=******
✔ Successfully pushed dist-tag experimental for eslint-plugin-react-compiler to npm
✔ Wrote package.json for react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806

========== react-compiler-healthcheck ==========

⠙ Publishing react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 to npm
+ react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806

✔ Successfully published react-compiler-healthcheck to npm
ℹ dry-run: npm dist-tag add react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 experimental --otp=******
✔ Successfully pushed dist-tag experimental for react-compiler-healthcheck to npm

 All done
  Done in 50.64s.
```

ghstack-source-id: 405cc001c2ab2adaad2bfe4f11fdb7fd28d7e2d1
Pull Request resolved: https://github.com/facebook/react/pull/30614
2024-08-06 14:48:33 -04:00
Lauren Tan
e8a2b47eb5
[compiler] Remove sleep in manual release script
I originally added this prior to the compiler being OSS'd as a "just in
case" feature to panic cancel if something went wrong. Now that the
compiler is already launched this is unnecessary.

ghstack-source-id: dd17dc8a331657ce23c0cbc012ba967cfc3b9542
Pull Request resolved: https://github.com/facebook/react/pull/30613
2024-08-06 14:48:33 -04:00
Lauren Tan
ff0d2621f4
Fix rust lints
ghstack-source-id: baf433a98a70d9105c8088d82e04a3d96783e9e6
Pull Request resolved: https://github.com/facebook/react/pull/30616
2024-08-06 14:48:32 -04:00
Sathya Gunsasekaran
eb1d52b01b [compiler] Refactor createTemporaryPlace
Update createTemporaryPlace to use makeTemporary and also rename
makeTemporary to makeTemporaryIdentifier to make it less ambiguous.

ghstack-source-id: b5955d3d667064f2ccf7e633ab63df2269dc56fa
Pull Request resolved: https://github.com/facebook/react/pull/30585
2024-08-06 15:30:01 +01:00
Mike Vitousek
3af905d954 [compiler] Fix issue with macro arguments being outlined
Summary:
Fixes issue documented by #30435. We change the pipeline order so that outlining comes after tracking macro operands, and any function that is referenced in a macro will now not be outlined.

ghstack-source-id: f731ad65c8b84db3fc5f3a2ff3a6986112765963
Pull Request resolved: https://github.com/facebook/react/pull/30587
2024-08-02 14:55:55 -07:00
Mike Vitousek
47337a842a [compiler] Allow global mutation effects in arguments passed to hooks and in return values
ghstack-source-id: f9ea675ead6eb61b3afc2a3deace0da270612d9d
Pull Request resolved: https://github.com/facebook/react/pull/30576
2024-08-02 12:24:41 -07:00
Sathya Gunsasekaran
bae18b4dfe [compiler] Add flag for lowering context access
*This is only for internal profiling, not intended to ship.*

ghstack-source-id: e48998b7be4272199c8a6ff9cc2ec0975add5030
Pull Request resolved: https://github.com/facebook/react/pull/30547
2024-08-02 18:13:51 +01:00
Sathya Gunsasekaran
f5f9899bee [compiler] Add typing for useContext hook
In the future, we can use this to identify useContext calls.

ghstack-source-id: 01d7b0941ccd09f65346eb5431aa53fe361ce5ed
Pull Request resolved: https://github.com/facebook/react/pull/30546
2024-08-02 18:13:51 +01:00
Sathya Gunsasekaran
ce6078521e [compiler] Refactor makeTemporary outside HIRBuilder
This is a useful utility function similar to the existing
`makeInstructionId` and `makeIdentifierId` functions.

This PR moves it outside the HIRBuilder so we can use this in passes
that don't have access to the builder instance.

ghstack-source-id: 1ac0839e6cb417aedcdf8cdd159af7069af7172a
Pull Request resolved: https://github.com/facebook/react/pull/30545
2024-08-02 18:13:51 +01:00
Sathya Gunsasekaran
a5a58164ea [compiler] Simplify FunctionExpression node
Rather than storing the entire babel node, store only the required
information which is the node type.

This will be useful for when we synthesize new functions that don't have
a corresponding babel node.

ghstack-source-id: 9098cbdbc4b1e9a6e7dafa2e7645f6f4854e1eac
Pull Request resolved: https://github.com/facebook/react/pull/30544
2024-08-02 18:13:51 +01:00
Joe Savona
1db4d6c415 [compiler] Validate against setState in useMemo (resubmit of #30552)
ghstack failed to land #30552 properly, resubmitting

Developers sometimes use `useMemo()` as a way to conditionally execute code, including conditionally calling setState. However, the compiler may remove existing useMemo calls if they are not necessary, which _should_ always be a safe optimization. If the useMemo has side effects (eg sets state), then this isn't safe.

This PR improves ValidateNoSetStateInRender to disallow any setState in useMemo (even if it's conditional), expanding on the previous check for unconditional setState in render. Note that the approach uses the StartMemoize/FinishMemoize instructions added in DropManualMemo to know whether a particular setState call is within a useMemo or not. This means enabling the validation in DropManualMemo when the setState validation is enabled, but that's fine since that validation is on everywhere by default (_except_ for in fixtures, which we have a todo for)

ghstack-source-id: 65bb3289c3
Pull Request resolved: https://github.com/facebook/react/pull/30583
2024-08-02 10:06:08 -07:00
Mike Vitousek
56dbd58feb [compiler] More complete validation against locals being reassigned after render
Summary:
This diff extends the existing work on validating against locals being reassigned after render, by propagating the reassignment "effect" into the lvalues of instructions when the rvalue operands include values known to cause reassignments. In particular, this "closes the loop" for function definitions and function calls: a function that returns a function that reassigns will be considered to also perform reassignments, but previous to this we didn't consider the result of a `Call` of a function that reassigns to itself be a value that reassigns.

This causes a number of new bailouts in test cases, all of which appear to me to be legit.

ghstack-source-id: 770bf02d079ea2480be243a49caa6f69573d8092
Pull Request resolved: https://github.com/facebook/react/pull/30540
2024-07-31 11:11:07 -07:00
Lauren Tan
d06196c1cd
[compiler] Visit nested scopes in pruned scopes in PromoteUsedTemporaries
While debugging #30536 I happened to notice that the bug only reproduced
when there was interleaving scopes, and observed that an unpruned scope
nested inside of a pruned one was not being visited by
CollectPromotableTemporaries, which keeps track of which identifiers
should be promoted later. Therefore when actually promoting temporaries
we were skipping over the identifiers in children of pruned scopes

ghstack-source-id: d805f62f22
Pull Request resolved: https://github.com/facebook/react/pull/30537
2024-07-30 17:05:23 -04:00
Mofei Zhang
edfaa99f01 [compiler][repro] JSX tag local variable is named lowercase
ghstack-source-id: f9ac4641e171a1ae3450f733fef71be346447866
Pull Request resolved: https://github.com/facebook/react/pull/30536
2024-07-30 16:32:09 -04:00
Mofei Zhang
212d5ae8cb [compiler][repro] fixtures for fbt plural and macro bugs
ghstack-source-id: 8ccf49bb40cd634932b84dd637439042aa60fd46
Pull Request resolved: https://github.com/facebook/react/pull/30535
2024-07-30 16:32:09 -04:00
Mofei Zhang
704c34e21f [compiler] Bail out on local variables named 'fbt'
ghstack-source-id: c4e2b802a029b9dd7941ebcdeaaf471ddd95f868
Pull Request resolved: https://github.com/facebook/react/pull/30524
2024-07-30 16:32:09 -04:00
Mofei Zhang
7c8734c41c [compiler][repro] Fbt local var incompatibility repro
ghstack-source-id: ec256a365bdcef7c10da2af2b58f3931e259ad65
Pull Request resolved: https://github.com/facebook/react/pull/30523
2024-07-30 16:32:09 -04:00
Jan Kassens
41ecbada0e
Enable prettier for some blocklisted fixtures with invalid GraphQL (#30425)
The invalid GraphQL in these fixtures somehow causes an unhandled
promise rejection error when running `yarn prettier-all`. This fixes
that issue by making the GraphQL valid.
2024-07-30 14:23:43 -04:00
Mofei Zhang
a8f5c4e16d [compiler] patch: retain UpdateExpression for globals
ghstack-source-id: aff6606f85698ccda13d1deffb6faa9d91f9821a
Pull Request resolved: https://github.com/facebook/react/pull/30471
2024-07-29 13:18:45 -04:00
Mofei Zhang
2a9274a73e [compiler] Repro: updates to globals should be retained
ghstack-source-id: 7ee813c0d72e3c752b299f63bfcec3647b022544
Pull Request resolved: https://github.com/facebook/react/pull/30470
2024-07-29 13:18:45 -04:00
Mofei Zhang
e215aa1160 [compiler] Fix FBT whitespace handling again (again (again))
ghstack-source-id: 00a86e41cfb8a6fb56b7fcd811740d1d9b89a611
Pull Request resolved: https://github.com/facebook/react/pull/30451
2024-07-29 13:18:45 -04:00
Mofei Zhang
e0acd77aab [compiler] Todo for fbt with multiple pronoun/plural
ghstack-source-id: 77b6980c2b080771d18aa275c3b3258884bd463c
Pull Request resolved: https://github.com/facebook/react/pull/30437
2024-07-29 13:18:45 -04:00
Mofei Zhang
a15e8d7cdc [compiler][repro] Test fixture for fbt plural bug
ghstack-source-id: 222e7312c081faf36702a1c790a4e336b5bcc928
Pull Request resolved: https://github.com/facebook/react/pull/30432
2024-07-29 13:18:45 -04:00
Ahmed Abdelbaset
f7ee804c22
[compiler] Add git info to package.json files in compiler packages (#30475)
This PR adds the repository field to `compiler/packages/*/package.json`

| eslint-plugin-react-compiler | eslint-plugin-react-hooks |
| --- | --- |
|
![image](https://github.com/user-attachments/assets/3392a496-1ff1-4f36-ab96-cfbe1ed88693)
|
![image](https://github.com/user-attachments/assets/b0605dba-eef7-44fe-9484-979b4814d9fb)
|
2024-07-26 12:56:39 -04:00
Lauren Tan
a0e7ecfc6a
Bump version to 0.0.0-experimental-ab3118d-20240725 2024-07-25 15:46:47 -04:00
Lauren Tan
83035ee299
Bump version to 0.0.0-experimental-9ed098e-20240725 2024-07-25 15:46:46 -04:00
Lauren Tan
789c257d79
Bump version to 0.0.0-experimental-334f00b-20240725 2024-07-25 15:46:45 -04:00
Lauren Tan
9f3bbb05ab
[compiler] Make inserting outlined functions more resilient
To handle more cases, always append the synthetic outlined function as a
new child of the module rather than make assumptions about the original
function. This should handle whatever case where the original function
expression may be a child of a variety of parents

ghstack-source-id: 8581edb8be
Pull Request resolved: https://github.com/facebook/react/pull/30466
2024-07-25 15:38:19 -04:00
Lauren Tan
d529a43212
[compiler] Add repro for outlining in non VarDecls
ghstack-source-id: 7688987b02
Pull Request resolved: https://github.com/facebook/react/pull/30465
2024-07-25 15:38:19 -04:00