Skip to content

Commit

Permalink
Flow: types first in reconciler
Browse files Browse the repository at this point in the history
  • Loading branch information
kassens committed Sep 30, 2022
1 parent c0ef211 commit 9291441
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 60 deletions.
15 changes: 12 additions & 3 deletions packages/react-reconciler/src/ReactChildFiber.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 12 additions & 3 deletions packages/react-reconciler/src/ReactChildFiber.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,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;
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberContext.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ if (__DEV__) {
warnedAboutMissingGetChildContext = {};
}

export const emptyContextObject = {};
// $FlowFixMe[incompatible-exact]
export const emptyContextObject: {} = {};
if (__DEV__) {
Object.freeze(emptyContextObject);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberContext.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ if (__DEV__) {
warnedAboutMissingGetChildContext = {};
}

export const emptyContextObject = {};
// $FlowFixMe[incompatible-exact]
export const emptyContextObject: {} = {};
if (__DEV__) {
Object.freeze(emptyContextObject);
}
Expand Down
6 changes: 3 additions & 3 deletions packages/react-reconciler/src/ReactFiberHotReloading.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: (
Expand Down
78 changes: 42 additions & 36 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberUnwindWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,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
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberUnwindWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,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
Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,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();
Expand All @@ -585,7 +585,7 @@ export function requestEventTime() {
return currentEventTime;
}

export function getCurrentTime() {
export function getCurrentTime(): number {
return now();
}

Expand Down Expand Up @@ -1557,7 +1557,7 @@ declare function flushSync<R>(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<R>(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 (
Expand Down Expand Up @@ -1605,7 +1605,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;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,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();
Expand All @@ -585,7 +585,7 @@ export function requestEventTime() {
return currentEventTime;
}

export function getCurrentTime() {
export function getCurrentTime(): number {
return now();
}

Expand Down Expand Up @@ -1557,7 +1557,7 @@ declare function flushSync<R>(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<R>(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 (
Expand Down Expand Up @@ -1605,7 +1605,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;
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/flow/config/flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ well_formed_exports.includes=<PROJECT_ROOT>/packages/react-is
; well_formed_exports.includes=<PROJECT_ROOT>/packages/react-native-renderer
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-noop-renderer
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-pg
; well_formed_exports.includes=<PROJECT_ROOT>/packages/react-reconciler
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-reconciler
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-refresh
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-server
well_formed_exports.includes=<PROJECT_ROOT>/packages/react-server-dom-relay
Expand Down

0 comments on commit 9291441

Please sign in to comment.