From 9c3de25e1ce52066c0518b3ca0803b69e684edd6 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Sat, 1 Oct 2022 18:47:32 -0400 Subject: [PATCH] Flow: types first in reconciler (#25362) This contains one code change, renaming the local function `ChildReconciler` to `createChildReconciler` as it's called as a function, not a constructor and to free up the name for the return value. --- .../src/ReactChildFiber.new.js | 15 +++- .../src/ReactChildFiber.old.js | 15 +++- .../src/ReactFiberClassComponent.new.js | 2 +- .../src/ReactFiberClassComponent.old.js | 2 +- .../src/ReactFiberContext.new.js | 3 +- .../src/ReactFiberContext.old.js | 3 +- .../src/ReactFiberHotReloading.js | 6 +- .../src/ReactFiberReconciler.js | 78 ++++++++++--------- .../src/ReactFiberUnwindWork.new.js | 2 +- .../src/ReactFiberUnwindWork.old.js | 2 +- .../src/ReactFiberWorkLoop.new.js | 8 +- .../src/ReactFiberWorkLoop.old.js | 8 +- scripts/flow/config/flowconfig | 33 ++++++++ 13 files changed, 118 insertions(+), 59 deletions(-) diff --git a/packages/react-reconciler/src/ReactChildFiber.new.js b/packages/react-reconciler/src/ReactChildFiber.new.js index 2e1a232e028db..21821f91b9b63 100644 --- a/packages/react-reconciler/src/ReactChildFiber.new.js +++ b/packages/react-reconciler/src/ReactChildFiber.new.js @@ -264,11 +264,18 @@ function resolveLazy(lazyType) { return init(payload); } +type ChildReconciler = ( + returnFiber: Fiber, + currentFirstChild: Fiber | null, + newChild: any, + lanes: Lanes, +) => Fiber | null; + // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. -function ChildReconciler(shouldTrackSideEffects) { +function createChildReconciler(shouldTrackSideEffects): ChildReconciler { function deleteChild(returnFiber: Fiber, childToDelete: Fiber): void { if (!shouldTrackSideEffects) { // Noop. @@ -1352,8 +1359,10 @@ function ChildReconciler(shouldTrackSideEffects) { return reconcileChildFibers; } -export const reconcileChildFibers = ChildReconciler(true); -export const mountChildFibers = ChildReconciler(false); +export const reconcileChildFibers: ChildReconciler = createChildReconciler( + true, +); +export const mountChildFibers: ChildReconciler = createChildReconciler(false); export function cloneChildFibers( current: Fiber | null, diff --git a/packages/react-reconciler/src/ReactChildFiber.old.js b/packages/react-reconciler/src/ReactChildFiber.old.js index c6fdbcc728a29..264ab51db2191 100644 --- a/packages/react-reconciler/src/ReactChildFiber.old.js +++ b/packages/react-reconciler/src/ReactChildFiber.old.js @@ -264,11 +264,18 @@ function resolveLazy(lazyType) { return init(payload); } +type ChildReconciler = ( + returnFiber: Fiber, + currentFirstChild: Fiber | null, + newChild: any, + lanes: Lanes, +) => Fiber | null; + // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. -function ChildReconciler(shouldTrackSideEffects) { +function createChildReconciler(shouldTrackSideEffects): ChildReconciler { function deleteChild(returnFiber: Fiber, childToDelete: Fiber): void { if (!shouldTrackSideEffects) { // Noop. @@ -1352,8 +1359,10 @@ function ChildReconciler(shouldTrackSideEffects) { return reconcileChildFibers; } -export const reconcileChildFibers = ChildReconciler(true); -export const mountChildFibers = ChildReconciler(false); +export const reconcileChildFibers: ChildReconciler = createChildReconciler( + true, +); +export const mountChildFibers: ChildReconciler = createChildReconciler(false); export function cloneChildFibers( current: Fiber | null, diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.new.js b/packages/react-reconciler/src/ReactFiberClassComponent.new.js index 398ffc28f4d33..de7e7bbba77f5 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.new.js @@ -83,7 +83,7 @@ const fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. -export const emptyRefsObject = new React.Component().refs; +export const emptyRefsObject: $FlowFixMe = new React.Component().refs; let didWarnAboutStateAssignmentForComponent; let didWarnAboutUninitializedState; diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.old.js b/packages/react-reconciler/src/ReactFiberClassComponent.old.js index a7cd936b1fe6d..5625c682c68b1 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.old.js @@ -83,7 +83,7 @@ const fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. -export const emptyRefsObject = new React.Component().refs; +export const emptyRefsObject: $FlowFixMe = new React.Component().refs; let didWarnAboutStateAssignmentForComponent; let didWarnAboutUninitializedState; diff --git a/packages/react-reconciler/src/ReactFiberContext.new.js b/packages/react-reconciler/src/ReactFiberContext.new.js index 43d5e68abb05d..23be350d21688 100644 --- a/packages/react-reconciler/src/ReactFiberContext.new.js +++ b/packages/react-reconciler/src/ReactFiberContext.new.js @@ -24,7 +24,8 @@ if (__DEV__) { warnedAboutMissingGetChildContext = {}; } -export const emptyContextObject = {}; +// $FlowFixMe[incompatible-exact] +export const emptyContextObject: {} = {}; if (__DEV__) { Object.freeze(emptyContextObject); } diff --git a/packages/react-reconciler/src/ReactFiberContext.old.js b/packages/react-reconciler/src/ReactFiberContext.old.js index 82bf05e6687c0..d4ba6c7c9f1c3 100644 --- a/packages/react-reconciler/src/ReactFiberContext.old.js +++ b/packages/react-reconciler/src/ReactFiberContext.old.js @@ -24,7 +24,8 @@ if (__DEV__) { warnedAboutMissingGetChildContext = {}; } -export const emptyContextObject = {}; +// $FlowFixMe[incompatible-exact] +export const emptyContextObject: {} = {}; if (__DEV__) { Object.freeze(emptyContextObject); } diff --git a/packages/react-reconciler/src/ReactFiberHotReloading.js b/packages/react-reconciler/src/ReactFiberHotReloading.js index 385ee8bfcd8e2..569ba8228fafe 100644 --- a/packages/react-reconciler/src/ReactFiberHotReloading.js +++ b/packages/react-reconciler/src/ReactFiberHotReloading.js @@ -63,13 +63,13 @@ export type FindHostInstancesForRefresh = ( export const setRefreshHandler: ( handler: RefreshHandler | null, ) => void = enableNewReconciler ? setRefreshHandler_new : setRefreshHandler_old; -export const resolveFunctionForHotReloading = enableNewReconciler +export const resolveFunctionForHotReloading: typeof resolveFunctionForHotReloading_new = enableNewReconciler ? resolveFunctionForHotReloading_new : resolveFunctionForHotReloading_old; -export const resolveClassForHotReloading = enableNewReconciler +export const resolveClassForHotReloading: typeof resolveClassForHotReloading_new = enableNewReconciler ? resolveClassForHotReloading_new : resolveClassForHotReloading_old; -export const resolveForwardRefForHotReloading = enableNewReconciler +export const resolveForwardRefForHotReloading: typeof resolveForwardRefForHotReloading_new = enableNewReconciler ? resolveForwardRefForHotReloading_new : resolveForwardRefForHotReloading_old; export const isCompatibleFamilyForHotReloading: ( diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index d10dfb5cf3723..3df72c6a44cb1 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -90,107 +90,113 @@ import { getCurrentUpdatePriority as getCurrentUpdatePriority_new, } from './ReactFiberReconciler.new'; -export const createContainer = enableNewReconciler +export const createContainer: typeof createContainer_new = enableNewReconciler ? createContainer_new : createContainer_old; -export const createHydrationContainer = enableNewReconciler +export const createHydrationContainer: typeof createHydrationContainer_new = enableNewReconciler ? createHydrationContainer_new : createHydrationContainer_old; -export const updateContainer = enableNewReconciler +export const updateContainer: typeof updateContainer_new = enableNewReconciler ? updateContainer_new : updateContainer_old; -export const batchedUpdates = enableNewReconciler +export const batchedUpdates: typeof batchedUpdates_new = enableNewReconciler ? batchedUpdates_new : batchedUpdates_old; -export const deferredUpdates = enableNewReconciler +export const deferredUpdates: typeof deferredUpdates_new = enableNewReconciler ? deferredUpdates_new : deferredUpdates_old; -export const discreteUpdates = enableNewReconciler +export const discreteUpdates: typeof discreteUpdates_new = enableNewReconciler ? discreteUpdates_new : discreteUpdates_old; -export const flushControlled = enableNewReconciler +export const flushControlled: typeof flushControlled_new = enableNewReconciler ? flushControlled_new : flushControlled_old; -export const flushSync = enableNewReconciler ? flushSync_new : flushSync_old; -export const isAlreadyRendering = enableNewReconciler +export const flushSync: typeof flushSync_new = enableNewReconciler + ? flushSync_new + : flushSync_old; +export const isAlreadyRendering: typeof isAlreadyRendering_new = enableNewReconciler ? isAlreadyRendering_new : isAlreadyRendering_old; -export const flushPassiveEffects = enableNewReconciler +export const flushPassiveEffects: typeof flushPassiveEffects_new = enableNewReconciler ? flushPassiveEffects_new : flushPassiveEffects_old; -export const getPublicRootInstance = enableNewReconciler +export const getPublicRootInstance: typeof getPublicRootInstance_new = enableNewReconciler ? getPublicRootInstance_new : getPublicRootInstance_old; -export const attemptSynchronousHydration = enableNewReconciler +export const attemptSynchronousHydration: typeof attemptSynchronousHydration_new = enableNewReconciler ? attemptSynchronousHydration_new : attemptSynchronousHydration_old; -export const attemptDiscreteHydration = enableNewReconciler +export const attemptDiscreteHydration: typeof attemptDiscreteHydration_new = enableNewReconciler ? attemptDiscreteHydration_new : attemptDiscreteHydration_old; -export const attemptContinuousHydration = enableNewReconciler +export const attemptContinuousHydration: typeof attemptContinuousHydration_new = enableNewReconciler ? attemptContinuousHydration_new : attemptContinuousHydration_old; -export const attemptHydrationAtCurrentPriority = enableNewReconciler +export const attemptHydrationAtCurrentPriority: typeof attemptHydrationAtCurrentPriority_new = enableNewReconciler ? attemptHydrationAtCurrentPriority_new : attemptHydrationAtCurrentPriority_old; -export const getCurrentUpdatePriority = enableNewReconciler +export const getCurrentUpdatePriority: typeof getCurrentUpdatePriority_new = enableNewReconciler ? getCurrentUpdatePriority_new - : getCurrentUpdatePriority_old; -export const findHostInstance = enableNewReconciler + : /* $FlowFixMe[incompatible-type] opaque types EventPriority from new and old + * are incompatible. */ + getCurrentUpdatePriority_old; +export const findHostInstance: typeof findHostInstance_new = enableNewReconciler ? findHostInstance_new : findHostInstance_old; -export const findHostInstanceWithWarning = enableNewReconciler +export const findHostInstanceWithWarning: typeof findHostInstanceWithWarning_new = enableNewReconciler ? findHostInstanceWithWarning_new : findHostInstanceWithWarning_old; -export const findHostInstanceWithNoPortals = enableNewReconciler +export const findHostInstanceWithNoPortals: typeof findHostInstanceWithNoPortals_new = enableNewReconciler ? findHostInstanceWithNoPortals_new : findHostInstanceWithNoPortals_old; -export const shouldError = enableNewReconciler +export const shouldError: typeof shouldError_new = enableNewReconciler ? shouldError_new : shouldError_old; -export const shouldSuspend = enableNewReconciler +export const shouldSuspend: typeof shouldSuspend_new = enableNewReconciler ? shouldSuspend_new : shouldSuspend_old; -export const injectIntoDevTools = enableNewReconciler +export const injectIntoDevTools: typeof injectIntoDevTools_new = enableNewReconciler ? injectIntoDevTools_new : injectIntoDevTools_old; -export const createPortal = enableNewReconciler +export const createPortal: typeof createPortal_new = enableNewReconciler ? createPortal_new : createPortal_old; -export const createComponentSelector = enableNewReconciler +export const createComponentSelector: typeof createComponentSelector_new = enableNewReconciler ? createComponentSelector_new : createComponentSelector_old; -export const createHasPseudoClassSelector = enableNewReconciler +export const createHasPseudoClassSelector: typeof createHasPseudoClassSelector_new = enableNewReconciler ? createHasPseudoClassSelector_new : createHasPseudoClassSelector_old; -export const createRoleSelector = enableNewReconciler +export const createRoleSelector: typeof createRoleSelector_new = enableNewReconciler ? createRoleSelector_new : createRoleSelector_old; -export const createTextSelector = enableNewReconciler +export const createTextSelector: typeof createTextSelector_new = enableNewReconciler ? createTextSelector_new : createTextSelector_old; -export const createTestNameSelector = enableNewReconciler +export const createTestNameSelector: typeof createTestNameSelector_new = enableNewReconciler ? createTestNameSelector_new : createTestNameSelector_old; -export const getFindAllNodesFailureDescription = enableNewReconciler +export const getFindAllNodesFailureDescription: typeof getFindAllNodesFailureDescription_new = enableNewReconciler ? getFindAllNodesFailureDescription_new : getFindAllNodesFailureDescription_old; -export const findAllNodes = enableNewReconciler +export const findAllNodes: typeof findAllNodes_new = enableNewReconciler ? findAllNodes_new : findAllNodes_old; -export const findBoundingRects = enableNewReconciler +export const findBoundingRects: typeof findBoundingRects_new = enableNewReconciler ? findBoundingRects_new : findBoundingRects_old; -export const focusWithin = enableNewReconciler +export const focusWithin: typeof focusWithin_new = enableNewReconciler ? focusWithin_new : focusWithin_old; -export const observeVisibleRects = enableNewReconciler +export const observeVisibleRects: typeof observeVisibleRects_new = enableNewReconciler ? observeVisibleRects_new : observeVisibleRects_old; -export const registerMutableSourceForHydration = enableNewReconciler +export const registerMutableSourceForHydration: typeof registerMutableSourceForHydration_new = enableNewReconciler ? registerMutableSourceForHydration_new : registerMutableSourceForHydration_old; -export const runWithPriority = enableNewReconciler +/* $FlowFixMe[incompatible-type] opaque types EventPriority from new and old + * are incompatible. */ +export const runWithPriority: typeof runWithPriority_new = enableNewReconciler ? runWithPriority_new : runWithPriority_old; diff --git a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js index a5c408681dd04..66794fbccd4df 100644 --- a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js +++ b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js @@ -63,7 +63,7 @@ function unwindWork( current: Fiber | null, workInProgress: Fiber, renderLanes: Lanes, -) { +): Fiber | null { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only diff --git a/packages/react-reconciler/src/ReactFiberUnwindWork.old.js b/packages/react-reconciler/src/ReactFiberUnwindWork.old.js index 870983968cc6f..e30fa19532885 100644 --- a/packages/react-reconciler/src/ReactFiberUnwindWork.old.js +++ b/packages/react-reconciler/src/ReactFiberUnwindWork.old.js @@ -63,7 +63,7 @@ function unwindWork( current: Fiber | null, workInProgress: Fiber, renderLanes: Lanes, -) { +): Fiber | null { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index c72de5c18d239..e0add4c8db6fd 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -580,7 +580,7 @@ export function getWorkInProgressRootRenderLanes(): Lanes { return workInProgressRootRenderLanes; } -export function requestEventTime() { +export function requestEventTime(): number { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return now(); @@ -595,7 +595,7 @@ export function requestEventTime() { return currentEventTime; } -export function getCurrentTime() { +export function getCurrentTime(): number { return now(); } @@ -1567,7 +1567,7 @@ declare function flushSync(fn: () => R): R; // eslint-disable-next-line no-redeclare declare function flushSync(): void; // eslint-disable-next-line no-redeclare -export function flushSync(fn): void { +export function flushSync(fn: (() => R) | void): R | void { // In legacy mode, we flush pending passive effects at the beginning of the // next event, not at the end of the previous one. if ( @@ -1615,7 +1615,7 @@ export function isAlreadyRendering(): boolean { ); } -export function isInvalidExecutionContextForEventFunction() { +export function isInvalidExecutionContextForEventFunction(): boolean { // Used to throw if certain APIs are called from the wrong context. return (executionContext & RenderContext) !== NoContext; } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 45b8a60adac64..e5774487dc2cf 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -580,7 +580,7 @@ export function getWorkInProgressRootRenderLanes(): Lanes { return workInProgressRootRenderLanes; } -export function requestEventTime() { +export function requestEventTime(): number { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return now(); @@ -595,7 +595,7 @@ export function requestEventTime() { return currentEventTime; } -export function getCurrentTime() { +export function getCurrentTime(): number { return now(); } @@ -1567,7 +1567,7 @@ declare function flushSync(fn: () => R): R; // eslint-disable-next-line no-redeclare declare function flushSync(): void; // eslint-disable-next-line no-redeclare -export function flushSync(fn): void { +export function flushSync(fn: (() => R) | void): R | void { // In legacy mode, we flush pending passive effects at the beginning of the // next event, not at the end of the previous one. if ( @@ -1615,7 +1615,7 @@ export function isAlreadyRendering(): boolean { ); } -export function isInvalidExecutionContextForEventFunction() { +export function isInvalidExecutionContextForEventFunction(): boolean { // Used to throw if certain APIs are called from the wrong context. return (executionContext & RenderContext) !== NoContext; } diff --git a/scripts/flow/config/flowconfig b/scripts/flow/config/flowconfig index 0b94bb02fecba..d5330858f60c7 100644 --- a/scripts/flow/config/flowconfig +++ b/scripts/flow/config/flowconfig @@ -48,10 +48,43 @@ munge_underscores=false types_first=false well_formed_exports=true +; well_formed_exports.includes=/packages/dom-event-testing-library +; well_formed_exports.includes=/packages/eslint-plugin-react-hooks +; well_formed_exports.includes=/packages/jest-mock-scheduler +; well_formed_exports.includes=/packages/jest-react +; well_formed_exports.includes=/packages/react +; well_formed_exports.includes=/packages/react-art +; well_formed_exports.includes=/packages/react-cache +; well_formed_exports.includes=/packages/react-client +; well_formed_exports.includes=/packages/react-debug-tools +; well_formed_exports.includes=/packages/react-devtools +; well_formed_exports.includes=/packages/react-devtools-core +; well_formed_exports.includes=/packages/react-devtools-extensions +; well_formed_exports.includes=/packages/react-devtools-inline well_formed_exports.includes=/packages/react-devtools-shared well_formed_exports.includes=/packages/react-devtools-shell well_formed_exports.includes=/packages/react-devtools-timeline +; well_formed_exports.includes=/packages/react-dom +; well_formed_exports.includes=/packages/react-dom-bindings +; well_formed_exports.includes=/packages/react-fetch +; well_formed_exports.includes=/packages/react-fs +; well_formed_exports.includes=/packages/react-interactions +; well_formed_exports.includes=/packages/react-is +; well_formed_exports.includes=/packages/react-native-renderer +; well_formed_exports.includes=/packages/react-noop-renderer +; well_formed_exports.includes=/packages/react-pg +well_formed_exports.includes=/packages/react-reconciler +; well_formed_exports.includes=/packages/react-refresh +; well_formed_exports.includes=/packages/react-server +; well_formed_exports.includes=/packages/react-server-dom-relay +; well_formed_exports.includes=/packages/react-server-dom-webpack +; well_formed_exports.includes=/packages/react-server-native-relay +; well_formed_exports.includes=/packages/react-suspense-test-utils +; well_formed_exports.includes=/packages/react-test-renderer well_formed_exports.includes=/packages/scheduler +; well_formed_exports.includes=/packages/shared +; well_formed_exports.includes=/packages/use-subscription +; well_formed_exports.includes=/packages/use-sync-external-store # Substituted by createFlowConfig.js: %REACT_RENDERER_FLOW_OPTIONS%