-
Notifications
You must be signed in to change notification settings - Fork 46.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add forked copies of reconciler modules
All changes in this commit were generated by the following commands. Copy each module that ends with `.old` to a new file that ends with `.new`: ```sh for f in packages/react-reconciler/src/*.old.js; do cp "$f" "$(echo "$f" | sed s/\.old/\.new/)"; done ``` Then transform the internal imports: ```sh grep -rl --include="*.new.js" '.old' packages/react-reconciler/src/| xargs sed -i '' "s/\.old\'/\.new\'/g" ```
- Loading branch information
Showing
30 changed files
with
22,052 additions
and
0 deletions.
There are no files selected for viewing
1,490 changes: 1,490 additions & 0 deletions
1,490
packages/react-reconciler/src/ReactChildFiber.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
3,494 changes: 3,494 additions & 0 deletions
3,494
packages/react-reconciler/src/ReactFiberBeginWork.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
1,182 changes: 1,182 additions & 0 deletions
1,182
packages/react-reconciler/src/ReactFiberClassComponent.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
1,837 changes: 1,837 additions & 0 deletions
1,837
packages/react-reconciler/src/ReactFiberCommitWork.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
1,314 changes: 1,314 additions & 0 deletions
1,314
packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,338 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
import type {Fiber} from './ReactInternalTypes'; | ||
import type {StackCursor} from './ReactFiberStack.new'; | ||
|
||
import {isFiberMounted} from './ReactFiberTreeReflection'; | ||
import {disableLegacyContext} from 'shared/ReactFeatureFlags'; | ||
import {ClassComponent, HostRoot} from './ReactWorkTags'; | ||
import getComponentName from 'shared/getComponentName'; | ||
import invariant from 'shared/invariant'; | ||
import checkPropTypes from 'shared/checkPropTypes'; | ||
|
||
import {createCursor, push, pop} from './ReactFiberStack.new'; | ||
|
||
let warnedAboutMissingGetChildContext; | ||
|
||
if (__DEV__) { | ||
warnedAboutMissingGetChildContext = {}; | ||
} | ||
|
||
export const emptyContextObject = {}; | ||
if (__DEV__) { | ||
Object.freeze(emptyContextObject); | ||
} | ||
|
||
// A cursor to the current merged context object on the stack. | ||
const contextStackCursor: StackCursor<Object> = createCursor( | ||
emptyContextObject, | ||
); | ||
// A cursor to a boolean indicating whether the context has changed. | ||
const didPerformWorkStackCursor: StackCursor<boolean> = createCursor(false); | ||
// Keep track of the previous context object that was on the stack. | ||
// We use this to get access to the parent context after we have already | ||
// pushed the next context provider, and now need to merge their contexts. | ||
let previousContext: Object = emptyContextObject; | ||
|
||
function getUnmaskedContext( | ||
workInProgress: Fiber, | ||
Component: Function, | ||
didPushOwnContextIfProvider: boolean, | ||
): Object { | ||
if (disableLegacyContext) { | ||
return emptyContextObject; | ||
} else { | ||
if (didPushOwnContextIfProvider && isContextProvider(Component)) { | ||
// If the fiber is a context provider itself, when we read its context | ||
// we may have already pushed its own child context on the stack. A context | ||
// provider should not "see" its own child context. Therefore we read the | ||
// previous (parent) context instead for a context provider. | ||
return previousContext; | ||
} | ||
return contextStackCursor.current; | ||
} | ||
} | ||
|
||
function cacheContext( | ||
workInProgress: Fiber, | ||
unmaskedContext: Object, | ||
maskedContext: Object, | ||
): void { | ||
if (disableLegacyContext) { | ||
return; | ||
} else { | ||
const instance = workInProgress.stateNode; | ||
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; | ||
instance.__reactInternalMemoizedMaskedChildContext = maskedContext; | ||
} | ||
} | ||
|
||
function getMaskedContext( | ||
workInProgress: Fiber, | ||
unmaskedContext: Object, | ||
): Object { | ||
if (disableLegacyContext) { | ||
return emptyContextObject; | ||
} else { | ||
const type = workInProgress.type; | ||
const contextTypes = type.contextTypes; | ||
if (!contextTypes) { | ||
return emptyContextObject; | ||
} | ||
|
||
// Avoid recreating masked context unless unmasked context has changed. | ||
// Failing to do this will result in unnecessary calls to componentWillReceiveProps. | ||
// This may trigger infinite loops if componentWillReceiveProps calls setState. | ||
const instance = workInProgress.stateNode; | ||
if ( | ||
instance && | ||
instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext | ||
) { | ||
return instance.__reactInternalMemoizedMaskedChildContext; | ||
} | ||
|
||
const context = {}; | ||
for (const key in contextTypes) { | ||
context[key] = unmaskedContext[key]; | ||
} | ||
|
||
if (__DEV__) { | ||
const name = getComponentName(type) || 'Unknown'; | ||
checkPropTypes(contextTypes, context, 'context', name); | ||
} | ||
|
||
// Cache unmasked context so we can avoid recreating masked context unless necessary. | ||
// Context is created before the class component is instantiated so check for instance. | ||
if (instance) { | ||
cacheContext(workInProgress, unmaskedContext, context); | ||
} | ||
|
||
return context; | ||
} | ||
} | ||
|
||
function hasContextChanged(): boolean { | ||
if (disableLegacyContext) { | ||
return false; | ||
} else { | ||
return didPerformWorkStackCursor.current; | ||
} | ||
} | ||
|
||
function isContextProvider(type: Function): boolean { | ||
if (disableLegacyContext) { | ||
return false; | ||
} else { | ||
const childContextTypes = type.childContextTypes; | ||
return childContextTypes !== null && childContextTypes !== undefined; | ||
} | ||
} | ||
|
||
function popContext(fiber: Fiber): void { | ||
if (disableLegacyContext) { | ||
return; | ||
} else { | ||
pop(didPerformWorkStackCursor, fiber); | ||
pop(contextStackCursor, fiber); | ||
} | ||
} | ||
|
||
function popTopLevelContextObject(fiber: Fiber): void { | ||
if (disableLegacyContext) { | ||
return; | ||
} else { | ||
pop(didPerformWorkStackCursor, fiber); | ||
pop(contextStackCursor, fiber); | ||
} | ||
} | ||
|
||
function pushTopLevelContextObject( | ||
fiber: Fiber, | ||
context: Object, | ||
didChange: boolean, | ||
): void { | ||
if (disableLegacyContext) { | ||
return; | ||
} else { | ||
invariant( | ||
contextStackCursor.current === emptyContextObject, | ||
'Unexpected context found on stack. ' + | ||
'This error is likely caused by a bug in React. Please file an issue.', | ||
); | ||
|
||
push(contextStackCursor, context, fiber); | ||
push(didPerformWorkStackCursor, didChange, fiber); | ||
} | ||
} | ||
|
||
function processChildContext( | ||
fiber: Fiber, | ||
type: any, | ||
parentContext: Object, | ||
): Object { | ||
if (disableLegacyContext) { | ||
return parentContext; | ||
} else { | ||
const instance = fiber.stateNode; | ||
const childContextTypes = type.childContextTypes; | ||
|
||
// TODO (bvaughn) Replace this behavior with an invariant() in the future. | ||
// It has only been added in Fiber to match the (unintentional) behavior in Stack. | ||
if (typeof instance.getChildContext !== 'function') { | ||
if (__DEV__) { | ||
const componentName = getComponentName(type) || 'Unknown'; | ||
|
||
if (!warnedAboutMissingGetChildContext[componentName]) { | ||
warnedAboutMissingGetChildContext[componentName] = true; | ||
console.error( | ||
'%s.childContextTypes is specified but there is no getChildContext() method ' + | ||
'on the instance. You can either define getChildContext() on %s or remove ' + | ||
'childContextTypes from it.', | ||
componentName, | ||
componentName, | ||
); | ||
} | ||
} | ||
return parentContext; | ||
} | ||
|
||
const childContext = instance.getChildContext(); | ||
for (const contextKey in childContext) { | ||
invariant( | ||
contextKey in childContextTypes, | ||
'%s.getChildContext(): key "%s" is not defined in childContextTypes.', | ||
getComponentName(type) || 'Unknown', | ||
contextKey, | ||
); | ||
} | ||
if (__DEV__) { | ||
const name = getComponentName(type) || 'Unknown'; | ||
checkPropTypes(childContextTypes, childContext, 'child context', name); | ||
} | ||
|
||
return {...parentContext, ...childContext}; | ||
} | ||
} | ||
|
||
function pushContextProvider(workInProgress: Fiber): boolean { | ||
if (disableLegacyContext) { | ||
return false; | ||
} else { | ||
const instance = workInProgress.stateNode; | ||
// We push the context as early as possible to ensure stack integrity. | ||
// If the instance does not exist yet, we will push null at first, | ||
// and replace it on the stack later when invalidating the context. | ||
const memoizedMergedChildContext = | ||
(instance && instance.__reactInternalMemoizedMergedChildContext) || | ||
emptyContextObject; | ||
|
||
// Remember the parent context so we can merge with it later. | ||
// Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. | ||
previousContext = contextStackCursor.current; | ||
push(contextStackCursor, memoizedMergedChildContext, workInProgress); | ||
push( | ||
didPerformWorkStackCursor, | ||
didPerformWorkStackCursor.current, | ||
workInProgress, | ||
); | ||
|
||
return true; | ||
} | ||
} | ||
|
||
function invalidateContextProvider( | ||
workInProgress: Fiber, | ||
type: any, | ||
didChange: boolean, | ||
): void { | ||
if (disableLegacyContext) { | ||
return; | ||
} else { | ||
const instance = workInProgress.stateNode; | ||
invariant( | ||
instance, | ||
'Expected to have an instance by this point. ' + | ||
'This error is likely caused by a bug in React. Please file an issue.', | ||
); | ||
|
||
if (didChange) { | ||
// Merge parent and own context. | ||
// Skip this if we're not updating due to sCU. | ||
// This avoids unnecessarily recomputing memoized values. | ||
const mergedContext = processChildContext( | ||
workInProgress, | ||
type, | ||
previousContext, | ||
); | ||
instance.__reactInternalMemoizedMergedChildContext = mergedContext; | ||
|
||
// Replace the old (or empty) context with the new one. | ||
// It is important to unwind the context in the reverse order. | ||
pop(didPerformWorkStackCursor, workInProgress); | ||
pop(contextStackCursor, workInProgress); | ||
// Now push the new context and mark that it has changed. | ||
push(contextStackCursor, mergedContext, workInProgress); | ||
push(didPerformWorkStackCursor, didChange, workInProgress); | ||
} else { | ||
pop(didPerformWorkStackCursor, workInProgress); | ||
push(didPerformWorkStackCursor, didChange, workInProgress); | ||
} | ||
} | ||
} | ||
|
||
function findCurrentUnmaskedContext(fiber: Fiber): Object { | ||
if (disableLegacyContext) { | ||
return emptyContextObject; | ||
} else { | ||
// Currently this is only used with renderSubtreeIntoContainer; not sure if it | ||
// makes sense elsewhere | ||
invariant( | ||
isFiberMounted(fiber) && fiber.tag === ClassComponent, | ||
'Expected subtree parent to be a mounted class component. ' + | ||
'This error is likely caused by a bug in React. Please file an issue.', | ||
); | ||
|
||
let node = fiber; | ||
do { | ||
switch (node.tag) { | ||
case HostRoot: | ||
return node.stateNode.context; | ||
case ClassComponent: { | ||
const Component = node.type; | ||
if (isContextProvider(Component)) { | ||
return node.stateNode.__reactInternalMemoizedMergedChildContext; | ||
} | ||
break; | ||
} | ||
} | ||
node = node.return; | ||
} while (node !== null); | ||
invariant( | ||
false, | ||
'Found unexpected detached subtree parent. ' + | ||
'This error is likely caused by a bug in React. Please file an issue.', | ||
); | ||
} | ||
} | ||
|
||
export { | ||
getUnmaskedContext, | ||
cacheContext, | ||
getMaskedContext, | ||
hasContextChanged, | ||
popContext, | ||
popTopLevelContextObject, | ||
pushTopLevelContextObject, | ||
processChildContext, | ||
isContextProvider, | ||
pushContextProvider, | ||
invalidateContextProvider, | ||
findCurrentUnmaskedContext, | ||
}; |
Oops, something went wrong.