Enable no-use-before-define rule (#13606)
Dan Abramov committed
Sep 10, 2018 at 16:15 UTC
144328fe81719e916b946e22660479e31561bb0b
9 files changed
+109
-94
.eslintrc.js
+1
@@ -37,6 +37,7 @@ module.exports = {
37
'no-shadow': ERROR,
38
'no-unused-expressions': ERROR,
39
'no-unused-vars': [ERROR, {args: 'none'}],
40
+ 'no-use-before-define': [ERROR, {functions: false, variables: false}],
41
'no-useless-concat': OFF,
42
'quotes': [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true }],
43
'space-before-blocks': ERROR,
packages/react-dom/src/client/ReactDOM.js
+15
-13
@@ -126,6 +126,7 @@ if (__DEV__) {
126
127
ReactControlledComponent.setRestoreImplementation(restoreControlledState);
128
129
+/* eslint-disable no-use-before-define */
130
type DOMContainer =
131
| (Element & {
132
_reactRootContainer: ?Root,
@@ -150,6 +151,20 @@ type Batch = FiberRootBatch & {
151
_didComplete: boolean,
152
};
153
154
+type Root = {
155
+ render(children: ReactNodeList, callback: ?() => mixed): Work,
156
+ unmount(callback: ?() => mixed): Work,
157
+ legacy_renderSubtreeIntoContainer(
158
+ parentComponent: ?React$Component<any, any>,
159
+ children: ReactNodeList,
160
+ callback: ?() => mixed,
161
+ ): Work,
162
+ createBatch(): Batch,
163
+
164
+ _internalRoot: FiberRoot,
165
+};
166
+/* eslint-enable no-use-before-define */
167
+
168
function ReactBatch(root: ReactRoot) {
169
const expirationTime = DOMRenderer.computeUniqueAsyncExpiration();
170
this._expirationTime = expirationTime;
@@ -317,19 +332,6 @@ ReactWork.prototype._onCommit = function(): void {
332
}
333
};
334
320
-type Root = {
321
- render(children: ReactNodeList, callback: ?() => mixed): Work,
322
- unmount(callback: ?() => mixed): Work,
323
- legacy_renderSubtreeIntoContainer(
324
- parentComponent: ?React$Component<any, any>,
325
- children: ReactNodeList,
326
- callback: ?() => mixed,
327
- ): Work,
328
- createBatch(): Batch,
329
-
330
- _internalRoot: FiberRoot,
331
-};
332
-
335
function ReactRoot(container: Container, isAsync: boolean, hydrate: boolean) {
336
const root = DOMRenderer.createContainer(container, isAsync, hydrate);
337
this._internalRoot = root;
packages/react-native-renderer/src/ReactFabricHostConfig.js
+2
@@ -50,6 +50,7 @@ import UIManager from 'UIManager';
50
// This means that they never overlap.
51
let nextReactTag = 2;
52
53
+/* eslint-disable no-use-before-define */
54
type Node = Object;
55
export type Type = string;
56
export type Props = Object;
@@ -71,6 +72,7 @@ export type UpdatePayload = Object;
72
73
export type TimeoutHandle = TimeoutID;
74
export type NoTimeout = -1;
75
+/* eslint-enable no-use-before-define */
76
77
// TODO: Remove this conditional once all changes have propagated.
78
if (registerEventHandler) {
packages/react-noop-renderer/src/createReactNoop.js
+2
@@ -21,6 +21,7 @@ import type {ReactNodeList} from 'shared/ReactTypes';
21
import * as ReactPortal from 'shared/ReactPortal';
22
import expect from 'expect';
23
24
+/* eslint-disable no-use-before-define */
25
type Container = {rootID: string, children: Array<Instance | TextInstance>};
26
type Props = {prop: any, hidden?: boolean, children?: mixed};
27
type Instance = {|
@@ -30,6 +31,7 @@ type Instance = {|
31
prop: any,
32
|};
33
type TextInstance = {|text: string, id: number|};
34
+/* eslint-enable no-use-before-define */
35
36
const NO_CONTEXT = {};
37
const UPDATE_SIGNAL = {};
packages/react-reconciler/src/ReactFiberRoot.js
+2
@@ -18,6 +18,7 @@ import {NoWork} from './ReactFiberExpirationTime';
18
import {enableSchedulerTracking} from 'shared/ReactFeatureFlags';
19
import {unstable_getThreadID} from 'schedule/tracking';
20
21
+/* eslint-disable no-use-before-define */
22
// TODO: This should be lifted into the renderer.
23
export type Batch = {
24
_defer: boolean,
@@ -98,6 +99,7 @@ export type FiberRoot = {
99
...BaseFiberRootProperties,
100
...ProfilingOnlyFiberRootProperties,
101
};
102
+/* eslint-enable no-use-before-define */
103
104
export function createFiberRoot(
105
containerInfo: any,
packages/react-test-renderer/src/ReactShallowRenderer.js
+66
-66
@@ -19,6 +19,72 @@ if (__DEV__) {
19
Object.freeze(emptyObject);
20
}
21
22
+class Updater {
23
+ constructor(renderer) {
24
+ this._renderer = renderer;
25
+ this._callbacks = [];
26
+ }
27
+
28
+ _enqueueCallback(callback, publicInstance) {
29
+ if (typeof callback === 'function' && publicInstance) {
30
+ this._callbacks.push({
31
+ callback,
32
+ publicInstance,
33
+ });
34
+ }
35
+ }
36
+
37
+ _invokeCallbacks() {
38
+ const callbacks = this._callbacks;
39
+ this._callbacks = [];
40
+
41
+ callbacks.forEach(({callback, publicInstance}) => {
42
+ callback.call(publicInstance);
43
+ });
44
+ }
45
+
46
+ isMounted(publicInstance) {
47
+ return !!this._renderer._element;
48
+ }
49
+
50
+ enqueueForceUpdate(publicInstance, callback, callerName) {
51
+ this._enqueueCallback(callback, publicInstance);
52
+ this._renderer._forcedUpdate = true;
53
+ this._renderer.render(this._renderer._element, this._renderer._context);
54
+ }
55
+
56
+ enqueueReplaceState(publicInstance, completeState, callback, callerName) {
57
+ this._enqueueCallback(callback, publicInstance);
58
+ this._renderer._newState = completeState;
59
+ this._renderer.render(this._renderer._element, this._renderer._context);
60
+ }
61
+
62
+ enqueueSetState(publicInstance, partialState, callback, callerName) {
63
+ this._enqueueCallback(callback, publicInstance);
64
+ const currentState = this._renderer._newState || publicInstance.state;
65
+
66
+ if (typeof partialState === 'function') {
67
+ partialState = partialState.call(
68
+ publicInstance,
69
+ currentState,
70
+ publicInstance.props,
71
+ );
72
+ }
73
+
74
+ // Null and undefined are treated as no-ops.
75
+ if (partialState === null || partialState === undefined) {
76
+ return;
77
+ }
78
+
79
+ this._renderer._newState = {
80
+ ...currentState,
81
+ ...partialState,
82
+ };
83
+
84
+ this._renderer.render(this._renderer._element, this._renderer._context);
85
+ }
86
+}
87
+
88
class ReactShallowRenderer {
89
static createRenderer = function() {
90
return new ReactShallowRenderer();
@@ -263,72 +329,6 @@ class ReactShallowRenderer {
329
}
330
}
331
266
-class Updater {
267
- constructor(renderer) {
268
- this._renderer = renderer;
269
- this._callbacks = [];
270
- }
271
-
272
- _enqueueCallback(callback, publicInstance) {
273
- if (typeof callback === 'function' && publicInstance) {
274
- this._callbacks.push({
275
- callback,
276
- publicInstance,
277
- });
278
- }
279
- }
280
-
281
- _invokeCallbacks() {
282
- const callbacks = this._callbacks;
283
- this._callbacks = [];
284
-
285
- callbacks.forEach(({callback, publicInstance}) => {
286
- callback.call(publicInstance);
287
- });
288
- }
289
-
290
- isMounted(publicInstance) {
291
- return !!this._renderer._element;
292
- }
293
-
294
- enqueueForceUpdate(publicInstance, callback, callerName) {
295
- this._enqueueCallback(callback, publicInstance);
296
- this._renderer._forcedUpdate = true;
297
- this._renderer.render(this._renderer._element, this._renderer._context);
298
- }
299
-
300
- enqueueReplaceState(publicInstance, completeState, callback, callerName) {
301
- this._enqueueCallback(callback, publicInstance);
302
- this._renderer._newState = completeState;
303
- this._renderer.render(this._renderer._element, this._renderer._context);
304
- }
305
-
306
- enqueueSetState(publicInstance, partialState, callback, callerName) {
307
- this._enqueueCallback(callback, publicInstance);
308
- const currentState = this._renderer._newState || publicInstance.state;
309
-
310
- if (typeof partialState === 'function') {
311
- partialState = partialState.call(
312
- publicInstance,
313
- currentState,
314
- publicInstance.props,
315
- );
316
- }
317
-
318
- // Null and undefined are treated as no-ops.
319
- if (partialState === null || partialState === undefined) {
320
- return;
321
- }
322
-
323
- this._renderer._newState = {
324
- ...currentState,
325
- ...partialState,
326
- };
327
-
328
- this._renderer.render(this._renderer._element, this._renderer._context);
329
- }
330
-}
331
-
332
let currentlyValidatingElement = null;
333
334
function getDisplayName(element) {
packages/react-test-renderer/src/ReactTestHostConfig.js
+2
@@ -10,6 +10,7 @@
10
import warning from 'shared/warning';
11
import * as TestRendererScheduling from './ReactTestRendererScheduling';
12
13
+/* eslint-disable no-use-before-define */
14
export type Type = string;
15
export type Props = Object;
16
export type Container = {|
@@ -35,6 +36,7 @@ export type UpdatePayload = Object;
36
export type ChildSet = void; // Unused
37
export type TimeoutHandle = TimeoutID;
38
export type NoTimeout = -1;
39
+/* eslint-enable no-use-before-define */
40
41
export * from 'shared/HostConfigWithNoPersistence';
42
export * from 'shared/HostConfigWithNoHydration';
packages/react-test-renderer/src/ReactTestRenderer.js
+15
-13
@@ -37,6 +37,7 @@ import ReactVersion from 'shared/ReactVersion';
37
import * as ReactTestHostConfig from './ReactTestHostConfig';
38
import * as TestRendererScheduling from './ReactTestRendererScheduling';
39
40
+/* eslint-disable no-use-before-define */
41
type TestRendererOptions = {
42
createNodeMock: (element: React$Element<any>) => any,
43
unstable_isAsync: boolean,
@@ -57,6 +58,7 @@ type FindOptions = $Shape<{
58
}>;
59
60
export type Predicate = (node: ReactTestInstance) => ?boolean;
61
+/* eslint-enable no-use-before-define */
62
63
const defaultTestOptions = {
64
createNodeMock: function() {
@@ -209,19 +211,6 @@ function toTree(node: ?Fiber) {
211
}
212
}
213
212
-const fiberToWrapper = new WeakMap();
213
-function wrapFiber(fiber: Fiber): ReactTestInstance {
214
- let wrapper = fiberToWrapper.get(fiber);
215
- if (wrapper === undefined && fiber.alternate !== null) {
216
- wrapper = fiberToWrapper.get(fiber.alternate);
217
- }
218
- if (wrapper === undefined) {
219
- wrapper = new ReactTestInstance(fiber);
220
- fiberToWrapper.set(fiber, wrapper);
221
- }
222
- return wrapper;
223
-}
224
-
214
const validWrapperTypes = new Set([
215
FunctionalComponent,
216
FunctionalComponentLazy,
@@ -543,6 +532,19 @@ const ReactTestRendererFiber = {
532
unstable_setNowImplementation: TestRendererScheduling.setNowImplementation,
533
};
534
535
+const fiberToWrapper = new WeakMap();
536
+function wrapFiber(fiber: Fiber): ReactTestInstance {
537
+ let wrapper = fiberToWrapper.get(fiber);
538
+ if (wrapper === undefined && fiber.alternate !== null) {
539
+ wrapper = fiberToWrapper.get(fiber.alternate);
540
+ }
541
+ if (wrapper === undefined) {
542
+ wrapper = new ReactTestInstance(fiber);
543
+ fiberToWrapper.set(fiber, wrapper);
544
+ }
545
+ return wrapper;
546
+}
547
+
548
// Enable ReactTestRenderer to be used to test DevTools integration.
549
TestRenderer.injectIntoDevTools({
550
findFiberByHostInstance: (() => {
packages/shared/ReactTypes.js
+4
-2
@@ -7,6 +7,7 @@
7
* @flow
8
*/
9
10
+/* eslint-disable no-use-before-define */
11
export type ReactNode =
12
| React$Element<any>
13
| ReactPortal
@@ -14,6 +15,9 @@ export type ReactNode =
15
| ReactFragment
16
| ReactProvider<any>
17
| ReactConsumer<any>;
18
+/* eslint-enable no-use-before-define */
19
+
20
+export type ReactEmpty = null | void | boolean;
21
22
export type ReactFragment = ReactEmpty | Iterable<React$Node>;
23
@@ -21,8 +25,6 @@ export type ReactNodeList = ReactEmpty | React$Node;
25
26
export type ReactText = string | number;
27
24
-export type ReactEmpty = null | void | boolean;
25
-
28
export type ReactProvider<T> = {
29
$$typeof: Symbol | number,
30
type: ReactProviderType<T>,