eslint-plugin-react-hooks 4.0.3 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,20 @@ npm install eslint-plugin-react-hooks --save-dev
18
18
  yarn add eslint-plugin-react-hooks --dev
19
19
  ```
20
20
 
21
- Then add it to your ESLint configuration:
21
+ Then extend the recommended eslint config:
22
+
23
+ ```js
24
+ {
25
+ "extends": [
26
+ // ...
27
+ "plugin:react-hooks/recommended"
28
+ ]
29
+ }
30
+ ```
31
+
32
+ ### Custom Configuration
33
+
34
+ If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:
22
35
 
23
36
  ```js
24
37
  {
@@ -34,16 +47,6 @@ Then add it to your ESLint configuration:
34
47
  }
35
48
  ```
36
49
 
37
- Or use the recommended config:
38
-
39
- ```js
40
- {
41
- "extends": [
42
- // ...
43
- "plugin:react-hooks/recommended"
44
- ]
45
- }
46
- ```
47
50
 
48
51
  ## Valid and Invalid Examples
49
52
 
@@ -1883,7 +1883,7 @@ function collectRecommendations(_ref5) {
1883
1883
  try {
1884
1884
  for (var _iterator3 = keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
1885
1885
  var key = _step3.value;
1886
- var child = node.children.get(key);
1886
+ var child = getChildByKey(node, key);
1887
1887
 
1888
1888
  if (!child) {
1889
1889
  child = createDepTree();
@@ -1920,7 +1920,7 @@ function collectRecommendations(_ref5) {
1920
1920
  try {
1921
1921
  for (var _iterator4 = keys[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
1922
1922
  var key = _step4.value;
1923
- var child = node.children.get(key);
1923
+ var child = getChildByKey(node, key);
1924
1924
 
1925
1925
  if (!child) {
1926
1926
  return;
@@ -1943,6 +1943,18 @@ function collectRecommendations(_ref5) {
1943
1943
  }
1944
1944
  }
1945
1945
  }
1946
+ }
1947
+ /**
1948
+ * Match key with optional chaining
1949
+ * key -> key
1950
+ * key? -> key
1951
+ * key -> key?
1952
+ * Otherwise undefined.
1953
+ */
1954
+
1955
+
1956
+ function getChildByKey(node, key) {
1957
+ return node.children.get(key) || node.children.get(key.split('?')[0]) || node.children.get(key + '?');
1946
1958
  } // Now we can learn which dependencies are missing or necessary.
1947
1959
 
1948
1960
 
@@ -7,51 +7,51 @@
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
9
 
10
- 'use strict';function M(a){if("Identifier"===a.type)return/^use[A-Z0-9].*$/.test(a.name);if("MemberExpression"===a.type&&!a.computed&&M(a.property)){a=a.object;var c=/^[A-Z].*/;return"Identifier"===a.type&&c.test(a.name)}return!1}function aa(a){return"Identifier"===a.type?!/^[a-z]/.test(a.name):!1}function ba(a,c){return a.name===c||"MemberExpression"===a.type&&"React"===a.object.name&&a.property.name===c}function ea(a){return!!(a.parent&&a.parent.callee&&ba(a.parent.callee,"forwardRef"))}
11
- function fa(a){return!!(a.parent&&a.parent.callee&&ba(a.parent.callee,"memo"))}function ha(a){for(;a;){var c=ia(a);if(c&&(aa(c)||M(c))||ea(a)||fa(a))return!0;a=a.parent}return!1}
12
- function ia(a){if("FunctionDeclaration"===a.type||"FunctionExpression"===a.type&&a.id)return a.id;if("FunctionExpression"===a.type||"ArrowFunctionExpression"===a.type)return"VariableDeclarator"===a.parent.type&&a.parent.init===a?a.parent.id:"AssignmentExpression"===a.parent.type&&a.parent.right===a&&"="===a.parent.operator?a.parent.left:"Property"!==a.parent.type||a.parent.value!==a||a.parent.computed?"AssignmentPattern"!==a.parent.type||a.parent.right!==a||a.parent.computed?void 0:a.parent.left:
10
+ 'use strict';function L(a){if("Identifier"===a.type)return/^use[A-Z0-9].*$/.test(a.name);if("MemberExpression"===a.type&&!a.computed&&L(a.property)){a=a.object;var c=/^[A-Z].*/;return"Identifier"===a.type&&c.test(a.name)}return!1}function ba(a){return"Identifier"===a.type?!/^[a-z]/.test(a.name):!1}function ca(a,c){return a.name===c||"MemberExpression"===a.type&&"React"===a.object.name&&a.property.name===c}function fa(a){return!!(a.parent&&a.parent.callee&&ca(a.parent.callee,"forwardRef"))}
11
+ function ha(a){return!!(a.parent&&a.parent.callee&&ca(a.parent.callee,"memo"))}function ia(a){for(;a;){var c=ja(a);if(c&&(ba(c)||L(c))||fa(a)||ha(a))return!0;a=a.parent}return!1}
12
+ function ja(a){if("FunctionDeclaration"===a.type||"FunctionExpression"===a.type&&a.id)return a.id;if("FunctionExpression"===a.type||"ArrowFunctionExpression"===a.type)return"VariableDeclarator"===a.parent.type&&a.parent.init===a?a.parent.id:"AssignmentExpression"===a.parent.type&&a.parent.right===a&&"="===a.parent.operator?a.parent.left:"Property"!==a.parent.type||a.parent.value!==a||a.parent.computed?"AssignmentPattern"!==a.parent.type||a.parent.right!==a||a.parent.computed?void 0:a.parent.left:
13
13
  a.parent.key}
14
- function ja(a){function c(){return{isRequired:!1,isSatisfiedRecursively:!1,hasRequiredNodesBelow:!1,children:new Map}}function b(a,d){d=d.split(".");var k=!0,f=!1,h=void 0;try{for(var e=d[Symbol.iterator](),b;!(k=(b=e.next()).done);k=!0){var n=b.value,z=a.children.get(n);z||(z=c(),a.children.set(n,z));a=z}}catch(G){f=!0,h=G}finally{try{k||null==e.return||e.return()}finally{if(f)throw h;}}return a}function e(a,c,d){c=c.split(".");var k=!0,f=!1,h=void 0;try{for(var e=c[Symbol.iterator](),b;!(k=
15
- (b=e.next()).done);k=!0){var z=a.children.get(b.value);if(!z)break;d(z);a=z}}catch(G){f=!0,h=G}finally{try{k||null==e.return||e.return()}finally{if(f)throw h;}}}function f(a,c,d,h){a.children.forEach(function(a,k){var e=h(k);a.isSatisfiedRecursively?a.hasRequiredNodesBelow&&d.add(e):a.isRequired?c.add(e):f(a,c,d,function(a){return e+"."+a})})}var C=a.dependencies,p=a.declaredDependencies,u=a.optionalDependencies,x=a.externalDependencies,y=a.isEffect,H=c();C.forEach(function(a,c){b(H,c).isRequired=
16
- !0;e(H,c,function(a){a.hasRequiredNodesBelow=!0})});p.forEach(function(a){b(H,a.key).isSatisfiedRecursively=!0});u.forEach(function(a){b(H,a).isSatisfiedRecursively=!0});a=new Set;var h=new Set;f(H,a,h,function(a){return a});var d=[],z=new Set,A=new Set;p.forEach(function(a){a=a.key;h.has(a)?-1===d.indexOf(a)?d.push(a):A.add(a):!y||a.endsWith(".current")||x.has(a)?z.add(a):-1===d.indexOf(a)&&d.push(a)});a.forEach(function(a){d.push(a)});return{suggestedDependencies:d,unnecessaryDependencies:z,duplicateDependencies:A,
17
- missingDependencies:a}}
18
- function ka(a){var c=a.declaredDependenciesNode,b=a.componentScope,e=a.scope;return a.declaredDependencies.map(function(a){a=b.set.get(a.key);if(null==a)return null;var c=a.defs[0];return null==c?null:"Variable"===c.type&&"VariableDeclarator"===c.node.type&&null!=c.node.init&&("ArrowFunctionExpression"===c.node.init.type||"FunctionExpression"===c.node.init.type)||"FunctionName"===c.type&&"FunctionDeclaration"===c.node.type?a:null}).filter(Boolean).map(function(a){var b=a.defs[0];a:{for(var f=!1,u=
19
- 0;u<a.references.length;u++){var x=a.references[u];if(x.writeExpr)if(f){a=!0;break a}else{f=!0;continue}for(var y=x.from;y!==e&&null!=y;)y=y.upper;if(y!==e&&!la(c,x.identifier)){a=!0;break a}}a=!1}return{fn:b,suggestUseCallback:a}})}
20
- function ma(a){return"MemberExpression"!==a.parent.type&&"OptionalMemberExpression"!==a.parent.type||a.parent.object!==a||"current"===a.parent.property.name||a.parent.computed||null!=a.parent.parent&&"CallExpression"===a.parent.parent.type&&a.parent.parent.callee===a.parent?"MemberExpression"===a.type&&a.parent&&"AssignmentExpression"===a.parent.type?a.object:a:ma(a.parent)}
21
- function Y(a){if("Identifier"===a.type)return a.name;if("MemberExpression"!==a.type||a.computed){if("OptionalMemberExpression"!==a.type||a.computed)throw Error("Unsupported node type: "+a.type);var c=Y(a.object);a=Y(a.property);return c+"?."+a}c=Y(a.object);a=Y(a.property);return c+"."+a}function na(a){return"MemberExpression"!==a.type||"Identifier"!==a.object.type||"React"!==a.object.name||"Identifier"!==a.property.type||a.computed?a:a.property}
22
- function pa(a,c){var b=na(a);if("Identifier"!==b.type)return-1;switch(b.name){case "useEffect":case "useLayoutEffect":case "useCallback":case "useMemo":return 0;case "useImperativeHandle":return 1;default:if(b===a&&c&&c.additionalHooks){try{var e=Y(b)}catch(f){if(/Unsupported node type/.test(f.message))return 0;throw f;}return c.additionalHooks.test(e)?0:-1}return-1}}
23
- function qa(a,c){for(var b=[a],e=null;b.length;){e=b.shift();if("Identifier"===e.type&&e.name===c.name&&e.range[0]===c.range[0]&&e.range[1]===c.range[1])return e;if(la(e,c)){a=0;for(var f=Object.entries(e);a<f.length;a++){var C=f[a],p=C[1];"parent"!==C[0]&&(ra(p)?(p.parent=e,b.push(p)):Array.isArray(p)&&p.forEach(function(a){ra(a)&&(a.parent=e,b.push(a))}))}}}return null}
24
- function sa(a){for(var c="",b=0;b<a.length;b++)c+=a[b],0===b&&2===a.length?c+=" and ":b===a.length-2&&2<a.length?c+=", and ":b<a.length-1&&(c+=", ");return c}function ra(a){return"object"===typeof a&&null!==a&&!Array.isArray(a)&&"string"===typeof a.type}function la(a,c){return a.range[0]<=c.range[0]&&a.range[1]>=c.range[1]}exports.configs={recommended:{plugins:["react-hooks"],rules:{"react-hooks/rules-of-hooks":"error","react-hooks/exhaustive-deps":"warn"}}};
25
- exports.rules={"rules-of-hooks":{meta:{type:"problem",docs:{description:"enforces the Rules of Hooks",category:"Possible Errors",recommended:!0,url:"https://reactjs.org/docs/hooks-rules.html"}},create:function(a){var c=[],b=[];return{onCodePathSegmentStart:function(a){return b.push(a)},onCodePathSegmentEnd:function(){return b.pop()},onCodePathStart:function(){return c.push(new Map)},onCodePathEnd:function(e,b){function f(a,c){var b=f.cache,d=b.get(a.id);c=new Set(c);if(c.has(a.id)){b=[].concat(c);
26
- a=b.slice(b.indexOf(a.id)+1);b=!0;d=!1;var g=void 0;try{for(var m=a[Symbol.iterator](),B;!(b=(B=m.next()).done);b=!0)y.add(B.value)}catch(I){d=!0,g=I}finally{try{b||null==m.return||m.return()}finally{if(d)throw g;}}return 0}c.add(a.id);if(void 0!==d)return d;if(e.thrownSegments.includes(a))d=0;else if(0===a.prevSegments.length)d=1;else{d=0;m=!0;B=!1;var K=void 0;try{g=a.prevSegments[Symbol.iterator]();for(var h;!(m=(h=g.next()).done);m=!0)d+=f(h.value,c)}catch(I){B=!0,K=I}finally{try{m||null==
27
- g.return||g.return()}finally{if(B)throw K;}}}a.reachable&&0===d?b.delete(a.id):b.set(a.id,d);return d}function p(a,c){var d=p.cache,b=d.get(a.id);c=new Set(c);if(c.has(a.id)){d=Array.from(c);a=d.slice(d.indexOf(a.id)+1);d=!0;b=!1;var g=void 0;try{for(var m=a[Symbol.iterator](),B;!(d=(B=m.next()).done);d=!0)y.add(B.value)}catch(I){b=!0,g=I}finally{try{d||null==m.return||m.return()}finally{if(b)throw g;}}return 0}c.add(a.id);if(void 0!==b)return b;if(e.thrownSegments.includes(a))b=0;else if(0===
28
- a.nextSegments.length)b=1;else{b=0;m=!0;B=!1;var K=void 0;try{g=a.nextSegments[Symbol.iterator]();for(var h;!(m=(h=g.next()).done);m=!0)b+=p(h.value,c)}catch(I){B=!0,K=I}finally{try{m||null==g.return||g.return()}finally{if(B)throw K;}}}d.set(a.id,b);return b}function u(a){var c=u.cache,b=c.get(a.id);if(null===b)return Infinity;if(void 0!==b)return b;c.set(a.id,null);if(0===a.prevSegments.length)b=1;else{b=Infinity;var d=!0,g=!1,m=void 0;try{for(var B=a.prevSegments[Symbol.iterator](),K;!(d=
29
- (K=B.next()).done);d=!0){var h=u(K.value);h<b&&(b=h)}}catch(I){g=!0,m=I}finally{try{d||null==B.return||B.return()}finally{if(g)throw m;}}b+=1}c.set(a.id,b);return b}var x=c.pop();if(0!==x.size){var y=new Set;f.cache=new Map;p.cache=new Map;u.cache=new Map;var H=p(e.initialSegment),h=ia(b),d=ha(b),z=h?aa(h)||M(h):ea(b)||fa(b),A=Infinity,k=!0,n=!1,T=void 0;try{for(var q=e.finalSegments[Symbol.iterator](),U;!(k=(U=q.next()).done);k=!0){var D=U.value;if(D.reachable){var w=u(D);w<A&&(A=w)}}}catch(F){n=
30
- !0,T=F}finally{try{k||null==q.return||q.return()}finally{if(n)throw T;}}k=!0;n=!1;T=void 0;try{for(var P=x[Symbol.iterator](),Z;!(k=(Z=P.next()).done);k=!0){var G=Z.value,t=G[0],W=G[1];if(t.reachable){var Q=0===t.nextSegments.length?A<=u(t):A<u(t),N=f(t)*p(t),L=y.has(t.id);x=!0;q=!1;U=void 0;try{for(var l=W[Symbol.iterator](),E;!(x=(E=l.next()).done);x=!0){var v=E.value;L&&a.report({node:v,message:'React Hook "'+a.getSource(v)+'" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.'});
31
- if(z){if(!L&&N!==H){var R='React Hook "'+a.getSource(v)+'" is called conditionally. React Hooks must be called in the exact same order in every component render.'+(Q?" Did you accidentally call a React Hook after an early return?":"");a.report({node:v,message:R})}}else if(b.parent&&("MethodDefinition"===b.parent.type||"ClassProperty"===b.parent.type)&&b.parent.value===b){var S='React Hook "'+a.getSource(v)+'" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.';
32
- a.report({node:v,message:S})}else if(h){var J='React Hook "'+a.getSource(v)+'" is called in function "'+(a.getSource(h)+'" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.');a.report({node:v,message:J})}else if("Program"===b.type){var X='React Hook "'+a.getSource(v)+'" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.';a.report({node:v,message:X})}else if(d){var O=
33
- 'React Hook "'+a.getSource(v)+'" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.';a.report({node:v,message:O})}}}catch(F){q=!0,U=F}finally{try{x||null==l.return||l.return()}finally{if(q)throw U;}}}}}catch(F){n=!0,T=F}finally{try{k||null==P.return||P.return()}finally{if(n)throw T;}}}},CallExpression:function(a){if(M(a.callee)){var e=c[c.length-1],C=b[b.length-1],p=e.get(C);p||(p=[],e.set(C,p));p.push(a.callee)}}}}},"exhaustive-deps":{meta:{type:"suggestion",
14
+ function ka(a){function c(){return{isRequired:!1,isSatisfiedRecursively:!1,hasRequiredNodesBelow:!1,children:new Map}}function e(a,d){d=d.split(".");var l=!0,b=!1,h=void 0;try{for(var e=d[Symbol.iterator](),n;!(l=(n=e.next()).done);l=!0){var B=n.value,k=f(a,B);k||(k=c(),a.children.set(B,k));a=k}}catch(r){b=!0,h=r}finally{try{l||null==e.return||e.return()}finally{if(b)throw h;}}return a}function h(a,c,d){c=c.split(".");var l=!0,b=!1,e=void 0;try{for(var h=c[Symbol.iterator](),n;!(l=(n=h.next()).done);l=
15
+ !0){var k=f(a,n.value);if(!k)break;d(k);a=k}}catch(r){b=!0,e=r}finally{try{l||null==h.return||h.return()}finally{if(b)throw e;}}}function f(a,c){return a.children.get(c)||a.children.get(c.split("?")[0])||a.children.get(c+"?")}function k(a,c,d,b){a.children.forEach(function(a,l){var f=b(l);a.isSatisfiedRecursively?a.hasRequiredNodesBelow&&d.add(f):a.isRequired?c.add(f):k(a,c,d,function(a){return f+"."+a})})}var q=a.dependencies,t=a.declaredDependencies,x=a.optionalDependencies,A=a.externalDependencies,
16
+ V=a.isEffect,d=c();q.forEach(function(a,c){e(d,c).isRequired=!0;h(d,c,function(a){a.hasRequiredNodesBelow=!0})});t.forEach(function(a){e(d,a.key).isSatisfiedRecursively=!0});x.forEach(function(a){e(d,a).isSatisfiedRecursively=!0});a=new Set;var b=new Set;k(d,a,b,function(a){return a});var n=[],D=new Set,p=new Set;t.forEach(function(a){a=a.key;b.has(a)?-1===n.indexOf(a)?n.push(a):p.add(a):!V||a.endsWith(".current")||A.has(a)?D.add(a):-1===n.indexOf(a)&&n.push(a)});a.forEach(function(a){n.push(a)});
17
+ return{suggestedDependencies:n,unnecessaryDependencies:D,duplicateDependencies:p,missingDependencies:a}}
18
+ function la(a){var c=a.declaredDependenciesNode,e=a.componentScope,h=a.scope;return a.declaredDependencies.map(function(a){a=e.set.get(a.key);if(null==a)return null;var c=a.defs[0];return null==c?null:"Variable"===c.type&&"VariableDeclarator"===c.node.type&&null!=c.node.init&&("ArrowFunctionExpression"===c.node.init.type||"FunctionExpression"===c.node.init.type)||"FunctionName"===c.type&&"FunctionDeclaration"===c.node.type?a:null}).filter(Boolean).map(function(a){var e=a.defs[0];a:{for(var f=!1,t=
19
+ 0;t<a.references.length;t++){var x=a.references[t];if(x.writeExpr)if(f){a=!0;break a}else{f=!0;continue}for(var A=x.from;A!==h&&null!=A;)A=A.upper;if(A!==h&&!ma(c,x.identifier)){a=!0;break a}}a=!1}return{fn:e,suggestUseCallback:a}})}
20
+ function na(a){return"MemberExpression"!==a.parent.type&&"OptionalMemberExpression"!==a.parent.type||a.parent.object!==a||"current"===a.parent.property.name||a.parent.computed||null!=a.parent.parent&&"CallExpression"===a.parent.parent.type&&a.parent.parent.callee===a.parent?"MemberExpression"===a.type&&a.parent&&"AssignmentExpression"===a.parent.type?a.object:a:na(a.parent)}
21
+ function Z(a){if("Identifier"===a.type)return a.name;if("MemberExpression"!==a.type||a.computed){if("OptionalMemberExpression"!==a.type||a.computed)throw Error("Unsupported node type: "+a.type);var c=Z(a.object);a=Z(a.property);return c+"?."+a}c=Z(a.object);a=Z(a.property);return c+"."+a}function oa(a){return"MemberExpression"!==a.type||"Identifier"!==a.object.type||"React"!==a.object.name||"Identifier"!==a.property.type||a.computed?a:a.property}
22
+ function pa(a,c){var e=oa(a);if("Identifier"!==e.type)return-1;switch(e.name){case "useEffect":case "useLayoutEffect":case "useCallback":case "useMemo":return 0;case "useImperativeHandle":return 1;default:if(e===a&&c&&c.additionalHooks){try{var h=Z(e)}catch(f){if(/Unsupported node type/.test(f.message))return 0;throw f;}return c.additionalHooks.test(h)?0:-1}return-1}}
23
+ function qa(a,c){for(var e=[a],h=null;e.length;){h=e.shift();if("Identifier"===h.type&&h.name===c.name&&h.range[0]===c.range[0]&&h.range[1]===c.range[1])return h;if(ma(h,c)){a=0;for(var f=Object.entries(h);a<f.length;a++){var k=f[a],q=k[1];"parent"!==k[0]&&(ra(q)?(q.parent=h,e.push(q)):Array.isArray(q)&&q.forEach(function(a){ra(a)&&(a.parent=h,e.push(a))}))}}}return null}
24
+ function sa(a){for(var c="",e=0;e<a.length;e++)c+=a[e],0===e&&2===a.length?c+=" and ":e===a.length-2&&2<a.length?c+=", and ":e<a.length-1&&(c+=", ");return c}function ra(a){return"object"===typeof a&&null!==a&&!Array.isArray(a)&&"string"===typeof a.type}function ma(a,c){return a.range[0]<=c.range[0]&&a.range[1]>=c.range[1]}exports.configs={recommended:{plugins:["react-hooks"],rules:{"react-hooks/rules-of-hooks":"error","react-hooks/exhaustive-deps":"warn"}}};
25
+ exports.rules={"rules-of-hooks":{meta:{type:"problem",docs:{description:"enforces the Rules of Hooks",category:"Possible Errors",recommended:!0,url:"https://reactjs.org/docs/hooks-rules.html"}},create:function(a){var c=[],e=[];return{onCodePathSegmentStart:function(a){return e.push(a)},onCodePathSegmentEnd:function(){return e.pop()},onCodePathStart:function(){return c.push(new Map)},onCodePathEnd:function(e,f){function h(a,c){var d=h.cache,b=d.get(a.id);c=new Set(c);if(c.has(a.id)){d=[].concat(c);
26
+ a=d.slice(d.indexOf(a.id)+1);d=!0;b=!1;var g=void 0;try{for(var m=a[Symbol.iterator](),y;!(d=(y=m.next()).done);d=!0)A.add(y.value)}catch(G){b=!0,g=G}finally{try{d||null==m.return||m.return()}finally{if(b)throw g;}}return 0}c.add(a.id);if(void 0!==b)return b;if(e.thrownSegments.includes(a))b=0;else if(0===a.prevSegments.length)b=1;else{b=0;m=!0;y=!1;var I=void 0;try{g=a.prevSegments[Symbol.iterator]();for(var J;!(m=(J=g.next()).done);m=!0)b+=h(J.value,c)}catch(G){y=!0,I=G}finally{try{m||null==
27
+ g.return||g.return()}finally{if(y)throw I;}}}a.reachable&&0===b?d.delete(a.id):d.set(a.id,b);return b}function q(a,c){var d=q.cache,b=d.get(a.id);c=new Set(c);if(c.has(a.id)){d=Array.from(c);a=d.slice(d.indexOf(a.id)+1);d=!0;b=!1;var g=void 0;try{for(var m=a[Symbol.iterator](),y;!(d=(y=m.next()).done);d=!0)A.add(y.value)}catch(G){b=!0,g=G}finally{try{d||null==m.return||m.return()}finally{if(b)throw g;}}return 0}c.add(a.id);if(void 0!==b)return b;if(e.thrownSegments.includes(a))b=0;else if(0===
28
+ a.nextSegments.length)b=1;else{b=0;m=!0;y=!1;var I=void 0;try{g=a.nextSegments[Symbol.iterator]();for(var J;!(m=(J=g.next()).done);m=!0)b+=q(J.value,c)}catch(G){y=!0,I=G}finally{try{m||null==g.return||g.return()}finally{if(y)throw I;}}}d.set(a.id,b);return b}function t(a){var c=t.cache,b=c.get(a.id);if(null===b)return Infinity;if(void 0!==b)return b;c.set(a.id,null);if(0===a.prevSegments.length)b=1;else{b=Infinity;var d=!0,g=!1,m=void 0;try{for(var y=a.prevSegments[Symbol.iterator](),I;!(d=
29
+ (I=y.next()).done);d=!0){var e=t(I.value);e<b&&(b=e)}}catch(G){g=!0,m=G}finally{try{d||null==y.return||y.return()}finally{if(g)throw m;}}b+=1}c.set(a.id,b);return b}var x=c.pop();if(0!==x.size){var A=new Set;h.cache=new Map;q.cache=new Map;t.cache=new Map;var V=q(e.initialSegment),d=ja(f),b=ia(f),n=d?ba(d)||L(d):fa(f)||ha(f),D=Infinity,p=!0,l=!1,B=void 0;try{for(var O=e.finalSegments[Symbol.iterator](),T;!(p=(T=O.next()).done);p=!0){var C=T.value;if(C.reachable){var v=t(C);v<D&&(D=v)}}}catch(F){l=
30
+ !0,B=F}finally{try{p||null==O.return||O.return()}finally{if(l)throw B;}}p=!0;l=!1;B=void 0;try{for(var P=x[Symbol.iterator](),aa;!(p=(aa=P.next()).done);p=!0){var U=aa.value,r=U[0],X=U[1];if(r.reachable){var Q=0===r.nextSegments.length?D<=t(r):D<t(r),M=h(r)*q(r),K=A.has(r.id);x=!0;O=!1;T=void 0;try{for(var u=X[Symbol.iterator](),E;!(x=(E=u.next()).done);x=!0){var z=E.value;K&&a.report({node:z,message:'React Hook "'+a.getSource(z)+'" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.'});
31
+ if(n){if(!K&&M!==V){var R='React Hook "'+a.getSource(z)+'" is called conditionally. React Hooks must be called in the exact same order in every component render.'+(Q?" Did you accidentally call a React Hook after an early return?":"");a.report({node:z,message:R})}}else if(f.parent&&("MethodDefinition"===f.parent.type||"ClassProperty"===f.parent.type)&&f.parent.value===f){var S='React Hook "'+a.getSource(z)+'" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.';
32
+ a.report({node:z,message:S})}else if(d){var H='React Hook "'+a.getSource(z)+'" is called in function "'+(a.getSource(d)+'" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.');a.report({node:z,message:H})}else if("Program"===f.type){var Y='React Hook "'+a.getSource(z)+'" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.';a.report({node:z,message:Y})}else if(b){var N=
33
+ 'React Hook "'+a.getSource(z)+'" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.';a.report({node:z,message:N})}}}catch(F){O=!0,T=F}finally{try{x||null==u.return||u.return()}finally{if(O)throw T;}}}}}catch(F){l=!0,B=F}finally{try{p||null==P.return||P.return()}finally{if(l)throw B;}}}},CallExpression:function(a){if(L(a.callee)){var h=c[c.length-1],k=e[e.length-1],q=h.get(k);q||(q=[],h.set(k,q));q.push(a.callee)}}}}},"exhaustive-deps":{meta:{type:"suggestion",
34
34
  docs:{description:"verifies the list of dependencies for Hooks like useEffect and similar",category:"Best Practices",recommended:!0,url:"https://github.com/facebook/react/issues/14920"},fixable:"code",schema:[{type:"object",additionalProperties:!1,enableDangerousAutofixThisMayCauseInfiniteLoops:!1,properties:{additionalHooks:{type:"string"},enableDangerousAutofixThisMayCauseInfiniteLoops:{type:"boolean"}}}]},create:function(a){function c(c){f&&Array.isArray(c.suggest)&&0<c.suggest.length&&(c.fix=
35
- c.suggest[0].fix);a.report(c)}function b(a,c){return function(b){if(c.has(b))return c.get(b);var d=a(b);c.set(b,d);return d}}function e(h,d,e,f,k){function z(a){var c=!0,g=!1,b=void 0;try{for(var d=a.references[Symbol.iterator](),e;!(c=(e=d.next()).done);c=!0){var f=e.value;if(f.resolved&&C.has(f.resolved.scope)){var p=qa(h,f.identifier),l=ma(p),A=Y(l),q;if(q=k&&"Identifier"===l.type&&"MemberExpression"===l.parent.type&&!l.parent.computed&&"Identifier"===l.parent.property.type&&"current"===l.parent.property.name){for(var n=
36
- f.from,u=!1;n.block!==h;)"function"===n.type&&(u=null!=n.block.parent&&"ReturnStatement"===n.block.parent.type),n=n.upper;q=u}q&&G.set(A,{reference:f,dependencyNode:l});var r=f.resolved.defs[0];if(null!=r&&(null==r.node||r.node.init!==h.parent)&&"TypeParameter"!==r.type)if(t.has(A))t.get(A).references.push(f);else{var w=f.resolved,x=P(w)||Z(w);t.set(A,{isStatic:x,references:[f]})}}}}catch(da){g=!0,b=da}finally{try{c||null==d.return||d.return()}finally{if(g)throw b;}}c=!0;g=!1;b=void 0;try{for(var v=
37
- a.childScopes[Symbol.iterator](),y;!(c=(y=v.next()).done);c=!0)z(y.value)}catch(da){g=!0,b=da}finally{try{c||null==v.return||v.return()}finally{if(g)throw b;}}}function A(a,c,b,d){return 0===a.size?null:(1<a.size?"":c+" ")+b+" "+(1<a.size?"dependencies":"dependency")+": "+sa(Array.from(a).sort().map(function(a){return"'"+a+"'"}))+(". Either "+d+" "+(1<a.size?"them":"it")+" or remove the dependency array.")}k&&h.async&&c({node:h,message:"Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching"});
38
- for(var q=p.acquire(h),C=new Set,D=null,w=q.upper;w;){C.add(w);if("function"===w.type)break;w=w.upper}if(w){D=w;var P=b(function(a){if(!Array.isArray(a.defs))return!1;var c=a.defs[0];if(null==c||"VariableDeclarator"!==c.node.type)return!1;var b=c.node.init;if(null==b)return!1;for(;"TSAsExpression"===b.type;)b=b.expression;var g=c.node.parent;if(null==g&&(qa(D.block,c.node.id),g=c.node.parent,null==g))return!1;if("const"===g.kind&&"Literal"===b.type&&("string"===typeof b.value||"number"===typeof b.value||
39
- null===b.value))return!0;if("CallExpression"!==b.type)return!1;b=b.callee;"MemberExpression"!==b.type||"React"!==b.object.name||null==b.property||b.computed||(b=b.property);if("Identifier"!==b.type)return!1;c=c.node.id;b=b.name;if("useRef"===b&&"Identifier"===c.type)return!0;if(("useState"===b||"useReducer"===b)&&"ArrayPattern"===c.type&&2===c.elements.length&&Array.isArray(a.identifiers)){if(c.elements[1]===a.identifiers[0]){if("useState"===b)for(a=a.references,b=0;b<a.length;b++)u.set(a[b].identifier,
40
- c.elements[0]);return!0}if(c.elements[0]===a.identifiers[0]&&"useState"===b)for(a=a.references,c=0;c<a.length;c++)x.add(a[c].identifier)}return!1},y),Z=b(function(a){if(!Array.isArray(a.defs))return!1;a=a.defs[0];if(null==a||null==a.node||null==a.node.id)return!1;var c=a.node,b=D.childScopes;a=null;var d;for(d=0;d<b.length;d++){var g=b[d],e=g.block;if("FunctionDeclaration"===c.type&&e===c||"VariableDeclarator"===c.type&&e.parent===c){a=g;break}}if(null==a)return!1;for(d=0;d<a.through.length;d++)if(c=
41
- a.through[d],null!=c.resolved&&C.has(c.resolved.scope)&&!P(c.resolved))return!1;return!0},H),G=new Map,t=new Map;z(q);G.forEach(function(a,b){var d=a.dependencyNode;a=a.reference.resolved.references;for(var g=!1,e=0;e<a.length;e++){var m=a[e].identifier.parent;if(null!=m&&"MemberExpression"===m.type&&!m.computed&&"Identifier"===m.property.type&&"current"===m.property.name&&"AssignmentExpression"===m.parent.type&&m.parent.left===m){g=!0;break}}g||c({node:d.parent.property,message:"The ref value '"+
42
- b+".current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy '"+(b+".current' to a variable inside the effect, and use that variable in the cleanup function.")})});var W=new Set,Q=new Set;t.forEach(function(b,d){var g=b.references;b.isStatic&&Q.add(d);g.forEach(function(b){b.writeExpr&&(b=b.writeExpr,W.has(d)||(W.add(d),c({node:b,message:"Assignments to the '"+d+"' variable from inside React Hook "+(a.getSource(e)+" will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside ")+
43
- (a.getSource(e)+".")})))})});if(!(0<W.size))if(d){var N=[],L=new Set;"ArrayExpression"!==d.type?c({node:d,message:"React Hook "+a.getSource(e)+" was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies."}):d.elements.forEach(function(b){if(null!==b)if("SpreadElement"===b.type)c({node:b,message:"React Hook "+a.getSource(e)+" has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies."});
44
- else{try{var d=Y(b)}catch(oa){if(/Unsupported node type/.test(oa.message)){"Literal"===b.type?t.has(b.value)?c({node:b,message:"The "+b.raw+" literal is not a valid dependency because it never changes. Did you mean to include "+(b.value+" in the array instead?")}):c({node:b,message:"The "+b.raw+" literal is not a valid dependency because it never changes. You can safely remove it."}):c({node:b,message:"React Hook "+a.getSource(e)+" has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked."});
45
- return}throw oa;}for(var g=b;"MemberExpression"===g.type;)g=g.object;var h=!D.through.some(function(a){return a.identifier===g});N.push({key:d,node:b});h||L.add(d)}});var l=ja({dependencies:t,declaredDependencies:N,optionalDependencies:Q,externalDependencies:L,isEffect:k});w=l.unnecessaryDependencies;var E=l.missingDependencies,v=l.duplicateDependencies,R=l.suggestedDependencies;if(0===v.size+E.size+w.size)ka({declaredDependencies:N,declaredDependenciesNode:d,componentScope:D,scope:q}).forEach(function(a){var b=
46
- a.fn;a=a.suggestUseCallback;var g="The '"+b.name.name+"' function makes the dependencies of "+(f+" Hook (at line "+d.loc.start.line+") change on every render.");g=a?g+(" To fix this, wrap the '"+(b.name.name+"' definition into its own useCallback() Hook.")):g+(" Move it inside the "+f+" callback. Alternatively, wrap the '"+(b.name.name+"' definition into its own useCallback() Hook."));var e;a&&"Variable"===b.type&&(e=[{desc:"Wrap the '"+b.name.name+"' definition into its own useCallback() Hook.",
47
- fix:function(a){return[a.insertTextBefore(b.node.init,"useCallback("),a.insertTextAfter(b.node.init,")")]}}]);c({node:b.node,message:g,suggest:e})});else{!k&&0<E.size&&(R=ja({dependencies:t,declaredDependencies:[],optionalDependencies:Q,externalDependencies:L,isEffect:k}).suggestedDependencies);(function(){if(0===N.length)return!0;var a=N.map(function(a){return a.key}),b=a.slice().sort();return a.join(",")===b.join(",")})()&&R.sort();l="";if(0<w.size){var S=null;Array.from(w.keys()).forEach(function(a){null===
48
- S&&a.endsWith(".current")&&(S=a)});if(null!==S)l=" Mutable values like '"+S+"' aren't valid dependencies because mutating them doesn't re-render the component.";else if(0<L.size){var J=Array.from(L)[0];q.set.has(J)||(l=" Outer scope values like '"+J+"' aren't valid dependencies because mutating them doesn't re-render the component.")}}if(!l&&E.has("props")){q=t.get("props");if(null==q)return;q=q.references;if(!Array.isArray(q))return;J=!0;for(var X=0;X<q.length;X++){var O=qa(D.block,q[X].identifier);
49
- if(!O){J=!1;break}O=O.parent;if(null==O){J=!1;break}if("MemberExpression"!==O.type){J=!1;break}}J&&(l=" However, 'props' will change when *any* prop changes, so the preferred fix is to destructure the 'props' object outside of the "+(f+" call and refer to those specific props inside ")+(a.getSource(e)+"."))}if(!l&&0<E.size){var F=null;E.forEach(function(a){if(!F){var b=D.set.get(a),c=t.get(a);if(c.references[0].resolved===b&&(b=b.defs[0],null!=b&&null!=b.name&&"Parameter"===b.type)){b=!1;for(var d,
50
- e=0;e<c.references.length;e++)if(d=c.references[e].identifier,null!=d&&null!=d.parent&&"CallExpression"===d.parent.type&&d.parent.callee===d){b=!0;break}b&&(F=a)}}});null!==F&&(l=" If '"+F+"' changes too often, find the parent component that defines it and wrap that definition in useCallback.")}if(!l&&0<E.size){var r=null;E.forEach(function(a){if(null===r)for(var b=t.get(a).references,c,d,e=0;e<b.length;e++){c=b[e].identifier;for(d=c.parent;null!=d&&d!==D.block;){if("CallExpression"===d.type){var g=
51
- u.get(d.callee);if(null!=g){g.name===a?r={missingDep:a,setter:d.callee.name,form:"updater"}:x.has(c)?r={missingDep:a,setter:d.callee.name,form:"reducer"}:(c=b[e].resolved,null!=c&&(c=c.defs[0],null!=c&&"Parameter"===c.type&&(r={missingDep:a,setter:d.callee.name,form:"inlineReducer"})));break}}d=d.parent}if(null!==r)break}});if(null!==r)switch(r.form){case "reducer":l=" You can also replace multiple useState variables with useReducer if '"+(r.setter+"' needs the current value of '")+(r.missingDep+
52
- "'.");break;case "inlineReducer":l=" If '"+r.setter+"' needs the current value of '"+(r.missingDep+"', you can also switch to useReducer instead of useState and read '")+(r.missingDep+"' in the reducer.");break;case "updater":l=" You can also do a functional update '"+r.setter+"("+r.missingDep.substring(0,1)+" => ...)' if you only need '"+r.missingDep+"' in the '"+(r.setter+"' call.");break;default:throw Error("Unknown case.");}}c({node:d,message:"React Hook "+a.getSource(e)+" has "+(A(E,"a","missing",
53
- "include")||A(w,"an","unnecessary","exclude")||A(v,"a","duplicate","omit"))+l,suggest:[{desc:"Update the dependencies array to be: ["+R.join(", ")+"]",fix:function(a){return a.replaceText(d,"["+R.join(", ")+"]")}}]})}}else{var V=null;t.forEach(function(a,b){V||a.references.forEach(function(a){if(!V&&u.has(a.identifier)){for(a=a.from;"function"!==a.type;)a=a.upper;a.block===h&&(V=b)}})});if(V){var ca=ja({dependencies:t,declaredDependencies:[],optionalDependencies:Q,externalDependencies:new Set,isEffect:!0}).suggestedDependencies;
54
- c({node:e,message:"React Hook "+f+" contains a call to '"+V+"'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass ["+ca.join(", ")+("] as a second argument to the "+f+" Hook."),suggest:[{desc:"Add dependencies array: ["+ca.join(", ")+"]",fix:function(a){return a.insertTextAfter(h,", ["+ca.join(", ")+"]")}}]})}}}}var f=a.options&&a.options[0]&&a.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops||!1,C={additionalHooks:a.options&&a.options[0]&&
55
- a.options[0].additionalHooks?new RegExp(a.options[0].additionalHooks):void 0,enableDangerousAutofixThisMayCauseInfiniteLoops:f},p=a.getSourceCode().scopeManager,u=new WeakMap,x=new WeakSet,y=new WeakMap,H=new WeakMap;return{CallExpression:function(b){var d=pa(b.callee,C);if(-1!==d){var f=b.arguments[d],h=b.callee,k=na(h).name,n=b.arguments[d+1];b=/Effect($|[^a-z])/g.test(k);if(n||b){switch(f.type){case "FunctionExpression":case "ArrowFunctionExpression":e(f,n,h,k,b);return;case "Identifier":if(!n||
56
- n.elements&&n.elements.some(function(a){return"Identifier"===a.type&&a.name===f.name}))return;d=a.getScope().set.get(f.name);if(null==d||null==d.defs)return;d=d.defs[0];if(!d||!d.node)break;if("Variable"!==d.type&&"FunctionName"!==d.type)break;switch(d.node.type){case "FunctionDeclaration":e(d.node,n,h,k,b);return;case "VariableDeclarator":if(d=d.node.init)switch(d.type){case "ArrowFunctionExpression":case "FunctionExpression":e(d,n,h,k,b);return}}break;default:c({node:h,message:"React Hook "+k+" received a function whose dependencies are unknown. Pass an inline function instead."});
57
- return}c({node:h,message:"React Hook "+k+" has a missing dependency: '"+f.name+"'. Either include it or remove the dependency array.",suggest:[{desc:"Update the dependencies array to be: ["+f.name+"]",fix:function(a){return a.replaceText(n,"["+f.name+"]")}}]})}else"useMemo"!==k&&"useCallback"!==k||c({node:h,message:"React Hook "+k+" does nothing when called with only one argument. Did you forget to pass an array of dependencies?"})}}}}}};
35
+ c.suggest[0].fix);a.report(c)}function e(a,c){return function(b){if(c.has(b))return c.get(b);var d=a(b);c.set(b,d);return d}}function h(d,b,h,f,p){function l(a){var c=!0,g=!1,b=void 0;try{for(var e=a.references[Symbol.iterator](),h;!(c=(h=e.next()).done);c=!0){var f=h.value;if(f.resolved&&D.has(f.resolved.scope)){var k=qa(d,f.identifier),n=na(k),q=Z(n),u;if(u=p&&"Identifier"===n.type&&"MemberExpression"===n.parent.type&&!n.parent.computed&&"Identifier"===n.parent.property.type&&"current"===n.parent.property.name){for(var t=
36
+ f.from,w=!1;t.block!==d;)"function"===t.type&&(w=null!=t.block.parent&&"ReturnStatement"===t.block.parent.type),t=t.upper;u=w}u&&U.set(q,{reference:f,dependencyNode:n});var v=f.resolved.defs[0];if(null!=v&&(null==v.node||v.node.init!==d.parent)&&"TypeParameter"!==v.type)if(r.has(q))r.get(q).references.push(f);else{var x=f.resolved,z=P(x)||aa(x);r.set(q,{isStatic:z,references:[f]})}}}}catch(ea){g=!0,b=ea}finally{try{c||null==e.return||e.return()}finally{if(g)throw b;}}c=!0;g=!1;b=void 0;try{for(var B=
37
+ a.childScopes[Symbol.iterator](),A;!(c=(A=B.next()).done);c=!0)l(A.value)}catch(ea){g=!0,b=ea}finally{try{c||null==B.return||B.return()}finally{if(g)throw b;}}}function n(a,c,y,b){return 0===a.size?null:(1<a.size?"":c+" ")+y+" "+(1<a.size?"dependencies":"dependency")+": "+sa(Array.from(a).sort().map(function(a){return"'"+a+"'"}))+(". Either "+b+" "+(1<a.size?"them":"it")+" or remove the dependency array.")}p&&d.async&&c({node:d,message:"Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching"});
38
+ for(var k=q.acquire(d),D=new Set,C=null,v=k.upper;v;){D.add(v);if("function"===v.type)break;v=v.upper}if(v){C=v;var P=e(function(a){if(!Array.isArray(a.defs))return!1;var c=a.defs[0];if(null==c||"VariableDeclarator"!==c.node.type)return!1;var b=c.node.init;if(null==b)return!1;for(;"TSAsExpression"===b.type;)b=b.expression;var g=c.node.parent;if(null==g&&(qa(C.block,c.node.id),g=c.node.parent,null==g))return!1;if("const"===g.kind&&"Literal"===b.type&&("string"===typeof b.value||"number"===typeof b.value||
39
+ null===b.value))return!0;if("CallExpression"!==b.type)return!1;b=b.callee;"MemberExpression"!==b.type||"React"!==b.object.name||null==b.property||b.computed||(b=b.property);if("Identifier"!==b.type)return!1;c=c.node.id;b=b.name;if("useRef"===b&&"Identifier"===c.type)return!0;if(("useState"===b||"useReducer"===b)&&"ArrayPattern"===c.type&&2===c.elements.length&&Array.isArray(a.identifiers)){if(c.elements[1]===a.identifiers[0]){if("useState"===b)for(a=a.references,b=0;b<a.length;b++)t.set(a[b].identifier,
40
+ c.elements[0]);return!0}if(c.elements[0]===a.identifiers[0]&&"useState"===b)for(a=a.references,c=0;c<a.length;c++)x.add(a[c].identifier)}return!1},A),aa=e(function(a){if(!Array.isArray(a.defs))return!1;a=a.defs[0];if(null==a||null==a.node||null==a.node.id)return!1;var c=a.node,b=C.childScopes;a=null;var g;for(g=0;g<b.length;g++){var d=b[g],e=d.block;if("FunctionDeclaration"===c.type&&e===c||"VariableDeclarator"===c.type&&e.parent===c){a=d;break}}if(null==a)return!1;for(g=0;g<a.through.length;g++)if(c=
41
+ a.through[g],null!=c.resolved&&D.has(c.resolved.scope)&&!P(c.resolved))return!1;return!0},V),U=new Map,r=new Map;l(k);U.forEach(function(a,b){var g=a.dependencyNode;a=a.reference.resolved.references;for(var d=!1,e=0;e<a.length;e++){var m=a[e].identifier.parent;if(null!=m&&"MemberExpression"===m.type&&!m.computed&&"Identifier"===m.property.type&&"current"===m.property.name&&"AssignmentExpression"===m.parent.type&&m.parent.left===m){d=!0;break}}d||c({node:g.parent.property,message:"The ref value '"+
42
+ b+".current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy '"+(b+".current' to a variable inside the effect, and use that variable in the cleanup function.")})});var X=new Set,Q=new Set;r.forEach(function(b,d){var g=b.references;b.isStatic&&Q.add(d);g.forEach(function(b){b.writeExpr&&(b=b.writeExpr,X.has(d)||(X.add(d),c({node:b,message:"Assignments to the '"+d+"' variable from inside React Hook "+(a.getSource(h)+" will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside ")+
43
+ (a.getSource(h)+".")})))})});if(!(0<X.size))if(b){var M=[],K=new Set;"ArrayExpression"!==b.type?c({node:b,message:"React Hook "+a.getSource(h)+" was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies."}):b.elements.forEach(function(b){if(null!==b)if("SpreadElement"===b.type)c({node:b,message:"React Hook "+a.getSource(h)+" has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies."});
44
+ else{try{var d=Z(b)}catch(J){if(/Unsupported node type/.test(J.message)){"Literal"===b.type?r.has(b.value)?c({node:b,message:"The "+b.raw+" literal is not a valid dependency because it never changes. Did you mean to include "+(b.value+" in the array instead?")}):c({node:b,message:"The "+b.raw+" literal is not a valid dependency because it never changes. You can safely remove it."}):c({node:b,message:"React Hook "+a.getSource(h)+" has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked."});
45
+ return}throw J;}for(var g=b;"MemberExpression"===g.type;)g=g.object;var e=!C.through.some(function(a){return a.identifier===g});M.push({key:d,node:b});e||K.add(d)}});var u=ka({dependencies:r,declaredDependencies:M,optionalDependencies:Q,externalDependencies:K,isEffect:p});v=u.unnecessaryDependencies;var E=u.missingDependencies,z=u.duplicateDependencies,R=u.suggestedDependencies;if(0===z.size+E.size+v.size)la({declaredDependencies:M,declaredDependenciesNode:b,componentScope:C,scope:k}).forEach(function(a){var d=
46
+ a.fn;a=a.suggestUseCallback;var g="The '"+d.name.name+"' function makes the dependencies of "+(f+" Hook (at line "+b.loc.start.line+") change on every render.");g=a?g+(" To fix this, wrap the '"+(d.name.name+"' definition into its own useCallback() Hook.")):g+(" Move it inside the "+f+" callback. Alternatively, wrap the '"+(d.name.name+"' definition into its own useCallback() Hook."));var e;a&&"Variable"===d.type&&(e=[{desc:"Wrap the '"+d.name.name+"' definition into its own useCallback() Hook.",
47
+ fix:function(a){return[a.insertTextBefore(d.node.init,"useCallback("),a.insertTextAfter(d.node.init,")")]}}]);c({node:d.node,message:g,suggest:e})});else{!p&&0<E.size&&(R=ka({dependencies:r,declaredDependencies:[],optionalDependencies:Q,externalDependencies:K,isEffect:p}).suggestedDependencies);(function(){if(0===M.length)return!0;var a=M.map(function(a){return a.key}),b=a.slice().sort();return a.join(",")===b.join(",")})()&&R.sort();u="";if(0<v.size){var S=null;Array.from(v.keys()).forEach(function(a){null===
48
+ S&&a.endsWith(".current")&&(S=a)});if(null!==S)u=" Mutable values like '"+S+"' aren't valid dependencies because mutating them doesn't re-render the component.";else if(0<K.size){var H=Array.from(K)[0];k.set.has(H)||(u=" Outer scope values like '"+H+"' aren't valid dependencies because mutating them doesn't re-render the component.")}}if(!u&&E.has("props")){k=r.get("props");if(null==k)return;k=k.references;if(!Array.isArray(k))return;H=!0;for(var Y=0;Y<k.length;Y++){var N=qa(C.block,k[Y].identifier);
49
+ if(!N){H=!1;break}N=N.parent;if(null==N){H=!1;break}if("MemberExpression"!==N.type){H=!1;break}}H&&(u=" However, 'props' will change when *any* prop changes, so the preferred fix is to destructure the 'props' object outside of the "+(f+" call and refer to those specific props inside ")+(a.getSource(h)+"."))}if(!u&&0<E.size){var F=null;E.forEach(function(a){if(!F){var b=C.set.get(a),c=r.get(a);if(c.references[0].resolved===b&&(b=b.defs[0],null!=b&&null!=b.name&&"Parameter"===b.type)){b=!1;for(var d,
50
+ e=0;e<c.references.length;e++)if(d=c.references[e].identifier,null!=d&&null!=d.parent&&"CallExpression"===d.parent.type&&d.parent.callee===d){b=!0;break}b&&(F=a)}}});null!==F&&(u=" If '"+F+"' changes too often, find the parent component that defines it and wrap that definition in useCallback.")}if(!u&&0<E.size){var w=null;E.forEach(function(a){if(null===w)for(var b=r.get(a).references,c,d,e=0;e<b.length;e++){c=b[e].identifier;for(d=c.parent;null!=d&&d!==C.block;){if("CallExpression"===d.type){var g=
51
+ t.get(d.callee);if(null!=g){g.name===a?w={missingDep:a,setter:d.callee.name,form:"updater"}:x.has(c)?w={missingDep:a,setter:d.callee.name,form:"reducer"}:(c=b[e].resolved,null!=c&&(c=c.defs[0],null!=c&&"Parameter"===c.type&&(w={missingDep:a,setter:d.callee.name,form:"inlineReducer"})));break}}d=d.parent}if(null!==w)break}});if(null!==w)switch(w.form){case "reducer":u=" You can also replace multiple useState variables with useReducer if '"+(w.setter+"' needs the current value of '")+(w.missingDep+
52
+ "'.");break;case "inlineReducer":u=" If '"+w.setter+"' needs the current value of '"+(w.missingDep+"', you can also switch to useReducer instead of useState and read '")+(w.missingDep+"' in the reducer.");break;case "updater":u=" You can also do a functional update '"+w.setter+"("+w.missingDep.substring(0,1)+" => ...)' if you only need '"+w.missingDep+"' in the '"+(w.setter+"' call.");break;default:throw Error("Unknown case.");}}c({node:b,message:"React Hook "+a.getSource(h)+" has "+(n(E,"a","missing",
53
+ "include")||n(v,"an","unnecessary","exclude")||n(z,"a","duplicate","omit"))+u,suggest:[{desc:"Update the dependencies array to be: ["+R.join(", ")+"]",fix:function(a){return a.replaceText(b,"["+R.join(", ")+"]")}}]})}}else{var W=null;r.forEach(function(a,b){W||a.references.forEach(function(a){if(!W&&t.has(a.identifier)){for(a=a.from;"function"!==a.type;)a=a.upper;a.block===d&&(W=b)}})});if(W){var da=ka({dependencies:r,declaredDependencies:[],optionalDependencies:Q,externalDependencies:new Set,isEffect:!0}).suggestedDependencies;
54
+ c({node:h,message:"React Hook "+f+" contains a call to '"+W+"'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass ["+da.join(", ")+("] as a second argument to the "+f+" Hook."),suggest:[{desc:"Add dependencies array: ["+da.join(", ")+"]",fix:function(a){return a.insertTextAfter(d,", ["+da.join(", ")+"]")}}]})}}}}var f=a.options&&a.options[0]&&a.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops||!1,k={additionalHooks:a.options&&a.options[0]&&
55
+ a.options[0].additionalHooks?new RegExp(a.options[0].additionalHooks):void 0,enableDangerousAutofixThisMayCauseInfiniteLoops:f},q=a.getSourceCode().scopeManager,t=new WeakMap,x=new WeakSet,A=new WeakMap,V=new WeakMap;return{CallExpression:function(d){var b=pa(d.callee,k);if(-1!==b){var e=d.arguments[b],f=d.callee,p=oa(f).name,l=d.arguments[b+1];d=/Effect($|[^a-z])/g.test(p);if(l||d){switch(e.type){case "FunctionExpression":case "ArrowFunctionExpression":h(e,l,f,p,d);return;case "Identifier":if(!l||
56
+ l.elements&&l.elements.some(function(a){return"Identifier"===a.type&&a.name===e.name}))return;b=a.getScope().set.get(e.name);if(null==b||null==b.defs)return;b=b.defs[0];if(!b||!b.node)break;if("Variable"!==b.type&&"FunctionName"!==b.type)break;switch(b.node.type){case "FunctionDeclaration":h(b.node,l,f,p,d);return;case "VariableDeclarator":if(b=b.node.init)switch(b.type){case "ArrowFunctionExpression":case "FunctionExpression":h(b,l,f,p,d);return}}break;default:c({node:f,message:"React Hook "+p+" received a function whose dependencies are unknown. Pass an inline function instead."});
57
+ return}c({node:f,message:"React Hook "+p+" has a missing dependency: '"+e.name+"'. Either include it or remove the dependency array.",suggest:[{desc:"Update the dependencies array to be: ["+e.name+"]",fix:function(a){return a.replaceText(l,"["+e.name+"]")}}]})}else"useMemo"!==p&&"useCallback"!==p||c({node:f,message:"React Hook "+p+" does nothing when called with only one argument. Did you forget to pass an array of dependencies?"})}}}}}};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks",
3
3
  "description": "ESLint rules for React Hooks",
4
- "version": "4.0.3",
4
+ "version": "4.0.4",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/facebook/react.git",