28
29
type Dependency = {
30
isStable: boolean;
31
- references: Scope.Reference[];
31
+ references: Array<Scope.Reference>;
32
};
33
34
type DependencyTreeNode = {
184
// Get the current scope.
185
const scope = scopeManager.acquire(node);
186
if (!scope) {
187
- return;
187
+ throw new Error(
188
+ 'Unable to acquire scope for the current node. This is a bug in eslint-plugin-react-hooks, please file an issue.',
189
+ );
190
}
191
192
// Find all our "pure scopes". On every re-render of a component these
257
// Detect primitive constants
258
// const foo = 42
259
let declaration = defNode.parent;
258
- if (declaration == null && componentScope) {
260
+ if (declaration == null && componentScope != null) {
261
// This might happen if variable is declared after the callback.
262
// In that case ESLint won't set up .parent refs.
263
// So we'll set them up manually.
268
}
269
}
270
if (
269
- declaration &&
271
+ declaration != null &&
272
'kind' in declaration &&
273
declaration.kind === 'const' &&
274
init.type === 'Literal' &&
456
function isInsideEffectCleanup(reference: Scope.Reference): boolean {
457
let curScope: Scope.Scope | null = reference.from;
458
let isInReturnedFunction = false;
457
- while (curScope && curScope.block !== node) {
459
+ while (curScope != null && curScope.block !== node) {
460
if (curScope.type === 'function') {
461
isInReturnedFunction =
462
curScope.block.parent != null &&
531
continue;
532
}
533
// Ignore references to the function itself as it's not defined yet.
532
- if (def.node && def.node.init === node.parent) {
534
+ if (def.node != null && def.node.init === node.parent) {
535
continue;
536
}
537
// Ignore Flow type parameters
568
// Is React managing this ref or us?
569
// Let's see if we can find a .current assignment.
570
let foundCurrentAssignment = false;
569
- for (const reference of references) {
570
- const {identifier} = reference;
571
+ for (const ref of references) {
572
+ const {identifier} = ref;
573
const {parent} = identifier;
574
if (
575
parent != null &&
662
}
663
664
let fnScope: Scope.Scope | null = reference.from;
663
- while (fnScope && fnScope.type !== 'function') {
665
+ while (fnScope != null && fnScope.type !== 'function') {
666
fnScope = fnScope.upper;
667
}
668
const isDirectlyInsideEffect = fnScope?.block === node;
706
return;
707
}
708
707
- const declaredDependencies: DeclaredDependency[] = [];
709
+ const declaredDependencies: Array<DeclaredDependency> = [];
710
const externalDependencies = new Set<string>();
711
const isArrayExpression =
712
declaredDependenciesNode.type === 'ArrayExpression';
1471
isEffect,
1472
}: {
1473
dependencies: Map<string, Dependency>;
1472
- declaredDependencies: DeclaredDependency[];
1474
+ declaredDependencies: Array<DeclaredDependency>;
1475
stableDependencies: Set<string>;
1476
externalDependencies: Set<string>;
1477
isEffect: boolean;
1594
}
1595
1596
// Collect suggestions in the order they were originally specified.
1595
- const suggestedDependencies: string[] = [];
1597
+ const suggestedDependencies: Array<string> = [];
1598
const unnecessaryDependencies = new Set<string>();
1599
const duplicateDependencies = new Set<string>();
1600
declaredDependencies.forEach(({key}) => {
1701
componentScope,
1702
scope,
1703
}: {
1702
- declaredDependencies: DeclaredDependency[];
1704
+ declaredDependencies: Array<DeclaredDependency>;
1705
declaredDependenciesNode: Node;
1706
componentScope: Scope.Scope;
1707
scope: Scope.Scope;
1749
}
1750
return null;
1751
})
1750
- .filter(Boolean) as [Scope.Variable, string][];
1752
+ .filter(Boolean) as Array<[Scope.Variable, string]>;
1753
1754
function isUsedOutsideOfHook(ref: Scope.Variable): boolean {
1755
let foundWriteExpr = false;
2009
return null;
2010
}
2011
2010
-function joinEnglish(arr: string[]): string {
2012
+function joinEnglish(arr: Array<string>): string {
2013
let s = '';
2014
for (let i = 0; i < arr.length; i++) {
2015
s += arr[i];