Skip to content

Commit

Permalink
Flow: inference_mode=constrain_writes
Browse files Browse the repository at this point in the history
This mode is going to be the new default in Flow going forward.
There was an unfortuante large number of suppressions in this update.

More on the changes can be found in this [Flow blog post](https://medium.com/flow-type/new-flow-language-rule-constrained-writes-4c70e375d190).

Added some of the required annotations using the provided codemod:

```sh
node_modules/.bin/flow codemod annotate-declarations --write .
```

ghstack-source-id: a9f908c0062f03fef8b4e6056f9dc83ec6428db5
Pull Request resolved: facebook#25422
  • Loading branch information
kassens committed Oct 4, 2022
1 parent af9afe9 commit 647263a
Show file tree
Hide file tree
Showing 70 changed files with 201 additions and 87 deletions.
2 changes: 1 addition & 1 deletion packages/react-cache/src/LRU.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function createLRU<T>(limit: number): LRU<T> {
// Delete entries from the cache, starting from the end of the list.
if (first !== null) {
const resolvedFirst: Entry<T> = (first: any);
let last = resolvedFirst.previous;
let last: null | Entry<T> = resolvedFirst.previous;
while (size > targetSize && last !== null) {
const onDelete = last.onDelete;
const previous = last.previous;
Expand Down
5 changes: 3 additions & 2 deletions packages/react-debug-tools/src/ReactDebugHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ function useImperativeHandle<T>(
// and if there is a ref callback it might not store it but if it does we
// have no way of knowing where. So let's only enable introspection of the
// ref itself if it is using the object form.
let instance = undefined;
let instance: ?T = undefined;
if (ref !== null && typeof ref === 'object') {
instance = ref.current;
}
Expand Down Expand Up @@ -716,14 +716,15 @@ export function inspectHooks<Props>(
} finally {
readHookLog = hookLog;
hookLog = [];
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentDispatcher.current = previousDispatcher;
}
const rootStack = ErrorStackParser.parse(ancestorStackError);
return buildTree(rootStack, readHookLog, includeHooksSource);
}

function setupContexts(contextMap: Map<ReactContext<any>, any>, fiber: Fiber) {
let current = fiber;
let current: null | Fiber = fiber;
while (current) {
if (current.tag === ContextProvider) {
const providerType: ReactProviderType<any> = current.type;
Expand Down
4 changes: 4 additions & 0 deletions packages/react-devtools-core/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
}
},
);
// $FlowFixMe[incompatible-use] found when upgrading Flow
bridge.addListener(
'updateComponentFilters',
(componentFilters: Array<ComponentFilter>) => {
Expand All @@ -165,10 +166,12 @@ export function connectToDevTools(options: ?ConnectOptions) {
// Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
// So for now we just fall back to using the default filters...
if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
// $FlowFixMe[incompatible-use] found when upgrading Flow
bridge.send('overrideComponentFilters', savedComponentFilters);
}

// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
// $FlowFixMe[incompatible-call] found when upgrading Flow
const agent = new Agent(bridge);
agent.addListener('shutdown', () => {
// If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
Expand All @@ -181,6 +184,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
// Setup React Native style editor if the environment supports it.
if (resolveRNStyle != null || hook.resolveRNStyle != null) {
setupNativeStyleEditor(
// $FlowFixMe[incompatible-call] found when upgrading Flow
bridge,
agent,
((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
Expand Down
1 change: 1 addition & 0 deletions packages/react-devtools-core/src/standalone.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ function initialize(socket: WebSocket) {
socket.close();
});

// $FlowFixMe[incompatible-call] found when upgrading Flow
store = new Store(bridge, {
checkBridgeProtocolCompatibility: true,
supportsNativeInspection: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ export function getStackByFiberInDevAndProd(
): string {
try {
let info = '';
let node = workInProgress;
let node: Fiber = workInProgress;
do {
info += describeFiber(workTagMap, node, currentDispatcherRef);
// $FlowFixMe[incompatible-type] we bail out when we get a null
node = node.return;
} while (node);
return info;
Expand Down
4 changes: 4 additions & 0 deletions packages/react-devtools-shared/src/backend/legacy/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ export function attach(
parentIDStack.pop();
return result;
} catch (err) {
// $FlowFixMe[incompatible-type] found when upgrading Flow
parentIDStack = [];
throw err;
} finally {
Expand Down Expand Up @@ -284,6 +285,7 @@ export function attach(
parentIDStack.pop();
return result;
} catch (err) {
// $FlowFixMe[incompatible-type] found when upgrading Flow
parentIDStack = [];
throw err;
} finally {
Expand Down Expand Up @@ -320,6 +322,7 @@ export function attach(
parentIDStack.pop();
return result;
} catch (err) {
// $FlowFixMe[incompatible-type] found when upgrading Flow
parentIDStack = [];
throw err;
} finally {
Expand Down Expand Up @@ -351,6 +354,7 @@ export function attach(

return result;
} catch (err) {
// $FlowFixMe[incompatible-type] found when upgrading Flow
parentIDStack = [];
throw err;
} finally {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-devtools-shared/src/backend/profilingHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ export function createProfilingHooks({

function getParentFibers(fiber: Fiber): Array<Fiber> {
const parents = [];
let parent = fiber;
let parent: null | Fiber = fiber;
while (parent !== null) {
parents.push(parent);
parent = parent.return;
Expand All @@ -824,6 +824,7 @@ export function createProfilingHooks({
warning: null,
};
currentFiberStacks.set(event, getParentFibers(fiber));
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTimelineData.schedulingEvents.push(event);
}
}
Expand Down
22 changes: 15 additions & 7 deletions packages/react-devtools-shared/src/backend/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,7 @@ export function attach(

// This is a naive implementation that shallowly recourses children.
// We might want to revisit this if it proves to be too inefficient.
let child = childSet;
let child: null | Fiber = childSet;
while (child !== null) {
findReorderedChildrenRecursively(child, nextChildren);
child = child.sibling;
Expand Down Expand Up @@ -2846,11 +2846,11 @@ export function attach(
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js
function getNearestMountedFiber(fiber: Fiber): null | Fiber {
let node = fiber;
let nearestMounted = fiber;
let nearestMounted: null | Fiber = fiber;
if (!fiber.alternate) {
// If there is no alternate, this might be a new tree that isn't inserted
// yet. If it is, then it will have a pending insertion effect on it.
let nextNode = node;
let nextNode: Fiber = node;
do {
node = nextNode;
if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
Expand All @@ -2859,6 +2859,7 @@ export function attach(
// if that one is still mounted.
nearestMounted = node.return;
}
// $FlowFixMe[incompatible-type] we bail out when we get a null
nextNode = node.return;
} while (nextNode);
} else {
Expand Down Expand Up @@ -3097,7 +3098,7 @@ export function attach(
const owners: Array<SerializedElement> = [fiberToSerializedElement(fiber)];

if (_debugOwner) {
let owner = _debugOwner;
let owner: null | Fiber = _debugOwner;
while (owner !== null) {
owners.unshift(fiberToSerializedElement(owner));
owner = owner._debugOwner || null;
Expand Down Expand Up @@ -3256,7 +3257,7 @@ export function attach(
let owners = null;
if (_debugOwner) {
owners = [];
let owner = _debugOwner;
let owner: null | Fiber = _debugOwner;
while (owner !== null) {
owners.push(fiberToSerializedElement(owner));
owner = owner._debugOwner || null;
Expand Down Expand Up @@ -3687,18 +3688,22 @@ export function attach(
// This will enable us to send patches without re-inspecting if hydrated paths are requested.
// (Reducing how often we shallow-render is a better DX for function components that use hooks.)
const cleanedInspectedElement = {...mostRecentlyInspectedElement};
// $FlowFixMe[prop-missing] found when upgrading Flow
cleanedInspectedElement.context = cleanForBridge(
cleanedInspectedElement.context,
createIsPathAllowed('context', null),
);
// $FlowFixMe[prop-missing] found when upgrading Flow
cleanedInspectedElement.hooks = cleanForBridge(
cleanedInspectedElement.hooks,
createIsPathAllowed('hooks', 'hooks'),
);
// $FlowFixMe[prop-missing] found when upgrading Flow
cleanedInspectedElement.props = cleanForBridge(
cleanedInspectedElement.props,
createIsPathAllowed('props', null),
);
// $FlowFixMe[prop-missing] found when upgrading Flow
cleanedInspectedElement.state = cleanForBridge(
cleanedInspectedElement.state,
createIsPathAllowed('state', null),
Expand All @@ -3709,6 +3714,7 @@ export function attach(
responseID: requestID,
type: 'full-data',
// $FlowFixMe[incompatible-return] found when upgrading Flow
// $FlowFixMe[prop-missing] found when upgrading Flow
value: cleanedInspectedElement,
};
}
Expand Down Expand Up @@ -4420,13 +4426,15 @@ export function attach(
// The return path will contain Fibers that are "invisible" to the store
// because their keys and indexes are important to restoring the selection.
function getPathForElement(id: number): Array<PathFrame> | null {
let fiber = idToArbitraryFiberMap.get(id);
let fiber: ?Fiber = idToArbitraryFiberMap.get(id);
if (fiber == null) {
return null;
}
const keyPath = [];
while (fiber !== null) {
// $FlowFixMe[incompatible-call] found when upgrading Flow
keyPath.push(getPathFrame(fiber));
// $FlowFixMe[incompatible-use] found when upgrading Flow
fiber = fiber.return;
}
keyPath.reverse();
Expand All @@ -4443,7 +4451,7 @@ export function attach(
return null;
}
// Find the closest Fiber store is aware of.
let fiber = trackedPathMatchFiber;
let fiber: null | Fiber = trackedPathMatchFiber;
while (fiber !== null && shouldFilterFiber(fiber)) {
fiber = fiber.return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ function findTipPos(dims, bounds, tipSize) {
const tipWidth = Math.max(tipSize.width, 60);
const margin = 5;

let top;
let top: number | string;
if (dims.top + dims.height + tipHeight <= bounds.top + bounds.height) {
if (dims.top + dims.height < bounds.top + 0) {
top = bounds.top + margin;
Expand All @@ -299,7 +299,7 @@ function findTipPos(dims, bounds, tipSize) {
top = bounds.top + bounds.height - tipHeight - margin;
}

let left = dims.left + margin;
let left: number | string = dims.left + margin;
if (dims.left < bounds.left) {
left = bounds.left + margin;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-shared/src/backend/views/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function getNestedBoundingClientRect(
const ownerIframe = getOwnerIframe(node);
if (ownerIframe && ownerIframe !== boundaryWindow) {
const rects = [node.getBoundingClientRect()];
let currentIframe = ownerIframe;
let currentIframe: null | HTMLElement = ownerIframe;
let onlyOneMore = false;
while (currentIframe) {
const rect = getBoundingClientRectWithBorderOffset(currentIframe);
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-shared/src/devtools/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const resourceConfigs: Map<Resource<any, any, any>, Config> = new Map();
function getEntriesForResource(
resource: any,
): Map<any, any> | WeakMap<any, any> {
let entriesForResource = ((entries.get(resource): any): Map<any, any>);
let entriesForResource: Map<any, any> | WeakMap<any, any> = ((entries.get(resource): any): Map<any, any>);
if (entriesForResource === undefined) {
const config = resourceConfigs.get(resource);
entriesForResource =
Expand Down
6 changes: 4 additions & 2 deletions packages/react-devtools-shared/src/devtools/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ export default class Store extends EventEmitter<{

const weightDelta = 1 - element.weight;

let parentElement = ((this._idToElement.get(
let parentElement: void | Element = ((this._idToElement.get(
element.parentID,
): any): Element);
while (parentElement != null) {
Expand All @@ -789,7 +789,7 @@ export default class Store extends EventEmitter<{
: currentElement.weight;
const weightDelta = newWeight - oldWeight;

let parentElement = ((this._idToElement.get(
let parentElement: void | Element = ((this._idToElement.get(
currentElement.parentID,
): any): Element);
while (parentElement != null) {
Expand All @@ -806,7 +806,9 @@ export default class Store extends EventEmitter<{

currentElement =
currentElement.parentID !== 0
// $FlowFixMe[incompatible-type] found when upgrading Flow
? this.getElementByID(currentElement.parentID)
// $FlowFixMe[incompatible-type] found when upgrading Flow
: null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ const resource: Resource<
return request.promise;
}

let resolveFn = ((null: any): ResolveFn);
let resolveFn:
| ResolveFn
| ((result: Promise<StyleAndLayoutFrontend> | StyleAndLayoutFrontend) => void) = ((null: any): ResolveFn);
const promise = new Promise(resolve => {
resolveFn = resolve;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function NewKeyValue({
const {id} = inspectedElement;
const rendererID = store.getRendererIDForElement(id);
if (rendererID !== null) {
let basePath = newPath;
let basePath: Array<string | number> = newPath;
if (hookID != null) {
basePath = parseHookPathForEdit(basePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ const resource: Resource<
return request.promise;
}

let resolveFn = ((null: any): ResolveFn);
let resolveFn:
| ResolveFn
| ((
result: Promise<Array<SerializedElement>> | Array<SerializedElement>
) => void) = ((null: any): ResolveFn);
const promise = new Promise(resolve => {
resolveFn = resolve;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

import * as React from 'react';
import type { Element } from './types';import * as React from 'react';
import {useContext, useMemo} from 'react';
import {TreeStateContext} from './TreeContext';
import {SettingsContext} from '../Settings/SettingsContext';
Expand Down Expand Up @@ -53,7 +53,7 @@ export default function SelectedTreeHighlight(_: {}): React.Node {
}

let stopIndex = null;
let current = element;
let current: null | Element = element;
while (current !== null) {
if (current.isCollapsed || current.children.length === 0) {
// We've found the last/deepest descendant.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ function reduceTreeState(store: Store, state: State, action: Action): State {
) {
const leafElement = store.getElementByID(ownerSubtreeLeafElementID);
if (leafElement !== null) {
let currentElement = leafElement;
let currentElement: null | Element = leafElement;
while (currentElement !== null) {
if (currentElement.ownerID === selectedElementID) {
selectedElementIndex = store.getIndexOfElementID(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ const TOOLTIP_OFFSET = 5;
// Method used to find the position of the tooltip based on current mouse position
function getTooltipPosition(element, mousePosition) {
const {height, mouseX, mouseY, width} = mousePosition;
let top = 0;
let left = 0;
let top: number | string = 0;
let left: number | string = 0;

if (mouseY + TOOLTIP_OFFSET + element.offsetHeight >= height) {
if (mouseY - TOOLTIP_OFFSET - element.offsetHeight > 0) {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-shared/src/devtools/views/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export function useModalDismissSignal(
// Delay until after the current call stack is empty,
// in case this effect is being run while an event is currently bubbling.
// In that case, we don't want to listen to the pre-existing event.
let timeoutID = setTimeout(() => {
let timeoutID: null | TimeoutID = setTimeout(() => {
timeoutID = null;

// It's important to listen to the ownerDocument to support the browser extension.
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-shared/src/dynamicImportCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export function loadModule(moduleLoaderFunction: ModuleLoaderFunction): Module {
);

// Eventually timeout and stop trying to load the module.
let timeoutID = setTimeout(function onTimeout() {
let timeoutID: null | TimeoutID = setTimeout(function onTimeout() {
if (__DEBUG__) {
console.log(
`[dynamicImportCache] loadModule("${moduleLoaderFunction.name}") onTimeout()`,
Expand Down
Loading

0 comments on commit 647263a

Please sign in to comment.