From 10a4c88f58233074f293ab387b73e96b67192538 Mon Sep 17 00:00:00 2001 From: inottn Date: Tue, 4 Feb 2025 00:41:04 +0800 Subject: [PATCH 1/3] [compiler] Handle TSInstantiationExpression in lowerExpression (#32302) Fix #31745 --- .../src/HIR/BuildHIR.ts | 1 + .../ts-instantiation-expression.expect.md | 46 +++++++++++++++++++ .../compiler/ts-instantiation-expression.tsx | 11 +++++ 3 files changed, 58 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.tsx diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 4d9ce6becc17a..d5c3ea6a492a9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -2528,6 +2528,7 @@ function lowerExpression( loc: expr.node.loc ?? GeneratedSource, }; } + case 'TSInstantiationExpression': case 'TSNonNullExpression': { let expr = exprPath as NodePath; return lowerExpression(builder, expr.get('expression')); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.expect.md new file mode 100644 index 0000000000000..8400a135b6fe4 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.expect.md @@ -0,0 +1,46 @@ + +## Input + +```javascript +import {identity, invoke} from 'shared-runtime'; + +function Test() { + const str = invoke(identity, 'test'); + return str; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Test, + params: [], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { identity, invoke } from "shared-runtime"; + +function Test() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = invoke(identity, "test"); + $[0] = t0; + } else { + t0 = $[0]; + } + const str = t0; + return str; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Test, + params: [], +}; + +``` + +### Eval output +(kind: ok) "test" \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.tsx new file mode 100644 index 0000000000000..373d005747644 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-expression.tsx @@ -0,0 +1,11 @@ +import {identity, invoke} from 'shared-runtime'; + +function Test() { + const str = invoke(identity, 'test'); + return str; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Test, + params: [], +}; From 442150e0e2783ce9ab407a113acd2656752323d2 Mon Sep 17 00:00:00 2001 From: michael faith Date: Mon, 3 Feb 2025 11:07:30 -0600 Subject: [PATCH 2/3] build(eslint-plugin-react-hooks): tsconfig and global types (#32283) ## Summary Contributing to https://github.com/facebook/react/pull/32240, this change adds the tsconfig, tsup config, and estree type declarations that will be needed for that plugin's typescript migration. --- .../src/types/estree.d.ts | 70 +++++++++++++++++++ .../src/types/global.d.ts | 4 ++ .../eslint-plugin-react-hooks/tsconfig.json | 15 ++++ .../eslint-plugin-react-hooks/tsup.config.ts | 9 +++ 4 files changed, 98 insertions(+) create mode 100644 packages/eslint-plugin-react-hooks/src/types/estree.d.ts create mode 100644 packages/eslint-plugin-react-hooks/src/types/global.d.ts create mode 100644 packages/eslint-plugin-react-hooks/tsconfig.json create mode 100644 packages/eslint-plugin-react-hooks/tsup.config.ts diff --git a/packages/eslint-plugin-react-hooks/src/types/estree.d.ts b/packages/eslint-plugin-react-hooks/src/types/estree.d.ts new file mode 100644 index 0000000000000..10337ef7d6bf0 --- /dev/null +++ b/packages/eslint-plugin-react-hooks/src/types/estree.d.ts @@ -0,0 +1,70 @@ +/** + * This file augments the `estree` types to include types that are not built-in to `estree` or `estree-jsx`. + * This is necessary because the `estree` types are used by ESLint, and ESLint does not natively support + * TypeScript or Flow types. Since we're not using a ton of them, we can just add them here, rather than + * installing typescript estree or flow estree types. + * + * This also adds support for the AST mutation that the Exhaustive deps rule does to add parent nodes. + */ +declare module 'estree' { + // The Exhaustive deps rule mutates the AST to add parent nodes for efficient traversal. + // We need to augment the `estree` types to support that. + interface BaseNode { + parent?: Node; + } + + // Adding types that aren't built-in to estree or estree-jsx. + // Namely, the specific TS and Flow types that we're using. + interface AsExpression extends BaseExpression { + type: 'AsExpression'; + expression: Expression | Identifier; + } + + interface OptionalCallExpression extends BaseCallExpression { + type: 'OptionalCallExpression'; + } + + interface OptionalMemberExpression extends MemberExpression { + type: 'OptionalMemberExpression'; + } + + interface TSAsExpression extends BaseExpression { + type: 'TSAsExpression'; + expression: Expression | Identifier; + } + + interface TSTypeQuery extends BaseNode { + type: 'TSTypeQuery'; + exprName: Identifier; + } + + interface TSTypeReference extends BaseNode { + type: 'TSTypeReference'; + typeName: Identifier; + } + + interface TypeCastExpression extends BaseExpression { + type: 'TypeCastExpression'; + expression: Expression | Identifier; + } + + // Extend the set of known Expression types + interface ExpressionMap { + AsExpression: AsExpression; + OptionalCallExpression: OptionalCallExpression; + OptionalMemberExpression: OptionalMemberExpression; + TSAsExpression: TSAsExpression; + TypeCastExpression: TypeCastExpression; + } + + // Extend the set of known Node types + interface NodeMap { + AsExpression: AsExpression; + OptionalCallExpression: OptionalCallExpression; + OptionalMemberExpression: OptionalMemberExpression; + TSAsExpression: TSAsExpression; + TSTypeQuery: TSTypeQuery; + TSTypeReference: TSTypeReference; + TypeCastExpression: TypeCastExpression; + } +} diff --git a/packages/eslint-plugin-react-hooks/src/types/global.d.ts b/packages/eslint-plugin-react-hooks/src/types/global.d.ts new file mode 100644 index 0000000000000..b334f17ee5381 --- /dev/null +++ b/packages/eslint-plugin-react-hooks/src/types/global.d.ts @@ -0,0 +1,4 @@ +// In order to support the __EXPERIMENTAL__ global in TypeScript, +// we need to declare it here. The value of this is set in both +// the jest setup and CI build +declare const __EXPERIMENTAL__: boolean; diff --git a/packages/eslint-plugin-react-hooks/tsconfig.json b/packages/eslint-plugin-react-hooks/tsconfig.json new file mode 100644 index 0000000000000..db8a4893649ea --- /dev/null +++ b/packages/eslint-plugin-react-hooks/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "@tsconfig/strictest/tsconfig.json", + "compilerOptions": { + "module": "ES2015", + "target": "ES2015", + "moduleResolution": "Bundler", + "lib": ["ES2020"], + "rootDir": ".", + "noEmit": true, + "sourceMap": false, + "types": ["estree-jsx", "node"] + }, + "exclude": ["node_modules"], + "include": ["src/**/*.ts"] +} diff --git a/packages/eslint-plugin-react-hooks/tsup.config.ts b/packages/eslint-plugin-react-hooks/tsup.config.ts new file mode 100644 index 0000000000000..e275d0495e26c --- /dev/null +++ b/packages/eslint-plugin-react-hooks/tsup.config.ts @@ -0,0 +1,9 @@ +import {defineConfig} from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/index.ts'], + format: ['cjs'], + outDir: 'build', +}); From 0a82580bfc80538c5ce914514dc86b17c8889954 Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 3 Feb 2025 12:57:51 -0500 Subject: [PATCH 3/3] [ci] Only notify discord on core team label (#32303) Rather than notify on every label event on a PR by a core team member, only do so for the specific core team label event. --- .github/workflows/compiler_discord_notify.yml | 2 +- .github/workflows/runtime_discord_notify.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compiler_discord_notify.yml b/.github/workflows/compiler_discord_notify.yml index b4694e12be94d..1ab9c1b1aff5b 100644 --- a/.github/workflows/compiler_discord_notify.yml +++ b/.github/workflows/compiler_discord_notify.yml @@ -14,7 +14,7 @@ jobs: actor: ${{ github.event.pull_request.user.login }} notify: - if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }} + if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' && github.event.label.name == 'React Core Team' }} needs: check_maintainer runs-on: ubuntu-latest steps: diff --git a/.github/workflows/runtime_discord_notify.yml b/.github/workflows/runtime_discord_notify.yml index a29735ac4ed8e..59a1078b499e8 100644 --- a/.github/workflows/runtime_discord_notify.yml +++ b/.github/workflows/runtime_discord_notify.yml @@ -14,7 +14,7 @@ jobs: actor: ${{ github.event.pull_request.user.login }} notify: - if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }} + if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' && github.event.label.name == 'React Core Team' }} needs: check_maintainer runs-on: ubuntu-latest steps: