From b8e0b0c92246efd3eb941411a0c4ef03a9e0d2f8 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 10 Jan 2022 16:01:12 -0500 Subject: [PATCH] add component boilerplate - Add Tracing Marker component type to React exports - Add reconciler work tag - Add devtools work tag - Add boilerplate for the cache to render children No functionality yet --- .../src/backend/renderer.js | 13 +++++++++ .../src/backend/types.js | 1 + packages/react-devtools-shared/src/types.js | 3 ++- packages/react-devtools-shared/src/utils.js | 7 ++++- .../react-reconciler/src/ReactFiber.new.js | 20 ++++++++++++++ .../react-reconciler/src/ReactFiber.old.js | 20 ++++++++++++++ .../src/ReactFiberBeginWork.new.js | 27 +++++++++++++++++++ .../src/ReactFiberBeginWork.old.js | 27 +++++++++++++++++++ .../react-reconciler/src/ReactWorkTags.js | 4 ++- .../src/getComponentNameFromFiber.js | 4 ++- packages/react/index.js | 1 + packages/react/src/React.js | 3 +++ packages/shared/ReactSymbols.js | 2 ++ packages/shared/getComponentNameFromType.js | 3 +++ packages/shared/isValidElementType.js | 10 +++++-- 15 files changed, 139 insertions(+), 6 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index 61bf164dc4598..88c1d53608372 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -24,6 +24,7 @@ import { ElementTypeRoot, ElementTypeSuspense, ElementTypeSuspenseList, + ElementTypeTracingMarker, StrictMode, } from 'react-devtools-shared/src/types'; import { @@ -247,6 +248,8 @@ export function getInternalReactConstants( SimpleMemoComponent: 15, SuspenseComponent: 13, SuspenseListComponent: 19, // Experimental + TracingMarkerComponent: 25, // Experimental - This is technically in 18 but we don't + // want to fork again so we're adding it here instead YieldComponent: -1, // Removed }; } else if (gte(version, '17.0.0-alpha')) { @@ -277,6 +280,7 @@ export function getInternalReactConstants( SimpleMemoComponent: 15, SuspenseComponent: 13, SuspenseListComponent: 19, // Experimental + TracingMarkerComponent: -1, // Doesn't exist yet YieldComponent: -1, // Removed }; } else if (gte(version, '16.6.0-beta.0')) { @@ -307,6 +311,7 @@ export function getInternalReactConstants( SimpleMemoComponent: 15, SuspenseComponent: 13, SuspenseListComponent: 19, // Experimental + TracingMarkerComponent: -1, // Doesn't exist yet YieldComponent: -1, // Removed }; } else if (gte(version, '16.4.3-alpha')) { @@ -337,6 +342,7 @@ export function getInternalReactConstants( SimpleMemoComponent: -1, // Doesn't exist yet SuspenseComponent: 16, SuspenseListComponent: -1, // Doesn't exist yet + TracingMarkerComponent: -1, // Doesn't exist yet YieldComponent: -1, // Removed }; } else { @@ -367,6 +373,7 @@ export function getInternalReactConstants( SimpleMemoComponent: -1, // Doesn't exist yet SuspenseComponent: 16, SuspenseListComponent: -1, // Doesn't exist yet + TracingMarkerComponent: -1, // Doesn't exist yet YieldComponent: 9, }; } @@ -405,6 +412,7 @@ export function getInternalReactConstants( SimpleMemoComponent, SuspenseComponent, SuspenseListComponent, + TracingMarkerComponent, } = ReactTypeOfWork; function resolveFiberType(type: any) { @@ -484,6 +492,8 @@ export function getInternalReactConstants( return 'SuspenseList'; case Profiler: return 'Profiler'; + case TracingMarkerComponent: + return 'TracingMarker'; default: const typeSymbol = getTypeSymbol(type); @@ -583,6 +593,7 @@ export function attach( SimpleMemoComponent, SuspenseComponent, SuspenseListComponent, + TracingMarkerComponent, } = ReactTypeOfWork; const { ImmediatePriority, @@ -1044,6 +1055,8 @@ export function attach( return ElementTypeSuspense; case SuspenseListComponent: return ElementTypeSuspenseList; + case TracingMarkerComponent: + return ElementTypeTracingMarker; default: const typeSymbol = getTypeSymbol(type); diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index 91a1a0c713cb3..4d975dbfec0d5 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -53,6 +53,7 @@ export type WorkTagMap = {| SimpleMemoComponent: WorkTag, SuspenseComponent: WorkTag, SuspenseListComponent: WorkTag, + TracingMarkerComponent: WorkTag, YieldComponent: WorkTag, |}; diff --git a/packages/react-devtools-shared/src/types.js b/packages/react-devtools-shared/src/types.js index 859fb9bd8ff72..6eb3e2f3a7686 100644 --- a/packages/react-devtools-shared/src/types.js +++ b/packages/react-devtools-shared/src/types.js @@ -32,11 +32,12 @@ export const ElementTypeProfiler = 10; export const ElementTypeRoot = 11; export const ElementTypeSuspense = 12; export const ElementTypeSuspenseList = 13; +export const ElementTypeTracingMarker = 14; // Different types of elements displayed in the Elements tree. // These types may be used to visually distinguish types, // or to enable/disable certain functionality. -export type ElementType = 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13; +export type ElementType = 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14; // WARNING // The values below are referenced by ComponentFilters (which are saved via localStorage). diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index c022cd4650ed7..181820646e9fd 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -22,7 +22,10 @@ import { StrictMode, Suspense, } from 'react-is'; -import {REACT_SUSPENSE_LIST_TYPE as SuspenseList} from 'shared/ReactSymbols'; +import { + REACT_SUSPENSE_LIST_TYPE as SuspenseList, + REACT_TRACING_MARKER_TYPE as TracingMarker, +} from 'shared/ReactSymbols'; import { TREE_OPERATION_ADD, TREE_OPERATION_REMOVE, @@ -684,6 +687,8 @@ export function getDisplayNameForReactElement( return 'Suspense'; case SuspenseList: return 'SuspenseList'; + case TracingMarker: + return 'TracingMarker'; default: const {type} = element; if (typeof type === 'string') { diff --git a/packages/react-reconciler/src/ReactFiber.new.js b/packages/react-reconciler/src/ReactFiber.new.js index 2e5c40c220a71..ae51649b4a908 100644 --- a/packages/react-reconciler/src/ReactFiber.new.js +++ b/packages/react-reconciler/src/ReactFiber.new.js @@ -25,6 +25,7 @@ import { enableScopeAPI, enableSyncDefaultUpdates, allowConcurrentByDefault, + enableTransitionTracing, } from 'shared/ReactFeatureFlags'; import { supportsPersistence, @@ -56,6 +57,7 @@ import { OffscreenComponent, LegacyHiddenComponent, CacheComponent, + TracingMarkerComponent, } from './ReactWorkTags'; import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber'; @@ -91,6 +93,7 @@ import { REACT_OFFSCREEN_TYPE, REACT_LEGACY_HIDDEN_TYPE, REACT_CACHE_TYPE, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; export type {Fiber}; @@ -521,6 +524,11 @@ export function createFiberFromTypeAndProps( return createFiberFromCache(pendingProps, mode, lanes, key); } // eslint-disable-next-line no-fallthrough + case REACT_TRACING_MARKER_TYPE: + if (enableTransitionTracing) { + return createFiberFromTracingMarker(pendingProps, mode, lanes, key); + } + // eslint-disable-next-line no-fallthrough default: { if (typeof type === 'object' && type !== null) { switch (type.$$typeof) { @@ -746,6 +754,18 @@ export function createFiberFromCache( return fiber; } +export function createFiberFromTracingMarker( + pendingProps: any, + mode: TypeOfMode, + lanes: Lanes, + key: null | string, +) { + const fiber = createFiber(TracingMarkerComponent, pendingProps, key, mode); + fiber.elementType = REACT_TRACING_MARKER_TYPE; + fiber.lanes = lanes; + return fiber; +} + export function createFiberFromText( content: string, mode: TypeOfMode, diff --git a/packages/react-reconciler/src/ReactFiber.old.js b/packages/react-reconciler/src/ReactFiber.old.js index 9d559a3f7afb0..e590c3f493fbd 100644 --- a/packages/react-reconciler/src/ReactFiber.old.js +++ b/packages/react-reconciler/src/ReactFiber.old.js @@ -25,6 +25,7 @@ import { enableScopeAPI, enableSyncDefaultUpdates, allowConcurrentByDefault, + enableTransitionTracing, } from 'shared/ReactFeatureFlags'; import { supportsPersistence, @@ -56,6 +57,7 @@ import { OffscreenComponent, LegacyHiddenComponent, CacheComponent, + TracingMarkerComponent, } from './ReactWorkTags'; import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber'; @@ -91,6 +93,7 @@ import { REACT_OFFSCREEN_TYPE, REACT_LEGACY_HIDDEN_TYPE, REACT_CACHE_TYPE, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; export type {Fiber}; @@ -521,6 +524,11 @@ export function createFiberFromTypeAndProps( return createFiberFromCache(pendingProps, mode, lanes, key); } // eslint-disable-next-line no-fallthrough + case REACT_TRACING_MARKER_TYPE: + if (enableTransitionTracing) { + return createFiberFromTracingMarker(pendingProps, mode, lanes, key); + } + // eslint-disable-next-line no-fallthrough default: { if (typeof type === 'object' && type !== null) { switch (type.$$typeof) { @@ -746,6 +754,18 @@ export function createFiberFromCache( return fiber; } +export function createFiberFromTracingMarker( + pendingProps: any, + mode: TypeOfMode, + lanes: Lanes, + key: null | string, +) { + const fiber = createFiber(TracingMarkerComponent, pendingProps, key, mode); + fiber.elementType = REACT_TRACING_MARKER_TYPE; + fiber.lanes = lanes; + return fiber; +} + export function createFiberFromText( content: string, mode: TypeOfMode, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index b001088f17e6d..521a75d11dcb7 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -61,6 +61,7 @@ import { OffscreenComponent, LegacyHiddenComponent, CacheComponent, + TracingMarkerComponent, } from './ReactWorkTags'; import { NoFlags, @@ -93,6 +94,7 @@ import { enableSuspenseLayoutEffectSemantics, enableSchedulingProfiler, enablePersistentOffscreenHostContainer, + enableTransitionTracing, } from 'shared/ReactFeatureFlags'; import isArray from 'shared/isArray'; import shallowEqual from 'shared/shallowEqual'; @@ -898,6 +900,21 @@ function updateCacheComponent( return workInProgress.child; } +// This should only be called if the name changes +function updateTracingMarkerComponent( + current: Fiber | null, + workInProgress: Fiber, + renderLanes: Lanes, +) { + if (!enableTransitionTracing) { + return null; + } + + const nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + function updateFragment( current: Fiber | null, workInProgress: Fiber, @@ -3900,6 +3917,16 @@ function beginWork( } break; } + case TracingMarkerComponent: { + if (enableTransitionTracing) { + return updateTracingMarkerComponent( + current, + workInProgress, + renderLanes, + ); + } + break; + } } throw new Error( diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index cbf3c5fa2e3ce..471bb11d941da 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -61,6 +61,7 @@ import { OffscreenComponent, LegacyHiddenComponent, CacheComponent, + TracingMarkerComponent, } from './ReactWorkTags'; import { NoFlags, @@ -93,6 +94,7 @@ import { enableSuspenseLayoutEffectSemantics, enableSchedulingProfiler, enablePersistentOffscreenHostContainer, + enableTransitionTracing, } from 'shared/ReactFeatureFlags'; import isArray from 'shared/isArray'; import shallowEqual from 'shared/shallowEqual'; @@ -898,6 +900,21 @@ function updateCacheComponent( return workInProgress.child; } +// This should only be called if the name changes +function updateTracingMarkerComponent( + current: Fiber | null, + workInProgress: Fiber, + renderLanes: Lanes, +) { + if (!enableTransitionTracing) { + return null; + } + + const nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + function updateFragment( current: Fiber | null, workInProgress: Fiber, @@ -3900,6 +3917,16 @@ function beginWork( } break; } + case TracingMarkerComponent: { + if (enableTransitionTracing) { + return updateTracingMarkerComponent( + current, + workInProgress, + renderLanes, + ); + } + break; + } } throw new Error( diff --git a/packages/react-reconciler/src/ReactWorkTags.js b/packages/react-reconciler/src/ReactWorkTags.js index fca4ffdce78b6..00d2d93794e9a 100644 --- a/packages/react-reconciler/src/ReactWorkTags.js +++ b/packages/react-reconciler/src/ReactWorkTags.js @@ -32,7 +32,8 @@ export type WorkTag = | 21 | 22 | 23 - | 24; + | 24 + | 25; export const FunctionComponent = 0; export const ClassComponent = 1; @@ -58,3 +59,4 @@ export const ScopeComponent = 21; export const OffscreenComponent = 22; export const LegacyHiddenComponent = 23; export const CacheComponent = 24; +export const TracingMarkerComponent = 25; diff --git a/packages/react-reconciler/src/getComponentNameFromFiber.js b/packages/react-reconciler/src/getComponentNameFromFiber.js index 4ae33c2ed594a..5cb87189c975c 100644 --- a/packages/react-reconciler/src/getComponentNameFromFiber.js +++ b/packages/react-reconciler/src/getComponentNameFromFiber.js @@ -34,6 +34,7 @@ import { OffscreenComponent, LegacyHiddenComponent, CacheComponent, + TracingMarkerComponent, } from 'react-reconciler/src/ReactWorkTags'; import getComponentNameFromType from 'shared/getComponentNameFromType'; import {REACT_STRICT_MODE_TYPE} from 'shared/ReactSymbols'; @@ -103,7 +104,8 @@ export default function getComponentNameFromFiber(fiber: Fiber): string | null { return 'Suspense'; case SuspenseListComponent: return 'SuspenseList'; - + case TracingMarkerComponent: + return 'TracingMarker'; // The display name for this tags come from the user-provided type: case ClassComponent: case FunctionComponent: diff --git a/packages/react/index.js b/packages/react/index.js index 6a249ba432c72..e4946bf095b69 100644 --- a/packages/react/index.js +++ b/packages/react/index.js @@ -58,6 +58,7 @@ export { unstable_LegacyHidden, unstable_Offscreen, unstable_Scope, + unstable_TracingMarker, unstable_getCacheSignal, unstable_getCacheForType, unstable_useCacheRefresh, diff --git a/packages/react/src/React.js b/packages/react/src/React.js index 891269ee32653..b899f51c80b6e 100644 --- a/packages/react/src/React.js +++ b/packages/react/src/React.js @@ -19,6 +19,7 @@ import { REACT_OFFSCREEN_TYPE, REACT_SCOPE_TYPE, REACT_CACHE_TYPE, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; import {Component, PureComponent} from './ReactBaseClasses'; @@ -126,6 +127,8 @@ export { REACT_CACHE_TYPE as unstable_Cache, // enableScopeAPI REACT_SCOPE_TYPE as unstable_Scope, + // enableTransitionTracing + REACT_TRACING_MARKER_TYPE as unstable_TracingMarker, useId, act, }; diff --git a/packages/shared/ReactSymbols.js b/packages/shared/ReactSymbols.js index a50a06b150169..3c67aeb7b85ec 100644 --- a/packages/shared/ReactSymbols.js +++ b/packages/shared/ReactSymbols.js @@ -30,6 +30,7 @@ export let REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; export let REACT_OFFSCREEN_TYPE = 0xeae2; export let REACT_LEGACY_HIDDEN_TYPE = 0xeae3; export let REACT_CACHE_TYPE = 0xeae4; +export let REACT_TRACING_MARKER_TYPE = 0xeae5; if (typeof Symbol === 'function' && Symbol.for) { const symbolFor = Symbol.for; @@ -50,6 +51,7 @@ if (typeof Symbol === 'function' && Symbol.for) { REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen'); REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden'); REACT_CACHE_TYPE = symbolFor('react.cache'); + REACT_TRACING_MARKER_TYPE = symbolFor('react.tracing_marker'); } const MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; diff --git a/packages/shared/getComponentNameFromType.js b/packages/shared/getComponentNameFromType.js index a8e1d088664e9..36432e56acada 100644 --- a/packages/shared/getComponentNameFromType.js +++ b/packages/shared/getComponentNameFromType.js @@ -23,6 +23,7 @@ import { REACT_SUSPENSE_LIST_TYPE, REACT_LAZY_TYPE, REACT_CACHE_TYPE, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; // Keep in sync with react-reconciler/getComponentNameFromFiber @@ -79,6 +80,8 @@ export default function getComponentNameFromType(type: mixed): string | null { return 'SuspenseList'; case REACT_CACHE_TYPE: return 'Cache'; + case REACT_TRACING_MARKER_TYPE: + return 'TracingMarker'; } if (typeof type === 'object') { switch (type.$$typeof) { diff --git a/packages/shared/isValidElementType.js b/packages/shared/isValidElementType.js index 78b6d2fc27545..e72b42d8794ae 100644 --- a/packages/shared/isValidElementType.js +++ b/packages/shared/isValidElementType.js @@ -23,8 +23,13 @@ import { REACT_LEGACY_HIDDEN_TYPE, REACT_OFFSCREEN_TYPE, REACT_CACHE_TYPE, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; -import {enableScopeAPI, enableCache} from './ReactFeatureFlags'; +import { + enableScopeAPI, + enableCache, + enableTransitionTracing, +} from './ReactFeatureFlags'; let REACT_MODULE_REFERENCE: number | Symbol = 0; if (typeof Symbol === 'function') { @@ -47,7 +52,8 @@ export default function isValidElementType(type: mixed) { type === REACT_LEGACY_HIDDEN_TYPE || type === REACT_OFFSCREEN_TYPE || (enableScopeAPI && type === REACT_SCOPE_TYPE) || - (enableCache && type === REACT_CACHE_TYPE) + (enableCache && type === REACT_CACHE_TYPE) || + (enableTransitionTracing && type === REACT_TRACING_MARKER_TYPE) ) { return true; }