@samitouri / QOS-React / commits / 0e23042e4b

refactor of ReactComponentTreeHook to isolate dev methods

Dominic Gannaway committed Mar 2, 2017 at 16:15 UTC 0e23042e4bba436dceb8ec8ae42856429d2ea69e
5 files changed +389 -382
src/isomorphic/classic/element/ReactDebugCurrentFrame.js
+4 -9
@@ -18,12 +18,7 @@ import type { DebugID } from 'ReactInstanceType';
18 const ReactDebugCurrentFrame = {};
19
20 if (__DEV__) {
21 - var {
22 - getStackAddendumByID,
23 - getStackAddendumByWorkInProgressFiber,
24 - getCurrentStackAddendum,
25 - } = require('ReactComponentTreeHook');
26 -
21 + var ReactComponentTreeHook = require('ReactComponentTreeHook');
22 // Component that is being worked on
23 ReactDebugCurrentFrame.current = (null : Fiber | DebugID | null);
24
@@ -38,16 +33,16 @@ if (__DEV__) {
33 if (typeof current === 'number') {
34 // DebugID from Stack.
35 const debugID = current;
41 - stack = getStackAddendumByID(debugID);
36 + stack = (ReactComponentTreeHook: any).getStackAddendumByID(debugID);
37 } else if (typeof current.tag === 'number') {
38 // This is a Fiber.
39 // The stack will only be correct if this is a work in progress
40 // version and we're calling it during reconciliation.
41 const workInProgress = current;
47 - stack = getStackAddendumByWorkInProgressFiber(workInProgress);
42 + stack = ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress);
43 }
44 } else if (element !== null) {
50 - stack = getCurrentStackAddendum(element);
45 + stack = (ReactComponentTreeHook: any).getCurrentStackAddendum(element);
46 }
47 return stack;
48 };
src/isomorphic/hooks/ReactComponentTreeHook.js
+372 -360
@@ -12,7 +12,11 @@
12
13 'use strict';
14
15 -var ReactCurrentOwner = require('ReactCurrentOwner');
15 +import type { ReactElement, Source } from 'ReactElementType';
16 +import type { DebugID } from 'ReactInstanceType';
17 +import type { Fiber } from 'ReactFiber';
18 +
19 +var getComponentName = require('getComponentName');
20 var ReactTypeOfWork = require('ReactTypeOfWork');
21 var {
22 IndeterminateComponent,
@@ -21,144 +25,6 @@ var {
25 HostComponent,
26 } = ReactTypeOfWork;
27
24 -var getComponentName = require('getComponentName');
25 -var invariant = require('fbjs/lib/invariant');
26 -var warning = require('fbjs/lib/warning');
27 -
28 -import type { ReactElement, Source } from 'ReactElementType';
29 -import type { DebugID } from 'ReactInstanceType';
30 -import type { Fiber } from 'ReactFiber';
31 -
32 -function isNative(fn) {
33 - // Based on isNative() from Lodash
34 - var funcToString = Function.prototype.toString;
35 - var hasOwnProperty = Object.prototype.hasOwnProperty;
36 - var reIsNative = RegExp('^' + funcToString
37 - // Take an example native function source for comparison
38 - .call(hasOwnProperty)
39 - // Strip regex characters so we can use it for regex
40 - .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
41 - // Remove hasOwnProperty from the template to make it generic
42 - .replace(
43 - /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
44 - '$1.*?'
45 - ) + '$'
46 - );
47 - try {
48 - var source = funcToString.call(fn);
49 - return reIsNative.test(source);
50 - } catch (err) {
51 - return false;
52 - }
53 -}
54 -
55 -var canUseCollections = (
56 - // Array.from
57 - typeof Array.from === 'function' &&
58 - // Map
59 - typeof Map === 'function' &&
60 - isNative(Map) &&
61 - // Map.prototype.keys
62 - Map.prototype != null &&
63 - typeof Map.prototype.keys === 'function' &&
64 - isNative(Map.prototype.keys) &&
65 - // Set
66 - typeof Set === 'function' &&
67 - isNative(Set) &&
68 - // Set.prototype.keys
69 - Set.prototype != null &&
70 - typeof Set.prototype.keys === 'function' &&
71 - isNative(Set.prototype.keys)
72 -);
73 -
74 -var setItem;
75 -var getItem;
76 -var removeItem;
77 -var getItemIDs;
78 -var addRoot;
79 -var removeRoot;
80 -var getRootIDs;
81 -
82 -if (canUseCollections) {
83 - var itemMap = new Map();
84 - var rootIDSet = new Set();
85 -
86 - setItem = function(id, item) {
87 - itemMap.set(id, item);
88 - };
89 - getItem = function(id) {
90 - return itemMap.get(id);
91 - };
92 - removeItem = function(id) {
93 - itemMap.delete(id);
94 - };
95 - getItemIDs = function() {
96 - return Array.from(itemMap.keys());
97 - };
98 -
99 - addRoot = function(id) {
100 - rootIDSet.add(id);
101 - };
102 - removeRoot = function(id) {
103 - rootIDSet.delete(id);
104 - };
105 - getRootIDs = function() {
106 - return Array.from(rootIDSet.keys());
107 - };
108 -
109 -} else {
110 - var itemByKey = {};
111 - var rootByKey = {};
112 -
113 - // Use non-numeric keys to prevent V8 performance issues:
114 - // https://github.com/facebook/react/pull/7232
115 - var getKeyFromID = function(id: DebugID): string {
116 - return '.' + id;
117 - };
118 - var getIDFromKey = function(key: string): DebugID {
119 - return parseInt(key.substr(1), 10);
120 - };
121 -
122 - setItem = function(id, item) {
123 - var key = getKeyFromID(id);
124 - itemByKey[key] = item;
125 - };
126 - getItem = function(id) {
127 - var key = getKeyFromID(id);
128 - return itemByKey[key];
129 - };
130 - removeItem = function(id) {
131 - var key = getKeyFromID(id);
132 - delete itemByKey[key];
133 - };
134 - getItemIDs = function() {
135 - return Object.keys(itemByKey).map(getIDFromKey);
136 - };
137 -
138 - addRoot = function(id) {
139 - var key = getKeyFromID(id);
140 - rootByKey[key] = true;
141 - };
142 - removeRoot = function(id) {
143 - var key = getKeyFromID(id);
144 - delete rootByKey[key];
145 - };
146 - getRootIDs = function() {
147 - return Object.keys(rootByKey).map(getIDFromKey);
148 - };
149 -}
150 -
151 -var unmountedIDs: Array<DebugID> = [];
152 -
153 -function purgeDeep(id) {
154 - var item = getItem(id);
155 - if (item) {
156 - var {childIDs} = item;
157 - removeItem(id);
158 - childIDs.forEach(purgeDeep);
159 - }
160 -}
161 -
28 function describeComponentFrame(name, source, ownerName) {
29 return '\n in ' + (name || 'Unknown') + (
30 source ?
@@ -170,35 +36,6 @@ function describeComponentFrame(name, source, ownerName) {
36 );
37 }
38
173 -function getDisplayName(element: ?ReactElement): string {
174 - if (element == null) {
175 - return '#empty';
176 - } else if (typeof element === 'string' || typeof element === 'number') {
177 - return '#text';
178 - } else if (typeof element.type === 'string') {
179 - return element.type;
180 - } else {
181 - return element.type.displayName || element.type.name || 'Unknown';
182 - }
183 -}
184 -
185 -function describeID(id: DebugID): string {
186 - var name = ReactComponentTreeHook.getDisplayName(id);
187 - var element = ReactComponentTreeHook.getElement(id);
188 - var ownerID = ReactComponentTreeHook.getOwnerID(id);
189 - var ownerName;
190 - if (ownerID) {
191 - ownerName = ReactComponentTreeHook.getDisplayName(ownerID);
192 - }
193 - warning(
194 - element,
195 - 'ReactComponentTreeHook: Missing React element for debugID %s when ' +
196 - 'building stack',
197 - id
198 - );
199 - return describeComponentFrame(name, element && element._source, ownerName);
200 -}
201 -
39 function describeFiber(fiber : Fiber) : string {
40 switch (fiber.tag) {
41 case IndeterminateComponent:
@@ -219,230 +56,405 @@ function describeFiber(fiber : Fiber) : string {
56 }
57
58 var ReactComponentTreeHook = {
222 - onSetChildren(id: DebugID, nextChildIDs: Array<DebugID>): void {
223 - var item = getItem(id);
224 - invariant(item, 'Item must have been set');
225 - item.childIDs = nextChildIDs;
226 -
227 - for (var i = 0; i < nextChildIDs.length; i++) {
228 - var nextChildID = nextChildIDs[i];
229 - var nextChild = getItem(nextChildID);
230 - invariant(
231 - nextChild,
232 - 'Expected hook events to fire for the child ' +
233 - 'before its parent includes it in onSetChildren().'
234 - );
235 - invariant(
236 - nextChild.childIDs != null ||
237 - typeof nextChild.element !== 'object' ||
238 - nextChild.element == null,
239 - 'Expected onSetChildren() to fire for a container child ' +
240 - 'before its parent includes it in onSetChildren().'
241 - );
242 - invariant(
243 - nextChild.isMounted,
244 - 'Expected onMountComponent() to fire for the child ' +
245 - 'before its parent includes it in onSetChildren().'
246 - );
247 - if (nextChild.parentID == null) {
248 - nextChild.parentID = id;
249 - // TODO: This shouldn't be necessary but mounting a new root during in
250 - // componentWillMount currently causes not-yet-mounted components to
251 - // be purged from our tree data so their parent id is missing.
252 - }
253 - invariant(
254 - nextChild.parentID === id,
255 - 'Expected onBeforeMountComponent() parent and onSetChildren() to ' +
256 - 'be consistent (%s has parents %s and %s).',
257 - nextChildID,
258 - nextChild.parentID,
259 - id
260 - );
261 - }
59 + // This function can only be called with a work-in-progress fiber and
60 + // only during begin or complete phase. Do not call it under any other
61 + // circumstances.
62 + getStackAddendumByWorkInProgressFiber(workInProgress : Fiber) : string {
63 + var info = '';
64 + var node = workInProgress;
65 + do {
66 + info += describeFiber(node);
67 + // Otherwise this return pointer might point to the wrong tree:
68 + node = node.return;
69 + } while (node);
70 + return info;
71 },
72 +};
73
264 - onBeforeMountComponent(id: DebugID, element: ReactElement, parentID: DebugID): void {
265 - var item = {
266 - element,
267 - parentID,
268 - text: null,
269 - childIDs: [],
270 - isMounted: false,
271 - updateCount: 0,
74 +if (__DEV__) {
75 + var ReactCurrentOwner = require('ReactCurrentOwner');
76 + var invariant = require('fbjs/lib/invariant');
77 + var warning = require('fbjs/lib/warning');
78 +
79 + var isNative = function(fn) {
80 + // Based on isNative() from Lodash
81 + var funcToString = Function.prototype.toString;
82 + var hasOwnProperty = Object.prototype.hasOwnProperty;
83 + var reIsNative = RegExp('^' + funcToString
84 + // Take an example native function source for comparison
85 + .call(hasOwnProperty)
86 + // Strip regex characters so we can use it for regex
87 + .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
88 + // Remove hasOwnProperty from the template to make it generic
89 + .replace(
90 + /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
91 + '$1.*?'
92 + ) + '$'
93 + );
94 + try {
95 + var source = funcToString.call(fn);
96 + return reIsNative.test(source);
97 + } catch (err) {
98 + return false;
99 + }
100 + };
101 +
102 + var canUseCollections = (
103 + // Array.from
104 + typeof Array.from === 'function' &&
105 + // Map
106 + typeof Map === 'function' &&
107 + isNative(Map) &&
108 + // Map.prototype.keys
109 + Map.prototype != null &&
110 + typeof Map.prototype.keys === 'function' &&
111 + isNative(Map.prototype.keys) &&
112 + // Set
113 + typeof Set === 'function' &&
114 + isNative(Set) &&
115 + // Set.prototype.keys
116 + Set.prototype != null &&
117 + typeof Set.prototype.keys === 'function' &&
118 + isNative(Set.prototype.keys)
119 + );
120 +
121 + var setItem;
122 + var getItem;
123 + var removeItem;
124 + var getItemIDs;
125 + var addRoot;
126 + var removeRoot;
127 + var getRootIDs;
128 +
129 + if (canUseCollections) {
130 + var itemMap = new Map();
131 + var rootIDSet = new Set();
132 +
133 + setItem = function(id, item) {
134 + itemMap.set(id, item);
135 + };
136 + getItem = function(id) {
137 + return itemMap.get(id);
138 + };
139 + removeItem = function(id) {
140 + itemMap.delete(id);
141 + };
142 + getItemIDs = function() {
143 + return Array.from(itemMap.keys());
144 };
273 - setItem(id, item);
274 - },
145
276 - onBeforeUpdateComponent(id: DebugID, element: ReactElement): void {
277 - var item = getItem(id);
278 - if (!item || !item.isMounted) {
279 - // We may end up here as a result of setState() in componentWillUnmount().
280 - // In this case, ignore the element.
281 - return;
282 - }
283 - item.element = element;
284 - },
146 + addRoot = function(id) {
147 + rootIDSet.add(id);
148 + };
149 + removeRoot = function(id) {
150 + rootIDSet.delete(id);
151 + };
152 + getRootIDs = function() {
153 + return Array.from(rootIDSet.keys());
154 + };
155
286 - onMountComponent(id: DebugID): void {
287 - var item = getItem(id);
288 - invariant(item, 'Item must have been set');
289 - item.isMounted = true;
290 - var isRoot = item.parentID === 0;
291 - if (isRoot) {
292 - addRoot(id);
293 - }
294 - },
156 + } else {
157 + var itemByKey = {};
158 + var rootByKey = {};
159
296 - onUpdateComponent(id: DebugID): void {
297 - var item = getItem(id);
298 - if (!item || !item.isMounted) {
299 - // We may end up here as a result of setState() in componentWillUnmount().
300 - // In this case, ignore the element.
301 - return;
302 - }
303 - item.updateCount++;
304 - },
160 + // Use non-numeric keys to prevent V8 performance issues:
161 + // https://github.com/facebook/react/pull/7232
162 + var getKeyFromID = function(id: DebugID): string {
163 + return '.' + id;
164 + };
165 + var getIDFromKey = function(key: string): DebugID {
166 + return parseInt(key.substr(1), 10);
167 + };
168
306 - onUnmountComponent(id: DebugID): void {
169 + setItem = function(id, item) {
170 + var key = getKeyFromID(id);
171 + itemByKey[key] = item;
172 + };
173 + getItem = function(id) {
174 + var key = getKeyFromID(id);
175 + return itemByKey[key];
176 + };
177 + removeItem = function(id) {
178 + var key = getKeyFromID(id);
179 + delete itemByKey[key];
180 + };
181 + getItemIDs = function() {
182 + return Object.keys(itemByKey).map(getIDFromKey);
183 + };
184 +
185 + addRoot = function(id) {
186 + var key = getKeyFromID(id);
187 + rootByKey[key] = true;
188 + };
189 + removeRoot = function(id) {
190 + var key = getKeyFromID(id);
191 + delete rootByKey[key];
192 + };
193 + getRootIDs = function() {
194 + return Object.keys(rootByKey).map(getIDFromKey);
195 + };
196 + }
197 +
198 + var unmountedIDs: Array<DebugID> = [];
199 +
200 + var purgeDeep = function(id) {
201 var item = getItem(id);
202 if (item) {
309 - // We need to check if it exists.
310 - // `item` might not exist if it is inside an error boundary, and a sibling
311 - // error boundary child threw while mounting. Then this instance never
312 - // got a chance to mount, but it still gets an unmounting event during
313 - // the error boundary cleanup.
314 - item.isMounted = false;
315 - var isRoot = item.parentID === 0;
316 - if (isRoot) {
317 - removeRoot(id);
318 - }
203 + var {childIDs} = item;
204 + removeItem(id);
205 + childIDs.forEach(purgeDeep);
206 }
320 - unmountedIDs.push(id);
321 - },
207 + };
208
323 - purgeUnmountedComponents(): void {
324 - if (ReactComponentTreeHook._preventPurging) {
325 - // Should only be used for testing.
326 - return;
209 + var getDisplayName = function(element: ?ReactElement): string {
210 + if (element == null) {
211 + return '#empty';
212 + } else if (typeof element === 'string' || typeof element === 'number') {
213 + return '#text';
214 + } else if (typeof element.type === 'string') {
215 + return element.type;
216 + } else {
217 + return element.type.displayName || element.type.name || 'Unknown';
218 }
219 + };
220
329 - for (var i = 0; i < unmountedIDs.length; i++) {
330 - var id = unmountedIDs[i];
331 - purgeDeep(id);
221 + var describeID = function(id: DebugID): string {
222 + var name = getDisplayName((id: any));
223 + var element = getElement(id);
224 + var ownerID: any = getOwnerID(id);
225 + var ownerName;
226 + if (ownerID) {
227 + ownerName = getDisplayName(ownerID);
228 }
333 - unmountedIDs.length = 0;
334 - },
335 -
336 - isMounted(id: DebugID): boolean {
337 - var item = getItem(id);
338 - return item ? item.isMounted : false;
339 - },
229 + warning(
230 + element,
231 + 'ReactComponentTreeHook: Missing React element for debugID %s when ' +
232 + 'building stack',
233 + id
234 + );
235 + return describeComponentFrame(name, element && element._source, ownerName);
236 + };
237
341 - getCurrentStackAddendum(topElement: ?ReactElement): string {
342 - var info = '';
343 - if (topElement) {
344 - var name = getDisplayName(topElement);
345 - var owner = topElement._owner;
346 - info += describeComponentFrame(
347 - name,
348 - topElement._source,
349 - owner && getComponentName(owner)
350 - );
238 + var getOwnerID = function(id: DebugID): ?DebugID {
239 + var element = getElement(id);
240 + if (!element || !element._owner) {
241 + return null;
242 }
243 + return element._owner._debugID;
244 + };
245
353 - var currentOwner = ReactCurrentOwner.current;
354 - if (currentOwner) {
355 - if (typeof currentOwner.tag === 'number') {
356 - const workInProgress = ((currentOwner : any) : Fiber);
357 - // Safe because if current owner exists, we are reconciling,
358 - // and it is guaranteed to be the work-in-progress version.
359 - info += ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress);
360 - } else if (typeof currentOwner._debugID === 'number') {
361 - info += ReactComponentTreeHook.getStackAddendumByID(currentOwner._debugID);
362 - }
363 - }
364 - return info;
365 - },
246 + var getElement = function(id: DebugID): ?ReactElement {
247 + var item = getItem(id);
248 + return item ? item.element : null;
249 + };
250
367 - getStackAddendumByID(id: ?DebugID): string {
251 + var getParentID = function(id: DebugID): ?DebugID {
252 + var item = getItem(id);
253 + return item ? item.parentID : null;
254 + };
255 +
256 + var getStackAddendumByID = function(id: ?DebugID): string {
257 var info = '';
258 while (id) {
259 info += describeID(id);
371 - id = ReactComponentTreeHook.getParentID(id);
260 + id = getParentID(id);
261 }
262 return info;
374 - },
263 + };
264
376 - // This function can only be called with a work-in-progress fiber and
377 - // only during begin or complete phase. Do not call it under any other
378 - // circumstances.
379 - getStackAddendumByWorkInProgressFiber(workInProgress : Fiber) : string {
380 - var info = '';
381 - var node = workInProgress;
382 - do {
383 - info += describeFiber(node);
384 - // Otherwise this return pointer might point to the wrong tree:
385 - node = node.return;
386 - } while (node);
387 - return info;
388 - },
265 + ReactComponentTreeHook = Object.assign({}, ReactComponentTreeHook, {
266 + onSetChildren(id: DebugID, nextChildIDs: Array<DebugID>): void {
267 + var item = getItem(id);
268 + invariant(item, 'Item must have been set');
269 + item.childIDs = nextChildIDs;
270 +
271 + for (var i = 0; i < nextChildIDs.length; i++) {
272 + var nextChildID = nextChildIDs[i];
273 + var nextChild = getItem(nextChildID);
274 + invariant(
275 + nextChild,
276 + 'Expected hook events to fire for the child ' +
277 + 'before its parent includes it in onSetChildren().'
278 + );
279 + invariant(
280 + nextChild.childIDs != null ||
281 + typeof nextChild.element !== 'object' ||
282 + nextChild.element == null,
283 + 'Expected onSetChildren() to fire for a container child ' +
284 + 'before its parent includes it in onSetChildren().'
285 + );
286 + invariant(
287 + nextChild.isMounted,
288 + 'Expected onMountComponent() to fire for the child ' +
289 + 'before its parent includes it in onSetChildren().'
290 + );
291 + if (nextChild.parentID == null) {
292 + nextChild.parentID = id;
293 + // TODO: This shouldn't be necessary but mounting a new root during in
294 + // componentWillMount currently causes not-yet-mounted components to
295 + // be purged from our tree data so their parent id is missing.
296 + }
297 + invariant(
298 + nextChild.parentID === id,
299 + 'Expected onBeforeMountComponent() parent and onSetChildren() to ' +
300 + 'be consistent (%s has parents %s and %s).',
301 + nextChildID,
302 + nextChild.parentID,
303 + id
304 + );
305 + }
306 + },
307 +
308 + onBeforeMountComponent(id: DebugID, element: ReactElement, parentID: DebugID): void {
309 + var item = {
310 + element,
311 + parentID,
312 + text: null,
313 + childIDs: [],
314 + isMounted: false,
315 + updateCount: 0,
316 + };
317 + setItem(id, item);
318 + },
319 +
320 + onBeforeUpdateComponent(id: DebugID, element: ReactElement): void {
321 + var item = getItem(id);
322 + if (!item || !item.isMounted) {
323 + // We may end up here as a result of setState() in componentWillUnmount().
324 + // In this case, ignore the element.
325 + return;
326 + }
327 + item.element = element;
328 + },
329
390 - getChildIDs(id: DebugID): Array<DebugID> {
391 - var item = getItem(id);
392 - return item ? item.childIDs : [];
393 - },
330 + onMountComponent(id: DebugID): void {
331 + var item = getItem(id);
332 + invariant(item, 'Item must have been set');
333 + item.isMounted = true;
334 + var isRoot = item.parentID === 0;
335 + if (isRoot) {
336 + addRoot(id);
337 + }
338 + },
339 +
340 + onUpdateComponent(id: DebugID): void {
341 + var item = getItem(id);
342 + if (!item || !item.isMounted) {
343 + // We may end up here as a result of setState() in componentWillUnmount().
344 + // In this case, ignore the element.
345 + return;
346 + }
347 + item.updateCount++;
348 + },
349 +
350 + onUnmountComponent(id: DebugID): void {
351 + var item = getItem(id);
352 + if (item) {
353 + // We need to check if it exists.
354 + // `item` might not exist if it is inside an error boundary, and a sibling
355 + // error boundary child threw while mounting. Then this instance never
356 + // got a chance to mount, but it still gets an unmounting event during
357 + // the error boundary cleanup.
358 + item.isMounted = false;
359 + var isRoot = item.parentID === 0;
360 + if (isRoot) {
361 + removeRoot(id);
362 + }
363 + }
364 + unmountedIDs.push(id);
365 + },
366
395 - getDisplayName(id: DebugID): ?string {
396 - var element = ReactComponentTreeHook.getElement(id);
397 - if (!element) {
398 - return null;
399 - }
400 - return getDisplayName(element);
401 - },
367 + purgeUnmountedComponents(): void {
368 + if (ReactComponentTreeHook._preventPurging) {
369 + // Should only be used for testing.
370 + return;
371 + }
372
403 - getElement(id: DebugID): ?ReactElement {
404 - var item = getItem(id);
405 - return item ? item.element : null;
406 - },
373 + for (var i = 0; i < unmountedIDs.length; i++) {
374 + var id = unmountedIDs[i];
375 + purgeDeep(id);
376 + }
377 + unmountedIDs.length = 0;
378 + },
379 +
380 + isMounted(id: DebugID): boolean {
381 + var item = getItem(id);
382 + return item ? item.isMounted : false;
383 + },
384 +
385 + getCurrentStackAddendum(topElement: ?ReactElement): string {
386 + var info = '';
387 + if (topElement) {
388 + var name = getDisplayName(topElement);
389 + var owner = topElement._owner;
390 + info += describeComponentFrame(
391 + name,
392 + topElement._source,
393 + owner && getComponentName(owner)
394 + );
395 + }
396
408 - getOwnerID(id: DebugID): ?DebugID {
409 - var element = ReactComponentTreeHook.getElement(id);
410 - if (!element || !element._owner) {
411 - return null;
412 - }
413 - return element._owner._debugID;
414 - },
397 + var currentOwner = ReactCurrentOwner.current;
398 + if (currentOwner) {
399 + if (typeof currentOwner.tag === 'number') {
400 + const workInProgress = ((currentOwner : any) : Fiber);
401 + // Safe because if current owner exists, we are reconciling,
402 + // and it is guaranteed to be the work-in-progress version.
403 + info += ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress);
404 + } else if (typeof currentOwner._debugID === 'number') {
405 + info += getStackAddendumByID(currentOwner._debugID);
406 + }
407 + }
408 + return info;
409 + },
410
416 - getParentID(id: DebugID): ?DebugID {
417 - var item = getItem(id);
418 - return item ? item.parentID : null;
419 - },
411 + getStackAddendumByID,
412
421 - getSource(id: DebugID): ?Source {
422 - var item = getItem(id);
423 - var element = item ? item.element : null;
424 - var source = element != null ? element._source : null;
425 - return source;
426 - },
413 + getChildIDs(id: DebugID): Array<DebugID> {
414 + var item = getItem(id);
415 + return item ? item.childIDs : [];
416 + },
417
428 - getText(id: DebugID): ?string {
429 - var element = ReactComponentTreeHook.getElement(id);
430 - if (typeof element === 'string') {
431 - return element;
432 - } else if (typeof element === 'number') {
433 - return '' + element;
434 - } else {
435 - return null;
436 - }
437 - },
418 + getDisplayName(id: DebugID): ?string {
419 + var element = getElement(id);
420 + if (!element) {
421 + return null;
422 + }
423 + return getDisplayName(element);
424 + },
425 +
426 + getElement,
427 +
428 + getOwnerID,
429 +
430 + getParentID,
431 +
432 + getSource(id: DebugID): ?Source {
433 + var item = getItem(id);
434 + var element = item ? item.element : null;
435 + var source = element != null ? element._source : null;
436 + return source;
437 + },
438 +
439 + getText(id: DebugID): ?string {
440 + var element = getElement(id);
441 + if (typeof element === 'string') {
442 + return element;
443 + } else if (typeof element === 'number') {
444 + return '' + element;
445 + } else {
446 + return null;
447 + }
448 + },
449
439 - getUpdateCount(id: DebugID): number {
440 - var item = getItem(id);
441 - return item ? item.updateCount : 0;
442 - },
450 + getUpdateCount(id: DebugID): number {
451 + var item = getItem(id);
452 + return item ? item.updateCount : 0;
453 + },
454
444 - getRootIDs,
445 - getRegisteredIDs: getItemIDs,
446 -};
455 + getRootIDs,
456 + getRegisteredIDs: getItemIDs,
457 + });
458 +}
459
460 module.exports = ReactComponentTreeHook;
src/renderers/shared/ReactDebugTool.js
+11 -11
@@ -108,22 +108,22 @@ if (__DEV__) {
108 var lifeCycleTimerHasWarned = false;
109
110 const clearHistory = function() {
111 - ReactComponentTreeHook.purgeUnmountedComponents();
111 + (ReactComponentTreeHook: any).purgeUnmountedComponents();
112 ReactHostOperationHistoryHook.clearHistory();
113 };
114
115 const getTreeSnapshot = function(registeredIDs) {
116 return registeredIDs.reduce((tree, id) => {
117 - var ownerID = ReactComponentTreeHook.getOwnerID(id);
118 - var parentID = ReactComponentTreeHook.getParentID(id);
117 + var ownerID = (ReactComponentTreeHook: any).getOwnerID(id);
118 + var parentID = (ReactComponentTreeHook: any).getParentID(id);
119 tree[id] = {
120 - displayName: ReactComponentTreeHook.getDisplayName(id),
121 - text: ReactComponentTreeHook.getText(id),
122 - updateCount: ReactComponentTreeHook.getUpdateCount(id),
123 - childIDs: ReactComponentTreeHook.getChildIDs(id),
120 + displayName: (ReactComponentTreeHook: any).getDisplayName(id),
121 + text: (ReactComponentTreeHook: any).getText(id),
122 + updateCount: (ReactComponentTreeHook: any).getUpdateCount(id),
123 + childIDs: (ReactComponentTreeHook: any).getChildIDs(id),
124 // Text nodes don't have owners but this is close enough.
125 ownerID: ownerID ||
126 - parentID && ReactComponentTreeHook.getOwnerID(parentID) ||
126 + parentID && (ReactComponentTreeHook: any).getOwnerID(parentID) ||
127 0,
128 parentID,
129 };
@@ -144,7 +144,7 @@ if (__DEV__) {
144 }
145
146 if (previousMeasurements.length || previousOperations.length) {
147 - var registeredIDs = ReactComponentTreeHook.getRegisteredIDs();
147 + var registeredIDs = (ReactComponentTreeHook: any).getRegisteredIDs();
148 flushHistory.push({
149 duration: performanceNow() - previousStartTime,
150 measurements: previousMeasurements || [],
@@ -253,7 +253,7 @@ if (__DEV__) {
253 if (!isProfiling || !canUsePerformanceMeasure) {
254 return false;
255 }
256 - var element = ReactComponentTreeHook.getElement(debugID);
256 + var element = (ReactComponentTreeHook: any).getElement(debugID);
257 if (element == null || typeof element !== 'object') {
258 return false;
259 }
@@ -280,7 +280,7 @@ if (__DEV__) {
280 }
281
282 var markName = `${debugID}::${markType}`;
283 - var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown';
283 + var displayName = (ReactComponentTreeHook: any).getDisplayName(debugID) || 'Unknown';
284
285 // Chrome has an issue of dropping markers recorded too fast:
286 // https://bugs.chromium.org/p/chromium/issues/detail?id=640652
src/renderers/shared/stack/reconciler/ReactRef.js
+1 -1
@@ -53,7 +53,7 @@ function attachRef(ref, component, owner) {
53 'Stateless function components cannot be given refs. ' +
54 'Attempts to access this ref will fail.%s%s',
55 info,
56 - ReactComponentTreeHook.getStackAddendumByID(component._debugID)
56 + (ReactComponentTreeHook: any).getStackAddendumByID(component._debugID)
57 );
58 }
59 }
src/shared/utils/flattenChildren.js
+1 -1
@@ -58,7 +58,7 @@ function flattenSingleChildIntoContext(
58 '`%s`. Child keys must be unique; when two children share a key, only ' +
59 'the first child will be used.%s',
60 KeyEscapeUtils.unescape(name),
61 - ReactComponentTreeHook.getStackAddendumByID(selfDebugID)
61 + (ReactComponentTreeHook: any).getStackAddendumByID(selfDebugID)
62 );
63 }
64 }