@samitouri / QOS-React / commits / 5662595677

Refactor stack handling (no functional changes) (#13165)

* Refactor ReactDebugCurrentFiber to use named exports This makes the difference between it and ReactFiberCurrentFrame a bit clearer. ReactDebugCurrentFiber is Fiber's own implementation. ReactFiberCurrentFrame is the thing that holds a reference to the current implementation and delegates to it. * Unify ReactFiberComponentTreeHook and ReactDebugCurrentFiber Conceptually they're very related. ReactFiberComponentTreeHook contains implementation details of reading Fiber's stack (both in DEV and PROD). ReactDebugCurrentFiber contained a reference to the current fiber, and used the above utility. It was confusing when to use which one. Colocating them makes it clearer what you could do with each method. In the future, the plan is to stop using these methods explicitly in most places, and instead delegate to a warning system that includes stacks automatically. This change makes future refactorings simpler by colocating related logic. * Rename methods to better reflect their meanings Clarify which are DEV or PROD-only. Clarify which can return null. I believe the "work in progress only" was a mistake. I introduced it because I wasn't sure what guarantees we have around .return. But we know for sure that following a .return chain gives us an accurate stack even if we get into WIP trees because we don't have reparenting. So it's fine to relax that naming. * Rename ReactDebugCurrentFiber -> ReactCurrentFiber It's not completely DEV-only anymore. Individual methods already specify whether they work in DEV or PROD in their names.

Dan Abramov committed Jul 7, 2018 at 01:09 UTC 566259567773a0af56e6c19da615e6802d73f834
17 files changed +201 -225
packages/react-dom/src/client/ReactDOMFiberComponent.js
+23 -16
@@ -8,7 +8,10 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
11 +import {
12 + getCurrentFiberOwnerNameInDevOrNull,
13 + getCurrentFiberStackInDevOrNull,
14 +} from 'react-reconciler/src/ReactCurrentFiber';
15 import {registrationNameModules} from 'events/EventPluginRegistry';
16 import warning from 'shared/warning';
17
@@ -45,10 +48,6 @@ import {validateProperties as validateARIAProperties} from '../shared/ReactDOMIn
48 import {validateProperties as validateInputProperties} from '../shared/ReactDOMNullInputValuePropHook';
49 import {validateProperties as validateUnknownProperties} from '../shared/ReactDOMUnknownPropertyHook';
50
48 -const {
49 - getCurrentFiberOwnerName,
50 - getCurrentFiberStackAddendum,
51 -} = ReactDebugCurrentFiber;
51 let didWarnInvalidHydration = false;
52 let didWarnShadyDOM = false;
53
@@ -62,7 +61,7 @@ const HTML = '__html';
61
62 const {html: HTML_NAMESPACE} = Namespaces;
63
65 -let getStack = () => '';
64 +let getStackInDevOrNull = () => '';
65
66 let warnedUnknownTags;
67 let suppressHydrationWarning;
@@ -77,7 +76,7 @@ let normalizeMarkupForTextOrAttribute;
76 let normalizeHTML;
77
78 if (__DEV__) {
80 - getStack = getCurrentFiberStackAddendum;
79 + getStackInDevOrNull = getCurrentFiberStackInDevOrNull;
80
81 warnedUnknownTags = {
82 // Chrome is the only major browser not shipping <time>. But as of July
@@ -181,7 +180,7 @@ if (__DEV__) {
180 registrationName,
181 registrationName,
182 registrationName,
184 - getCurrentFiberStackAddendum(),
183 + getCurrentFiberStackInDevOrNull(),
184 );
185 } else {
186 warning(
@@ -189,7 +188,7 @@ if (__DEV__) {
188 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s',
189 registrationName,
190 typeof listener,
192 - getCurrentFiberStackAddendum(),
191 + getCurrentFiberStackInDevOrNull(),
192 );
193 }
194 };
@@ -267,7 +266,11 @@ function setInitialDOMProperties(
266 }
267 }
268 // Relies on `updateStylesByID` not mutating `styleUpdates`.
270 - CSSPropertyOperations.setValueForStyles(domElement, nextProp, getStack);
269 + CSSPropertyOperations.setValueForStyles(
270 + domElement,
271 + nextProp,
272 + getStackInDevOrNull,
273 + );
274 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
275 const nextHtml = nextProp ? nextProp[HTML] : undefined;
276 if (nextHtml != null) {
@@ -323,7 +326,11 @@ function updateDOMProperties(
326 const propKey = updatePayload[i];
327 const propValue = updatePayload[i + 1];
328 if (propKey === STYLE) {
326 - CSSPropertyOperations.setValueForStyles(domElement, propValue, getStack);
329 + CSSPropertyOperations.setValueForStyles(
330 + domElement,
331 + propValue,
332 + getStackInDevOrNull,
333 + );
334 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
335 setInnerHTML(domElement, propValue);
336 } else if (propKey === CHILDREN) {
@@ -442,7 +449,7 @@ export function setInitialProperties(
449 false,
450 '%s is using shady DOM. Using shady DOM with React can ' +
451 'cause things to break subtly.',
445 - getCurrentFiberOwnerName() || 'A component',
452 + getCurrentFiberOwnerNameInDevOrNull() || 'A component',
453 );
454 didWarnShadyDOM = true;
455 }
@@ -516,7 +523,7 @@ export function setInitialProperties(
523 props = rawProps;
524 }
525
519 - assertValidProps(tag, props, getStack);
526 + assertValidProps(tag, props, getStackInDevOrNull);
527
528 setInitialDOMProperties(
529 tag,
@@ -604,7 +611,7 @@ export function diffProperties(
611 break;
612 }
613
607 - assertValidProps(tag, nextProps, getStack);
614 + assertValidProps(tag, nextProps, getStackInDevOrNull);
615
616 let propKey;
617 let styleName;
@@ -834,7 +841,7 @@ export function diffHydratedProperties(
841 false,
842 '%s is using shady DOM. Using shady DOM with React can ' +
843 'cause things to break subtly.',
837 - getCurrentFiberOwnerName() || 'A component',
844 + getCurrentFiberOwnerNameInDevOrNull() || 'A component',
845 );
846 didWarnShadyDOM = true;
847 }
@@ -895,7 +902,7 @@ export function diffHydratedProperties(
902 break;
903 }
904
898 - assertValidProps(tag, rawProps, getStack);
905 + assertValidProps(tag, rawProps, getStackInDevOrNull);
906
907 if (__DEV__) {
908 extraAttributeNames = new Set();
packages/react-dom/src/client/ReactDOMFiberInput.js
+9 -10
@@ -8,7 +8,10 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
11 +import {
12 + getCurrentFiberOwnerNameInDevOrNull,
13 + getCurrentFiberStackInDevOrNull,
14 +} from 'react-reconciler/src/ReactCurrentFiber';
15 import invariant from 'shared/invariant';
16 import warning from 'shared/warning';
17
@@ -25,10 +28,6 @@ type InputWithWrapperState = HTMLInputElement & {
28 },
29 };
30
28 -const {
29 - getCurrentFiberOwnerName,
30 - getCurrentFiberStackAddendum,
31 -} = ReactDebugCurrentFiber;
31 let didWarnValueDefaultValue = false;
32 let didWarnCheckedDefaultChecked = false;
33 let didWarnControlledToUncontrolled = false;
@@ -75,7 +74,7 @@ export function initWrapperState(element: Element, props: Object) {
74 ReactControlledValuePropTypes.checkPropTypes(
75 'input',
76 props,
78 - getCurrentFiberStackAddendum,
77 + getCurrentFiberStackInDevOrNull,
78 );
79
80 if (
@@ -91,7 +90,7 @@ export function initWrapperState(element: Element, props: Object) {
90 'both). Decide between using a controlled or uncontrolled input ' +
91 'element and remove one of these props. More info: ' +
92 'https://fb.me/react-controlled-components',
94 - getCurrentFiberOwnerName() || 'A component',
93 + getCurrentFiberOwnerNameInDevOrNull() || 'A component',
94 props.type,
95 );
96 didWarnCheckedDefaultChecked = true;
@@ -109,7 +108,7 @@ export function initWrapperState(element: Element, props: Object) {
108 'both). Decide between using a controlled or uncontrolled input ' +
109 'element and remove one of these props. More info: ' +
110 'https://fb.me/react-controlled-components',
112 - getCurrentFiberOwnerName() || 'A component',
111 + getCurrentFiberOwnerNameInDevOrNull() || 'A component',
112 props.type,
113 );
114 didWarnValueDefaultValue = true;
@@ -154,7 +153,7 @@ export function updateWrapper(element: Element, props: Object) {
153 'Decide between using a controlled or uncontrolled input ' +
154 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s',
155 props.type,
157 - getCurrentFiberStackAddendum(),
156 + getCurrentFiberStackInDevOrNull(),
157 );
158 didWarnUncontrolledToControlled = true;
159 }
@@ -170,7 +169,7 @@ export function updateWrapper(element: Element, props: Object) {
169 'Decide between using a controlled or uncontrolled input ' +
170 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s',
171 props.type,
173 - getCurrentFiberStackAddendum(),
172 + getCurrentFiberStackInDevOrNull(),
173 );
174 didWarnControlledToUncontrolled = true;
175 }
packages/react-dom/src/client/ReactDOMFiberSelect.js
+6 -8
@@ -8,16 +8,14 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
11 +import {
12 + getCurrentFiberOwnerNameInDevOrNull,
13 + getCurrentFiberStackInDevOrNull,
14 +} from 'react-reconciler/src/ReactCurrentFiber';
15 import warning from 'shared/warning';
16
17 import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
18
16 -const {
17 - getCurrentFiberOwnerName,
18 - getCurrentFiberStackAddendum,
19 -} = ReactDebugCurrentFiber;
20 -
19 let didWarnValueDefaultValue;
20
21 if (__DEV__) {
@@ -32,7 +30,7 @@ type SelectWithWrapperState = HTMLSelectElement & {
30 };
31
32 function getDeclarationErrorAddendum() {
35 - const ownerName = getCurrentFiberOwnerName();
33 + const ownerName = getCurrentFiberOwnerNameInDevOrNull();
34 if (ownerName) {
35 return '\n\nCheck the render method of `' + ownerName + '`.';
36 }
@@ -48,7 +46,7 @@ function checkSelectPropTypes(props) {
46 ReactControlledValuePropTypes.checkPropTypes(
47 'select',
48 props,
51 - getCurrentFiberStackAddendum,
49 + getCurrentFiberStackInDevOrNull,
50 );
51
52 for (let i = 0; i < valuePropNames.length; i++) {
packages/react-dom/src/client/ReactDOMFiberTextarea.js
+2 -3
@@ -10,11 +10,10 @@
10 import invariant from 'shared/invariant';
11 import warning from 'shared/warning';
12 // TODO: direct imports like some-package/src/* are bad. Fix me.
13 -import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
13 +import {getCurrentFiberStackInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
14
15 import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
16
17 -const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
17 let didWarnValDefaultVal = false;
18
19 type TextAreaWithWrapperState = HTMLTextAreaElement & {
@@ -68,7 +67,7 @@ export function initWrapperState(element: Element, props: Object) {
67 ReactControlledValuePropTypes.checkPropTypes(
68 'textarea',
69 props,
71 - getCurrentFiberStackAddendum,
70 + getCurrentFiberStackInDevOrNull,
71 );
72 if (
73 props.value !== undefined &&
packages/react-dom/src/client/validateDOMNesting.js
+2 -3
@@ -7,9 +7,8 @@
7
8 import warning from 'shared/warning';
9 // TODO: direct imports like some-package/src/* are bad. Fix me.
10 -import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
10 +import {getCurrentFiberStackInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
11
12 -const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
12 let validateDOMNesting = () => {};
13
14 if (__DEV__) {
@@ -427,7 +426,7 @@ if (__DEV__) {
426 }
427
428 const ancestorTag = invalidParentOrAncestor.tag;
430 - const addendum = getCurrentFiberStackAddendum();
429 + const addendum = getCurrentFiberStackInDevOrNull();
430
431 const warnKey =
432 !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
packages/react-native-renderer/src/ReactNativeRenderer.js
+3 -3
@@ -13,14 +13,14 @@ import type {ReactNodeList} from 'shared/ReactTypes';
13 import './ReactNativeInjection';
14
15 import * as ReactNativeFiberRenderer from 'react-reconciler/inline.native';
16 +// TODO: direct imports like some-package/src/* are bad. Fix me.
17 +import {getStackByFiberInDevAndProd} from 'react-reconciler/src/ReactCurrentFiber';
18 import * as ReactPortal from 'shared/ReactPortal';
19 import * as ReactGenericBatching from 'events/ReactGenericBatching';
20 import ReactVersion from 'shared/ReactVersion';
21 // Module provided by RN:
22 import UIManager from 'UIManager';
23
22 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
23 -
24 import NativeMethodsMixin from './NativeMethodsMixin';
25 import ReactNativeComponent from './ReactNativeComponent';
26 import * as ReactNativeComponentTree from './ReactNativeComponentTree';
@@ -80,7 +80,7 @@ function computeComponentStackForErrorReporting(reactTag: number): string {
80 if (!fiber) {
81 return '';
82 }
83 - return getStackAddendumByWorkInProgressFiber(fiber);
83 + return getStackByFiberInDevAndProd(fiber);
84 }
85
86 const roots = new Map();
packages/react-reconciler/src/ReactCapturedValue.js
+2 -2
@@ -9,7 +9,7 @@
9
10 import type {Fiber} from './ReactFiber';
11
12 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
12 +import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
13
14 export type CapturedValue<T> = {
15 value: T,
@@ -36,6 +36,6 @@ export function createCapturedValue<T>(
36 return {
37 value,
38 source,
39 - stack: getStackAddendumByWorkInProgressFiber(source),
39 + stack: getStackByFiberInDevAndProd(source),
40 };
41 }
packages/react-reconciler/src/ReactChildFiber.js
+12 -12
@@ -27,7 +27,6 @@ import {
27 HostPortal,
28 Fragment,
29 } from 'shared/ReactTypeOfWork';
30 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
30 import invariant from 'shared/invariant';
31 import warning from 'shared/warning';
32
@@ -39,11 +38,12 @@ import {
38 createFiberFromPortal,
39 } from './ReactFiber';
40 import {emptyRefsObject} from './ReactFiberClassComponent';
42 -import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
41 +import {
42 + getCurrentFiberStackInDevOrNull,
43 + getStackByFiberInDevAndProd,
44 +} from './ReactCurrentFiber';
45 import {StrictMode} from './ReactTypeOfMode';
46
45 -const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
46 -
47 let didWarnAboutMaps;
48 let didWarnAboutStringRefInStrictMode;
49 let ownerHasKeyUseWarning;
@@ -80,7 +80,7 @@ if (__DEV__) {
80 'Each child in an array or iterator should have a unique ' +
81 '"key" prop. See https://fb.me/react-warning-keys for ' +
82 'more information.' +
83 - (getCurrentFiberStackAddendum() || '');
83 + (getCurrentFiberStackInDevOrNull() || '');
84 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
85 return;
86 }
@@ -91,7 +91,7 @@ if (__DEV__) {
91 'Each child in an array or iterator should have a unique ' +
92 '"key" prop. See https://fb.me/react-warning-keys for ' +
93 'more information.%s',
94 - getCurrentFiberStackAddendum(),
94 + getCurrentFiberStackInDevOrNull(),
95 );
96 };
97 }
@@ -122,7 +122,7 @@ function coerceRef(
122 '\n\nLearn more about using refs safely here:' +
123 '\nhttps://fb.me/react-strict-mode-string-ref',
124 mixedRef,
125 - getStackAddendumByWorkInProgressFiber(returnFiber),
125 + getStackByFiberInDevAndProd(returnFiber),
126 );
127 didWarnAboutStringRefInStrictMode[componentName] = true;
128 }
@@ -197,7 +197,7 @@ function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
197 addendum =
198 ' If you meant to render a collection of children, use an array ' +
199 'instead.' +
200 - (getCurrentFiberStackAddendum() || '');
200 + (getCurrentFiberStackInDevOrNull() || '');
201 }
202 invariant(
203 false,
@@ -215,7 +215,7 @@ function warnOnFunctionType() {
215 'Functions are not valid as a React child. This may happen if ' +
216 'you return a Component instead of <Component /> from render. ' +
217 'Or maybe you meant to call this function rather than return it.' +
218 - (getCurrentFiberStackAddendum() || '');
218 + (getCurrentFiberStackInDevOrNull() || '');
219
220 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
221 return;
@@ -227,7 +227,7 @@ function warnOnFunctionType() {
227 'Functions are not valid as a React child. This may happen if ' +
228 'you return a Component instead of <Component /> from render. ' +
229 'Or maybe you meant to call this function rather than return it.%s',
230 - getCurrentFiberStackAddendum() || '',
230 + getCurrentFiberStackInDevOrNull() || '',
231 );
232 }
233
@@ -719,7 +719,7 @@ function ChildReconciler(shouldTrackSideEffects) {
719 'duplicated and/or omitted — the behavior is unsupported and ' +
720 'could change in a future version.%s',
721 key,
722 - getCurrentFiberStackAddendum(),
722 + getCurrentFiberStackInDevOrNull(),
723 );
724 break;
725 default:
@@ -912,7 +912,7 @@ function ChildReconciler(shouldTrackSideEffects) {
912 'Using Maps as children is unsupported and will likely yield ' +
913 'unexpected results. Convert it to a sequence/iterable of keyed ' +
914 'ReactElements instead.%s',
915 - getCurrentFiberStackAddendum(),
915 + getCurrentFiberStackInDevOrNull(),
916 );
917 didWarnAboutMaps = true;
918 }
packages/react-reconciler/src/ReactCurrentFiber.js new
+101
@@ -0,0 +1,101 @@
1 +/**
2 + * Copyright (c) 2013-present, Facebook, Inc.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState';
11 +import {
12 + IndeterminateComponent,
13 + FunctionalComponent,
14 + ClassComponent,
15 + HostComponent,
16 +} from 'shared/ReactTypeOfWork';
17 +import describeComponentFrame from 'shared/describeComponentFrame';
18 +import getComponentName from 'shared/getComponentName';
19 +
20 +import type {Fiber} from './ReactFiber';
21 +
22 +type LifeCyclePhase = 'render' | 'getChildContext';
23 +
24 +function describeFiber(fiber: Fiber): string {
25 + switch (fiber.tag) {
26 + case IndeterminateComponent:
27 + case FunctionalComponent:
28 + case ClassComponent:
29 + case HostComponent:
30 + const owner = fiber._debugOwner;
31 + const source = fiber._debugSource;
32 + const name = getComponentName(fiber);
33 + let ownerName = null;
34 + if (owner) {
35 + ownerName = getComponentName(owner);
36 + }
37 + return describeComponentFrame(name, source, ownerName);
38 + default:
39 + return '';
40 + }
41 +}
42 +
43 +export function getStackByFiberInDevAndProd(workInProgress: Fiber): string {
44 + let info = '';
45 + let node = workInProgress;
46 + do {
47 + info += describeFiber(node);
48 + node = node.return;
49 + } while (node);
50 + return info;
51 +}
52 +
53 +export let current: Fiber | null = null;
54 +export let phase: LifeCyclePhase | null = null;
55 +
56 +export function getCurrentFiberOwnerNameInDevOrNull(): string | null {
57 + if (__DEV__) {
58 + if (current === null) {
59 + return null;
60 + }
61 + const owner = current._debugOwner;
62 + if (owner !== null && typeof owner !== 'undefined') {
63 + return getComponentName(owner);
64 + }
65 + }
66 + return null;
67 +}
68 +
69 +export function getCurrentFiberStackInDevOrNull(): string | null {
70 + if (__DEV__) {
71 + if (current === null) {
72 + return null;
73 + }
74 + // Safe because if current fiber exists, we are reconciling,
75 + // and it is guaranteed to be the work-in-progress version.
76 + return getStackByFiberInDevAndProd(current);
77 + }
78 + return null;
79 +}
80 +
81 +export function resetCurrentFiber() {
82 + if (__DEV__) {
83 + ReactDebugCurrentFrame.getCurrentStack = null;
84 + current = null;
85 + phase = null;
86 + }
87 +}
88 +
89 +export function setCurrentFiber(fiber: Fiber) {
90 + if (__DEV__) {
91 + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDevOrNull;
92 + current = fiber;
93 + phase = null;
94 + }
95 +}
96 +
97 +export function setCurrentPhase(lifeCyclePhase: LifeCyclePhase | null) {
98 + if (__DEV__) {
99 + phase = lifeCyclePhase;
100 + }
101 +}
packages/react-reconciler/src/ReactDebugCurrentFiber.js deleted
-71
@@ -1,71 +0,0 @@
1 -/**
2 - * Copyright (c) 2013-present, Facebook, Inc.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState';
11 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
12 -import getComponentName from 'shared/getComponentName';
13 -
14 -import type {Fiber} from './ReactFiber';
15 -
16 -type LifeCyclePhase = 'render' | 'getChildContext';
17 -
18 -function getCurrentFiberOwnerName(): string | null {
19 - if (__DEV__) {
20 - const fiber = ReactDebugCurrentFiber.current;
21 - if (fiber === null) {
22 - return null;
23 - }
24 - const owner = fiber._debugOwner;
25 - if (owner !== null && typeof owner !== 'undefined') {
26 - return getComponentName(owner);
27 - }
28 - }
29 - return null;
30 -}
31 -
32 -function getCurrentFiberStackAddendum(): string | null {
33 - if (__DEV__) {
34 - const fiber = ReactDebugCurrentFiber.current;
35 - if (fiber === null) {
36 - return null;
37 - }
38 - // Safe because if current fiber exists, we are reconciling,
39 - // and it is guaranteed to be the work-in-progress version.
40 - return getStackAddendumByWorkInProgressFiber(fiber);
41 - }
42 - return null;
43 -}
44 -
45 -function resetCurrentFiber() {
46 - ReactDebugCurrentFrame.getCurrentStack = null;
47 - ReactDebugCurrentFiber.current = null;
48 - ReactDebugCurrentFiber.phase = null;
49 -}
50 -
51 -function setCurrentFiber(fiber: Fiber) {
52 - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum;
53 - ReactDebugCurrentFiber.current = fiber;
54 - ReactDebugCurrentFiber.phase = null;
55 -}
56 -
57 -function setCurrentPhase(phase: LifeCyclePhase | null) {
58 - ReactDebugCurrentFiber.phase = phase;
59 -}
60 -
61 -const ReactDebugCurrentFiber = {
62 - current: (null: Fiber | null),
63 - phase: (null: LifeCyclePhase | null),
64 - resetCurrentFiber,
65 - setCurrentFiber,
66 - setCurrentPhase,
67 - getCurrentFiberOwnerName,
68 - getCurrentFiberStackAddendum,
69 -};
70 -
71 -export default ReactDebugCurrentFiber;
packages/react-reconciler/src/ReactFiberBeginWork.js
+12 -14
@@ -50,7 +50,7 @@ import invariant from 'shared/invariant';
50 import getComponentName from 'shared/getComponentName';
51 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
52 import warning from 'shared/warning';
53 -import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
53 +import * as ReactCurrentFiber from './ReactCurrentFiber';
54 import {cancelWorkTimer} from './ReactDebugFiberPerf';
55
56 import {applyDerivedStateFromProps} from './ReactFiberClassComponent';
@@ -98,8 +98,6 @@ import {
98 } from './ReactFiberClassComponent';
99 import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';
100
101 -const {getCurrentFiberStackAddendum} = ReactDebugCurrentFiber;
102 -
101 let didWarnAboutBadClass;
102 let didWarnAboutGetDerivedStateOnFunctionalComponent;
103 let didWarnAboutStatelessRefs;
@@ -170,9 +168,9 @@ function updateForwardRef(current, workInProgress) {
168 let nextChildren;
169 if (__DEV__) {
170 ReactCurrentOwner.current = workInProgress;
173 - ReactDebugCurrentFiber.setCurrentPhase('render');
171 + ReactCurrentFiber.setCurrentPhase('render');
172 nextChildren = render(nextProps, ref);
175 - ReactDebugCurrentFiber.setCurrentPhase(null);
173 + ReactCurrentFiber.setCurrentPhase(null);
174 } else {
175 nextChildren = render(nextProps, ref);
176 }
@@ -258,9 +256,9 @@ function updateFunctionalComponent(current, workInProgress) {
256
257 if (__DEV__) {
258 ReactCurrentOwner.current = workInProgress;
261 - ReactDebugCurrentFiber.setCurrentPhase('render');
259 + ReactCurrentFiber.setCurrentPhase('render');
260 nextChildren = fn(nextProps, context);
263 - ReactDebugCurrentFiber.setCurrentPhase(null);
261 + ReactCurrentFiber.setCurrentPhase(null);
262 } else {
263 nextChildren = fn(nextProps, context);
264 }
@@ -359,7 +357,7 @@ function finishClassComponent(
357 }
358 } else {
359 if (__DEV__) {
362 - ReactDebugCurrentFiber.setCurrentPhase('render');
360 + ReactCurrentFiber.setCurrentPhase('render');
361 nextChildren = instance.render();
362 if (
363 debugRenderPhaseSideEffects ||
@@ -368,7 +366,7 @@ function finishClassComponent(
366 ) {
367 instance.render();
368 }
371 - ReactDebugCurrentFiber.setCurrentPhase(null);
369 + ReactCurrentFiber.setCurrentPhase(null);
370 } else {
371 nextChildren = instance.render();
372 }
@@ -660,7 +658,7 @@ function mountIndeterminateComponent(
658 }
659 if (workInProgress.ref !== null) {
660 let info = '';
663 - const ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
661 + const ownerName = ReactCurrentFiber.getCurrentFiberOwnerNameInDevOrNull();
662 if (ownerName) {
663 info += '\n\nCheck the render method of `' + ownerName + '`.';
664 }
@@ -677,7 +675,7 @@ function mountIndeterminateComponent(
675 'Stateless function components cannot be given refs. ' +
676 'Attempts to access this ref will fail.%s%s',
677 info,
680 - ReactDebugCurrentFiber.getCurrentFiberStackAddendum(),
678 + ReactCurrentFiber.getCurrentFiberStackInDevOrNull(),
679 );
680 }
681 }
@@ -935,7 +933,7 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) {
933 newProps,
934 'prop',
935 'Context.Provider',
938 - getCurrentFiberStackAddendum,
936 + ReactCurrentFiber.getCurrentFiberStackInDevOrNull,
937 );
938 }
939 }
@@ -1069,9 +1067,9 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) {
1067 let newChildren;
1068 if (__DEV__) {
1069 ReactCurrentOwner.current = workInProgress;
1072 - ReactDebugCurrentFiber.setCurrentPhase('render');
1070 + ReactCurrentFiber.setCurrentPhase('render');
1071 newChildren = render(newValue);
1074 - ReactDebugCurrentFiber.setCurrentPhase(null);
1072 + ReactCurrentFiber.setCurrentPhase(null);
1073 } else {
1074 newChildren = render(newValue);
1075 }
packages/react-reconciler/src/ReactFiberCommitWork.js
+6 -6
@@ -20,7 +20,6 @@ import type {ExpirationTime} from './ReactFiberExpirationTime';
20 import type {CapturedValue, CapturedError} from './ReactCapturedValue';
21
22 import {enableProfilerTimer, enableSuspense} from 'shared/ReactFeatureFlags';
23 -import {getCommitTime} from './ReactProfilerTimer';
23 import {
24 ClassComponent,
25 HostRoot,
@@ -38,16 +37,17 @@ import {
37 Snapshot,
38 Update,
39 } from 'shared/ReactTypeOfSideEffect';
41 -import {commitUpdateQueue} from './ReactUpdateQueue';
40 +import getComponentName from 'shared/getComponentName';
41 import invariant from 'shared/invariant';
42 import warning from 'shared/warning';
43
44 import {Sync} from './ReactFiberExpirationTime';
45 import {onCommitUnmount} from './ReactFiberDevToolsHook';
46 import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
48 -import getComponentName from 'shared/getComponentName';
49 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
47 +import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
48 import {logCapturedError} from './ReactFiberErrorLogger';
49 +import {getCommitTime} from './ReactProfilerTimer';
50 +import {commitUpdateQueue} from './ReactUpdateQueue';
51 import {
52 getPublicInstance,
53 supportsMutation,
@@ -89,7 +89,7 @@ export function logError(boundary: Fiber, errorInfo: CapturedValue<mixed>) {
89 const source = errorInfo.source;
90 let stack = errorInfo.stack;
91 if (stack === null && source !== null) {
92 - stack = getStackAddendumByWorkInProgressFiber(source);
92 + stack = getStackByFiberInDevAndProd(source);
93 }
94
95 const capturedError: CapturedError = {
@@ -373,7 +373,7 @@ function commitAttachRef(finishedWork: Fiber) {
373 'Unexpected ref object provided for %s. ' +
374 'Use either a ref-setter function or React.createRef().%s',
375 getComponentName(finishedWork),
376 - getStackAddendumByWorkInProgressFiber(finishedWork),
376 + getStackByFiberInDevAndProd(finishedWork),
377 );
378 }
379 }
packages/react-reconciler/src/ReactFiberContext.js
+5 -5
@@ -17,7 +17,7 @@ import invariant from 'shared/invariant';
17 import warning from 'shared/warning';
18 import checkPropTypes from 'prop-types/checkPropTypes';
19
20 -import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
20 +import * as ReactCurrentFiber from './ReactCurrentFiber';
21 import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
22 import {createCursor, push, pop} from './ReactFiberStack';
23
@@ -96,7 +96,7 @@ function getMaskedContext(
96 context,
97 'context',
98 name,
99 - ReactDebugCurrentFiber.getCurrentFiberStackAddendum,
99 + ReactCurrentFiber.getCurrentFiberStackInDevOrNull,
100 );
101 }
102
@@ -177,13 +177,13 @@ function processChildContext(fiber: Fiber, parentContext: Object): Object {
177
178 let childContext;
179 if (__DEV__) {
180 - ReactDebugCurrentFiber.setCurrentPhase('getChildContext');
180 + ReactCurrentFiber.setCurrentPhase('getChildContext');
181 }
182 startPhaseTimer(fiber, 'getChildContext');
183 childContext = instance.getChildContext();
184 stopPhaseTimer();
185 if (__DEV__) {
186 - ReactDebugCurrentFiber.setCurrentPhase(null);
186 + ReactCurrentFiber.setCurrentPhase(null);
187 }
188 for (let contextKey in childContext) {
189 invariant(
@@ -205,7 +205,7 @@ function processChildContext(fiber: Fiber, parentContext: Object): Object {
205 // context from the parent component instance. The stack will be missing
206 // because it's outside of the reconciliation, and so the pointer has not
207 // been set. This is rare and doesn't matter. We'll also remove that API.
208 - ReactDebugCurrentFiber.getCurrentFiberStackAddendum,
208 + ReactCurrentFiber.getCurrentFiberStackInDevOrNull,
209 );
210 }
211
packages/react-reconciler/src/ReactFiberReconciler.js
+4 -4
@@ -55,7 +55,7 @@ import {
55 } from './ReactFiberScheduler';
56 import {createUpdate, enqueueUpdate} from './ReactUpdateQueue';
57 import ReactFiberInstrumentation from './ReactFiberInstrumentation';
58 -import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
58 +import * as ReactCurrentFiber from './ReactCurrentFiber';
59
60 type OpaqueRoot = FiberRoot;
61
@@ -104,8 +104,8 @@ function scheduleRootUpdate(
104 ) {
105 if (__DEV__) {
106 if (
107 - ReactDebugCurrentFiber.phase === 'render' &&
108 - ReactDebugCurrentFiber.current !== null &&
107 + ReactCurrentFiber.phase === 'render' &&
108 + ReactCurrentFiber.current !== null &&
109 !didWarnAboutNestedUpdates
110 ) {
111 didWarnAboutNestedUpdates = true;
@@ -115,7 +115,7 @@ function scheduleRootUpdate(
115 'triggering nested component updates from render is not allowed. ' +
116 'If necessary, trigger nested updates in componentDidUpdate.\n\n' +
117 'Check the render method of %s.',
118 - getComponentName(ReactDebugCurrentFiber.current) || 'Unknown',
118 + getComponentName(ReactCurrentFiber.current) || 'Unknown',
119 );
120 }
121 }
packages/react-reconciler/src/ReactFiberScheduler.js
+10 -11
@@ -12,7 +12,6 @@ import type {FiberRoot, Batch} from './ReactFiberRoot';
12 import type {ExpirationTime} from './ReactFiberExpirationTime';
13
14 import ReactErrorUtils from 'shared/ReactErrorUtils';
15 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
15 import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState';
16 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
17 import {
@@ -56,7 +55,7 @@ import {
55 } from './ReactFiberHostConfig';
56
57 import ReactFiberInstrumentation from './ReactFiberInstrumentation';
59 -import ReactDebugCurrentFiber from './ReactDebugCurrentFiber';
58 +import * as ReactCurrentFiber from './ReactCurrentFiber';
59 import {
60 now,
61 scheduleDeferredCallback,
@@ -185,13 +184,13 @@ if (__DEV__) {
184 'is a no-op, but it indicates a memory leak in your application. To ' +
185 'fix, cancel all subscriptions and asynchronous tasks in the ' +
186 'componentWillUnmount method.%s',
188 - getStackAddendumByWorkInProgressFiber(fiber),
187 + ReactCurrentFiber.getStackByFiberInDevAndProd(fiber),
188 );
189 didWarnStateUpdateForUnmountedComponent[componentName] = true;
190 };
191
192 warnAboutInvalidUpdates = function(instance: React$Component<any>) {
194 - switch (ReactDebugCurrentFiber.phase) {
193 + switch (ReactCurrentFiber.phase) {
194 case 'getChildContext':
195 if (didWarnSetStateChildContext) {
196 return;
@@ -363,7 +362,7 @@ function resetStack() {
362 function commitAllHostEffects() {
363 while (nextEffect !== null) {
364 if (__DEV__) {
366 - ReactDebugCurrentFiber.setCurrentFiber(nextEffect);
365 + ReactCurrentFiber.setCurrentFiber(nextEffect);
366 }
367 recordEffect();
368
@@ -422,7 +421,7 @@ function commitAllHostEffects() {
421 }
422
423 if (__DEV__) {
425 - ReactDebugCurrentFiber.resetCurrentFiber();
424 + ReactCurrentFiber.resetCurrentFiber();
425 }
426 }
427
@@ -778,7 +777,7 @@ function completeUnitOfWork(workInProgress: Fiber): Fiber | null {
777 // progress.
778 const current = workInProgress.alternate;
779 if (__DEV__) {
781 - ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
780 + ReactCurrentFiber.setCurrentFiber(workInProgress);
781 }
782
783 const returnFiber = workInProgress.return;
@@ -794,7 +793,7 @@ function completeUnitOfWork(workInProgress: Fiber): Fiber | null {
793 stopWorkTimer(workInProgress);
794 resetExpirationTime(workInProgress, nextRenderExpirationTime);
795 if (__DEV__) {
797 - ReactDebugCurrentFiber.resetCurrentFiber();
796 + ReactCurrentFiber.resetCurrentFiber();
797 }
798
799 if (next !== null) {
@@ -873,7 +872,7 @@ function completeUnitOfWork(workInProgress: Fiber): Fiber | null {
872 }
873
874 if (__DEV__) {
876 - ReactDebugCurrentFiber.resetCurrentFiber();
875 + ReactCurrentFiber.resetCurrentFiber();
876 }
877
878 if (next !== null) {
@@ -929,7 +928,7 @@ function performUnitOfWork(workInProgress: Fiber): Fiber | null {
928 // See if beginning this work spawns more work.
929 startWorkTimer(workInProgress);
930 if (__DEV__) {
932 - ReactDebugCurrentFiber.setCurrentFiber(workInProgress);
931 + ReactCurrentFiber.setCurrentFiber(workInProgress);
932 }
933
934 if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
@@ -957,7 +956,7 @@ function performUnitOfWork(workInProgress: Fiber): Fiber | null {
956 }
957
958 if (__DEV__) {
960 - ReactDebugCurrentFiber.resetCurrentFiber();
959 + ReactCurrentFiber.resetCurrentFiber();
960 if (isReplayingFailedUnitOfWork) {
961 // Currently replaying a failed unit of work. This should be unreachable,
962 // because the render phase is meant to be idempotent, and it should
packages/react-reconciler/src/ReactStrictModeWarnings.js
+4 -3
@@ -9,8 +9,9 @@
9
10 import type {Fiber} from './ReactFiber';
11
12 +import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
13 +
14 import getComponentName from 'shared/getComponentName';
13 -import {getStackAddendumByWorkInProgressFiber} from 'shared/ReactFiberComponentTreeHook';
15 import {StrictMode} from './ReactTypeOfMode';
16 import lowPriorityWarning from 'shared/lowPriorityWarning';
17 import warning from 'shared/warning';
@@ -94,7 +95,7 @@ if (__DEV__) {
95 });
96
97 if (lifecyclesWarningMesages.length > 0) {
97 - const strictRootComponentStack = getStackAddendumByWorkInProgressFiber(
98 + const strictRootComponentStack = getStackByFiberInDevAndProd(
99 strictRoot,
100 );
101
@@ -341,7 +342,7 @@ if (__DEV__) {
342 });
343
344 const sortedNames = setToSortedString(uniqueNames);
344 - const strictRootComponentStack = getStackAddendumByWorkInProgressFiber(
345 + const strictRootComponentStack = getStackByFiberInDevAndProd(
346 strictRoot,
347 );
348
packages/shared/ReactFiberComponentTreeHook.js deleted
-54
@@ -1,54 +0,0 @@
1 -/**
2 - * Copyright (c) 2016-present, Facebook, Inc.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import type {Fiber} from 'react-reconciler/src/ReactFiber';
11 -
12 -import {
13 - IndeterminateComponent,
14 - FunctionalComponent,
15 - ClassComponent,
16 - HostComponent,
17 -} from './ReactTypeOfWork';
18 -import describeComponentFrame from './describeComponentFrame';
19 -import getComponentName from './getComponentName';
20 -
21 -function describeFiber(fiber: Fiber): string {
22 - switch (fiber.tag) {
23 - case IndeterminateComponent:
24 - case FunctionalComponent:
25 - case ClassComponent:
26 - case HostComponent:
27 - const owner = fiber._debugOwner;
28 - const source = fiber._debugSource;
29 - const name = getComponentName(fiber);
30 - let ownerName = null;
31 - if (owner) {
32 - ownerName = getComponentName(owner);
33 - }
34 - return describeComponentFrame(name, source, ownerName);
35 - default:
36 - return '';
37 - }
38 -}
39 -
40 -// This function can only be called with a work-in-progress fiber and
41 -// only during begin or complete phase. Do not call it under any other
42 -// circumstances.
43 -export function getStackAddendumByWorkInProgressFiber(
44 - workInProgress: Fiber,
45 -): string {
46 - let info = '';
47 - let node = workInProgress;
48 - do {
49 - info += describeFiber(node);
50 - // Otherwise this return pointer might point to the wrong tree:
51 - node = node.return;
52 - } while (node);
53 - return info;
54 -}