Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suspense fuzz tester #14147

Merged
merged 5 commits into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -1178,7 +1178,6 @@ function updateSuspenseComponent(
currentPrimaryChildFragment.pendingProps,
NoWork,
);
primaryChildFragment.effectTag |= Placement;

if ((workInProgress.mode & ConcurrentMode) === NoContext) {
// Outside of concurrent mode, we commit the effects from the
Expand Down Expand Up @@ -1213,7 +1212,6 @@ function updateSuspenseComponent(
nextFallbackChildren,
currentFallbackChildFragment.expirationTime,
));
fallbackChildFragment.effectTag |= Placement;
child = primaryChildFragment;
primaryChildFragment.childExpirationTime = NoWork;
// Skip the primary children, and continue working on the
Expand Down Expand Up @@ -1257,11 +1255,14 @@ function updateSuspenseComponent(
NoWork,
null,
);

primaryChildFragment.effectTag |= Placement;
primaryChildFragment.child = currentPrimaryChild;
currentPrimaryChild.return = primaryChildFragment;

// Even though we're creating a new fiber, there are no new children,
// because we're reusing an already mounted tree. So we don't need to
// schedule a placement.
// primaryChildFragment.effectTag |= Placement;

if ((workInProgress.mode & ConcurrentMode) === NoContext) {
// Outside of concurrent mode, we commit the effects from the
// partially completed, timed-out tree, too.
Expand Down
10 changes: 10 additions & 0 deletions packages/react-reconciler/src/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,16 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
} else {
unhideTextInstance(instance, node.memoizedProps);
}
} else if (
node.tag === SuspenseComponent &&
node.memoizedState !== null
) {
// Found a nested Suspense component that timed out. Skip over the
// primary child fragment, which should remain hidden.
const fallbackChildFragment: Fiber = (node.child: any).sibling;
fallbackChildFragment.return = node;
node = fallbackChildFragment;
continue;
} else if (node.child !== null) {
node.child.return = node;
node = node.child;
Expand Down
18 changes: 11 additions & 7 deletions packages/react-reconciler/src/ReactFiberCompleteWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
Update,
NoEffect,
DidCapture,
Deletion,
} from 'shared/ReactSideEffectTags';
import invariant from 'shared/invariant';

Expand Down Expand Up @@ -82,7 +83,6 @@ import {
popHydrationState,
} from './ReactFiberHydrationContext';
import {ConcurrentMode, NoContext} from './ReactTypeOfMode';
import {reconcileChildFibers} from './ReactChildFiber';

function markUpdate(workInProgress: Fiber) {
// Tag the fiber with an update effect. This turns a Placement into
Expand Down Expand Up @@ -715,12 +715,16 @@ function completeWork(
// the stateNode during the begin phase?
const currentFallbackChild: Fiber | null = (current.child: any).sibling;
if (currentFallbackChild !== null) {
reconcileChildFibers(
workInProgress,
currentFallbackChild,
null,
renderExpirationTime,
);
// Deletions go at the beginning of the return fiber's effect list
const first = workInProgress.firstEffect;
if (first !== null) {
workInProgress.firstEffect = currentFallbackChild;
currentFallbackChild.nextEffect = first;
} else {
workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
currentFallbackChild.nextEffect = null;
}
currentFallbackChild.effectTag = Deletion;
}
}

Expand Down
83 changes: 40 additions & 43 deletions packages/react-reconciler/src/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,46 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
}
}

if (enableSchedulerTracing) {
if (root !== null) {
const interactions = __interactionsRef.current;
if (interactions.size > 0) {
const pendingInteractionMap = root.pendingInteractionMap;
const pendingInteractions = pendingInteractionMap.get(expirationTime);
if (pendingInteractions != null) {
interactions.forEach(interaction => {
if (!pendingInteractions.has(interaction)) {
// Update the pending async work count for previously unscheduled interaction.
interaction.__count++;
}

pendingInteractions.add(interaction);
});
} else {
pendingInteractionMap.set(expirationTime, new Set(interactions));

// Update the pending async work count for the current interactions.
interactions.forEach(interaction => {
interaction.__count++;
});
}

const subscriber = __subscriberRef.current;
if (subscriber !== null) {
const threadID = computeThreadID(
expirationTime,
root.interactionThreadID,
);
subscriber.onWorkScheduled(interactions, threadID);
}
}
}
}
return root;
}

function scheduleWork(fiber: Fiber, expirationTime: ExpirationTime) {
const root = scheduleWorkToRoot(fiber, expirationTime);
if (root === null) {
if (__DEV__) {
switch (fiber.tag) {
Expand All @@ -1761,49 +1801,6 @@ function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
break;
}
}
return null;
}

if (enableSchedulerTracing) {
const interactions = __interactionsRef.current;
if (interactions.size > 0) {
const pendingInteractionMap = root.pendingInteractionMap;
const pendingInteractions = pendingInteractionMap.get(expirationTime);
if (pendingInteractions != null) {
interactions.forEach(interaction => {
if (!pendingInteractions.has(interaction)) {
// Update the pending async work count for previously unscheduled interaction.
interaction.__count++;
}

pendingInteractions.add(interaction);
});
} else {
pendingInteractionMap.set(expirationTime, new Set(interactions));

// Update the pending async work count for the current interactions.
interactions.forEach(interaction => {
interaction.__count++;
});
}

const subscriber = __subscriberRef.current;
if (subscriber !== null) {
const threadID = computeThreadID(
expirationTime,
root.interactionThreadID,
);
subscriber.onWorkScheduled(interactions, threadID);
}
}
}

return root;
}

function scheduleWork(fiber: Fiber, expirationTime: ExpirationTime) {
const root = scheduleWorkToRoot(fiber, expirationTime);
if (root === null) {
return;
}

Expand Down
Loading