eslint-plugin-react-x 5.24.1 → 5.24.3

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.
Files changed (2) hide show
  1. package/dist/index.js +15 -1766
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -145,7 +145,7 @@ const rules$6 = {
145
145
  //#endregion
146
146
  //#region package.json
147
147
  var name$6 = "eslint-plugin-react-x";
148
- var version = "5.24.1";
148
+ var version = "5.24.3";
149
149
 
150
150
  //#endregion
151
151
  //#region src/utils/create-rule.ts
@@ -257,17 +257,11 @@ const rule$1 = {
257
257
  }
258
258
  context.report(problem);
259
259
  }
260
- /**
261
- * SourceCode that also works down to ESLint 3.0.0
262
- */
263
260
  const getSourceCode = typeof context.getSourceCode === "function" ? () => {
264
261
  return context.getSourceCode();
265
262
  } : () => {
266
263
  return context.sourceCode;
267
264
  };
268
- /**
269
- * SourceCode#getScope that also works down to ESLint 3.0.0
270
- */
271
265
  const getScope = typeof context.getScope === "function" ? () => {
272
266
  return context.getScope();
273
267
  } : (node) => {
@@ -287,9 +281,6 @@ const rule$1 = {
287
281
  return result;
288
282
  };
289
283
  }
290
- /**
291
- * Visitor for both function expressions and arrow function expressions.
292
- */
293
284
  function visitFunctionWithDependencies(node, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect, isAutoDepsHook) {
294
285
  if (isEffect && node.async) reportProblem({
295
286
  node,
@@ -989,24 +980,11 @@ function scanForConstructions({ declaredDependencies, declaredDependenciesNode,
989
980
  isUsedOutsideOfHook: isUsedOutsideOfHook(ref)
990
981
  }));
991
982
  }
992
- /**
993
- * Assuming () means the passed/returned node:
994
- * (props) => (props)
995
- * props.(foo) => (props.foo)
996
- * props.foo.(bar) => (props).foo.bar
997
- * props.foo.bar.(baz) => (props).foo.bar.baz
998
- */
999
983
  function getDependency(node) {
1000
984
  if (node.parent && (node.parent.type === "MemberExpression" || node.parent.type === "OptionalMemberExpression") && node.parent.object === node && "name" in node.parent.property && node.parent.property.name !== "current" && !node.parent.computed && !(node.parent.parent != null && (node.parent.parent.type === "CallExpression" || node.parent.parent.type === "OptionalCallExpression") && node.parent.parent.callee === node.parent)) return getDependency(node.parent);
1001
985
  else if (node.type === "MemberExpression" && node.parent && node.parent.type === "AssignmentExpression" && node.parent.left === node) return node.object;
1002
986
  else return node;
1003
987
  }
1004
- /**
1005
- * Mark a node as either optional or required.
1006
- * Note: If the node argument is an OptionalMemberExpression, it doesn't necessarily mean it is optional.
1007
- * It just means there is an optional member somewhere inside.
1008
- * This particular node might still represent a required member, so check .optional field.
1009
- */
1010
988
  function markNode(node, optionalChains, result) {
1011
989
  if (optionalChains) {
1012
990
  if ("optional" in node && node.optional) {
@@ -1014,13 +992,6 @@ function markNode(node, optionalChains, result) {
1014
992
  } else optionalChains.set(result, false);
1015
993
  }
1016
994
  }
1017
- /**
1018
- * Assuming () means the passed node.
1019
- * (foo) -> 'foo'
1020
- * foo(.)bar -> 'foo.bar'
1021
- * foo.bar(.)baz -> 'foo.bar.baz'
1022
- * Otherwise throw.
1023
- */
1024
995
  function analyzePropertyChain(node, optionalChains) {
1025
996
  if (node.type === "Identifier" || node.type === "JSXIdentifier") {
1026
997
  const result = node.name;
@@ -1067,16 +1038,6 @@ function getReactiveHookCallbackIndex(calleeNode, options) {
1067
1038
  } else return -1;
1068
1039
  }
1069
1040
  }
1070
- /**
1071
- * ESLint won't assign node.parent to references from context.getScope()
1072
- *
1073
- * So instead we search for the node from an ancestor assigning node.parent
1074
- * as we go. This mutates the AST.
1075
- *
1076
- * This traversal is:
1077
- * - optimized by only searching nodes with a range surrounding our target node
1078
- * - agnostic to AST node types, it looks for `{ type: string, ... }`
1079
- */
1080
1041
  function fastFindReferenceWithParent(start, target) {
1081
1042
  const queue = [start];
1082
1043
  let item;
@@ -1127,10 +1088,6 @@ function getUnknownDependenciesMessage(reactiveHookName) {
1127
1088
 
1128
1089
  //#endregion
1129
1090
  //#region src/rules/globals/helpers.ts
1130
- /**
1131
- * Array methods that mutate the array in place.
1132
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
1133
- */
1134
1091
  const MUTATING_ARRAY_METHODS = /* @__PURE__ */ new Set([
1135
1092
  "copyWithin",
1136
1093
  "fill",
@@ -1142,7 +1099,6 @@ const MUTATING_ARRAY_METHODS = /* @__PURE__ */ new Set([
1142
1099
  "splice",
1143
1100
  "unshift"
1144
1101
  ]);
1145
- /** Resolve a direct call target, following simple function aliases. */
1146
1102
  function resolveToFunction(context, node, seen = /* @__PURE__ */ new Set()) {
1147
1103
  const expression = Extract.unwrap(node);
1148
1104
  if (Check.isFunction(expression)) return expression;
@@ -1222,22 +1178,11 @@ function createFactCollector$6() {
1222
1178
 
1223
1179
  //#endregion
1224
1180
  //#region src/rules/globals/origins.ts
1225
- /**
1226
- * Return whether an identifier is an unresolved global or is declared in the
1227
- * global/module scope.
1228
- */
1229
1181
  function isGlobalVariable(context, node) {
1230
1182
  const variable = findVariable(context.sourceCode.getScope(node), node);
1231
1183
  if (variable == null || variable.defs.length === 0) return true;
1232
1184
  return variable.scope.type === ScopeType.global || variable.scope.type === ScopeType.module;
1233
1185
  }
1234
- /**
1235
- * Resolve an object expression to the global/module binding it aliases.
1236
- *
1237
- * This intentionally follows only stable `const alias = value` declarations.
1238
- * It gives the rule useful Alias effects without pretending to perform full
1239
- * control-flow analysis for reassigned locals.
1240
- */
1241
1186
  function resolveGlobalOrigin(context, node, seen = /* @__PURE__ */ new Set()) {
1242
1187
  const expression = Extract.unwrap(node);
1243
1188
  if (seen.has(expression)) return null;
@@ -1257,11 +1202,6 @@ function resolveGlobalOrigin(context, node, seen = /* @__PURE__ */ new Set()) {
1257
1202
 
1258
1203
  //#endregion
1259
1204
  //#region src/rules/globals/effects.ts
1260
- /**
1261
- * Classify the collected writes and mutating method calls, keeping only the
1262
- * ones that reach a global/module binding, grouped by the function that
1263
- * performs them.
1264
- */
1265
1205
  function inferGlobalMutations(context, facts) {
1266
1206
  const directEffects = /* @__PURE__ */ new Map();
1267
1207
  function pushEffect(enclosingFunction, effect) {
@@ -1300,7 +1240,6 @@ function inferGlobalMutations(context, facts) {
1300
1240
  }
1301
1241
  return directEffects;
1302
1242
  }
1303
- /** Resolve the collected call edges into a function-to-function call graph. */
1304
1243
  function inferCallGraph$1(context, callEdges) {
1305
1244
  const callGraph = /* @__PURE__ */ new Map();
1306
1245
  for (const edge of callEdges) {
@@ -1312,11 +1251,6 @@ function inferCallGraph$1(context, callEdges) {
1312
1251
  }
1313
1252
  return callGraph;
1314
1253
  }
1315
- /**
1316
- * Like the SPEC's function signatures, these summaries keep creation of an
1317
- * effect separate from applying it in a component or hook render: walk the
1318
- * call graph from each render function and gather every reachable effect once.
1319
- */
1320
1254
  function collectReachableEffects(renderFunctions, directEffects, callGraph) {
1321
1255
  const visited = /* @__PURE__ */ new Set();
1322
1256
  const reported = /* @__PURE__ */ new Set();
@@ -1377,12 +1311,6 @@ function create$49(context) {
1377
1311
 
1378
1312
  //#endregion
1379
1313
  //#region src/rules/immutability/helpers.ts
1380
- /**
1381
- * Methods that mutate their receiver in place.
1382
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
1383
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
1384
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
1385
- */
1386
1314
  const KNOWN_MUTATING_METHODS = /* @__PURE__ */ new Set([
1387
1315
  "add",
1388
1316
  "clear",
@@ -1398,9 +1326,6 @@ const KNOWN_MUTATING_METHODS = /* @__PURE__ */ new Set([
1398
1326
  "splice",
1399
1327
  "unshift"
1400
1328
  ]);
1401
- /**
1402
- * Known mutating hooks.
1403
- */
1404
1329
  const KNOWN_MUTATING_HOOKS = /* @__PURE__ */ new Set([
1405
1330
  "useHistory",
1406
1331
  "useNavigate",
@@ -1571,17 +1496,6 @@ function createFactCollector$5() {
1571
1496
 
1572
1497
  //#endregion
1573
1498
  //#region src/rules/immutability/origins.ts
1574
- /**
1575
- * Classify whether a variable ultimately holds a value that must be treated as
1576
- * immutable: a component's props, a state value returned from `useState`-like or
1577
- * `useReducer` calls, a shallow copy (spread literal) of either, or a `for...of`
1578
- * iterator variable whose iterated collection resolves to one of those.
1579
- * @param context The rule context.
1580
- * @param variable The variable to classify.
1581
- * @param components The confirmed function component nodes in the file.
1582
- * @param seen Variables already visited during spread/iterator recursion.
1583
- * @returns The frozen origin, or `null` when the variable is not derived from one.
1584
- */
1585
1499
  function classifyFrozenOrigin(context, variable, components, seen = /* @__PURE__ */ new Set()) {
1586
1500
  if (seen.has(variable)) return null;
1587
1501
  seen.add(variable);
@@ -1835,12 +1749,6 @@ function create$47(context) {
1835
1749
 
1836
1750
  //#endregion
1837
1751
  //#region src/rules/no-array-index-key/lib.ts
1838
- /**
1839
- * Iterator-like methods that pass the item's index to their callback,
1840
- * mapped to the position of the index parameter in the callback's parameter list.
1841
- * `map` and `forEach` also cover `Children.map` and `Children.forEach`,
1842
- * whose callback is the second argument instead of the first.
1843
- */
1844
1752
  const INDEX_PARAM_POSITIONS$1 = /* @__PURE__ */ new Map([
1845
1753
  ["every", 1],
1846
1754
  ["filter", 1],
@@ -1855,13 +1763,6 @@ const INDEX_PARAM_POSITIONS$1 = /* @__PURE__ */ new Map([
1855
1763
  ["reduceRight", 2],
1856
1764
  ["some", 1]
1857
1765
  ]);
1858
- /**
1859
- * Checks whether an identifier is a reference to the index parameter of an
1860
- * iterator-like method's callback (e.g. `i` in `items.map((item, i) => ...)`).
1861
- * @param context The ESLint rule context.
1862
- * @param node The identifier to check.
1863
- * @returns `true` if the identifier resolves to an array index parameter.
1864
- */
1865
1766
  function isArrayIndexReference(context, node) {
1866
1767
  const def = findVariable(context.sourceCode.getScope(node), node)?.defs.at(0);
1867
1768
  if (def == null || def.type !== DefinitionType.Parameter) return false;
@@ -1882,12 +1783,6 @@ function isArrayIndexReference(context, node) {
1882
1783
  if (param == null) return false;
1883
1784
  return param === def.name || param.type === AST_NODE_TYPES.AssignmentPattern && param.left === def.name;
1884
1785
  }
1885
- /**
1886
- * Recursively collects all identifiers from a binary expression.
1887
- * e.g., for `a + b + c`, it returns identifiers for a, b, and c.
1888
- * @param side The binary expression (or one of its sides) to collect from.
1889
- * @returns The identifiers found in the expression.
1890
- */
1891
1786
  function getIdentifiersFromBinaryExpression(side) {
1892
1787
  if (Check.isIdentifier(side)) return [side];
1893
1788
  if (side.type === AST_NODE_TYPES.BinaryExpression) return [...getIdentifiersFromBinaryExpression(side.left), ...getIdentifiersFromBinaryExpression(side.right)];
@@ -1897,7 +1792,6 @@ function getIdentifiersFromBinaryExpression(side) {
1897
1792
  //#endregion
1898
1793
  //#region src/rules/no-array-index-key/no-array-index-key.ts
1899
1794
  const RULE_NAME$46 = "no-array-index-key";
1900
- /** Global functions that convert their first argument while preserving its identity as a key. */
1901
1795
  const COERCION_FUNCTIONS = /* @__PURE__ */ new Set(["Number", "String"]);
1902
1796
  var no_array_index_key_default = createRule({
1903
1797
  meta: {
@@ -1920,12 +1814,6 @@ function create$46(context) {
1920
1814
  if (!core.isCloneElementCall(context, node)) return null;
1921
1815
  return props?.type === AST_NODE_TYPES.ObjectExpression ? props : null;
1922
1816
  }
1923
- /**
1924
- * Checks an expression used as a 'key' value, recursing into the branches
1925
- * it may evaluate to and reporting every array index it is derived from.
1926
- * @param node The key value expression to check.
1927
- * @returns The report descriptors for the violations found.
1928
- */
1929
1817
  function visitKeyExpression(node) {
1930
1818
  switch (node.type) {
1931
1819
  case AST_NODE_TYPES.Identifier: return isArrayIndex(node) ? [{
@@ -2094,44 +1982,6 @@ function create$41(context) {
2094
1982
 
2095
1983
  //#endregion
2096
1984
  //#region ../../.pkgs/eff/dist/index.js
2097
- /**
2098
- * Applies a `pipe` method's variadic arguments to an initial value from left
2099
- * to right.
2100
- *
2101
- * **When to use**
2102
- *
2103
- * Use to implement a custom `.pipe(...)` method from JavaScript's `arguments`
2104
- * object.
2105
- *
2106
- * **Details**
2107
- *
2108
- * This helper is intended for implementing `Pipeable.pipe` methods that
2109
- * receive JavaScript's `arguments` object. With no functions it returns the
2110
- * original value; otherwise it feeds each result into the next function.
2111
- *
2112
- * **Example** (Implementing a pipe method)
2113
- *
2114
- * ```ts
2115
- * import { Pipeable } from "effect"
2116
- *
2117
- * class NumberBox {
2118
- * constructor(readonly value: number) {}
2119
- *
2120
- * pipe(..._fns: ReadonlyArray<(value: number) => number>): number {
2121
- * return Pipeable.pipeArguments(this.value, arguments) as number
2122
- * }
2123
- * }
2124
- *
2125
- * const result = new NumberBox(5).pipe(
2126
- * (n) => n + 2,
2127
- * (n) => n * 3
2128
- * )
2129
- * result // => 21
2130
- * ```
2131
- *
2132
- * @category combinators
2133
- * @since 2.0.0
2134
- */
2135
1985
  const pipeArguments = (self, args) => {
2136
1986
  switch (args.length) {
2137
1987
  case 0: return self;
@@ -2151,100 +2001,14 @@ const pipeArguments = (self, args) => {
2151
2001
  }
2152
2002
  }
2153
2003
  };
2154
- /**
2155
- * Reusable prototype that implements `Pipeable.pipe`.
2156
- *
2157
- * **When to use**
2158
- *
2159
- * Use when classes or object prototypes can reuse this value when they need the
2160
- * standard pipe implementation backed by `pipeArguments`.
2161
- *
2162
- * @category prototypes
2163
- * @since 3.15.0
2164
- */
2165
2004
  const Prototype = { pipe() {
2166
2005
  return pipeArguments(this, arguments);
2167
2006
  } };
2168
- /**
2169
- * Provides a base constructor whose instances implement the standard `Pipeable.pipe`
2170
- * method.
2171
- *
2172
- * **When to use**
2173
- *
2174
- * Use when you need to define a class that supports Effect-style method
2175
- * chaining through `.pipe(...)`.
2176
- *
2177
- * @category constructors
2178
- * @since 3.15.0
2179
- */
2180
2007
  const Class = (function() {
2181
2008
  function PipeableBase() {}
2182
2009
  PipeableBase.prototype = Prototype;
2183
2010
  return PipeableBase;
2184
2011
  })();
2185
- /**
2186
- * Creates a function that can be called in data-first style or data-last
2187
- * (`pipe`-friendly) style.
2188
- *
2189
- * **When to use**
2190
- *
2191
- * Use to expose one implementation through both direct and `pipe`-friendly
2192
- * call styles.
2193
- *
2194
- * **Details**
2195
- *
2196
- * Pass either the arity of the uncurried function or a predicate that decides
2197
- * whether the current call is data-first. Arity is the common case. Use a
2198
- * predicate when optional arguments make arity ambiguous.
2199
- *
2200
- * **Example** (Selecting data-first or data-last style by arity)
2201
- *
2202
- * ```ts
2203
- * import { Function, pipe } from "effect"
2204
- *
2205
- * const sum = Function.dual<
2206
- * (that: number) => (self: number) => number,
2207
- * (self: number, that: number) => number
2208
- * >(2, (self, that) => self + that)
2209
- *
2210
- * sum(2, 3) // => 5
2211
- * pipe(2, sum(3)) // => 5
2212
- * ```
2213
- *
2214
- * **Example** (Defining overloads with call signatures)
2215
- *
2216
- * ```ts
2217
- * import { Function, pipe } from "effect"
2218
- *
2219
- * const sum: {
2220
- * (that: number): (self: number) => number
2221
- * (self: number, that: number): number
2222
- * } = Function.dual(2, (self: number, that: number): number => self + that)
2223
- *
2224
- * sum(2, 3) // => 5
2225
- * pipe(2, sum(3)) // => 5
2226
- * ```
2227
- *
2228
- * **Example** (Selecting data-first or data-last style with a predicate)
2229
- *
2230
- * ```ts
2231
- * import { Function, pipe } from "effect"
2232
- *
2233
- * const sum = Function.dual<
2234
- * (that: number) => (self: number) => number,
2235
- * (self: number, that: number) => number
2236
- * >(
2237
- * (args) => args.length === 2,
2238
- * (self, that) => self + that
2239
- * )
2240
- *
2241
- * sum(2, 3) // => 5
2242
- * pipe(2, sum(3)) // => 5
2243
- * ```
2244
- *
2245
- * @category combinators
2246
- * @since 2.0.0
2247
- */
2248
2012
  const dual = function(arity, body) {
2249
2013
  if (typeof arity === "function") return function() {
2250
2014
  return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
@@ -2273,196 +2037,14 @@ const dual = function(arity, body) {
2273
2037
  };
2274
2038
  }
2275
2039
  };
2276
- /**
2277
- * Returns its input argument unchanged.
2278
- *
2279
- * **When to use**
2280
- *
2281
- * Use to return a value unchanged where a function is required.
2282
- *
2283
- * **Example** (Returning the same value)
2284
- *
2285
- * ```ts
2286
- * import { identity } from "effect"
2287
- *
2288
- * identity(5) // => 5
2289
- * ```
2290
- *
2291
- * @category combinators
2292
- * @since 2.0.0
2293
- */
2294
2040
  const identity = (a) => a;
2295
- /**
2296
- * Returns the input value with a different static type.
2297
- *
2298
- * **When to use**
2299
- *
2300
- * Use when you need an explicit type-level cast and accept that the value is
2301
- * returned unchanged at runtime.
2302
- *
2303
- * **Gotchas**
2304
- *
2305
- * This is a type-level cast only; it performs no runtime validation or
2306
- * conversion.
2307
- *
2308
- * @see {@link satisfies} for checking assignability without changing the resulting type
2309
- *
2310
- * @category utility types
2311
- * @since 4.0.0
2312
- */
2313
2041
  const cast = identity;
2314
- /**
2315
- * Creates a zero-argument function that always returns the provided value.
2316
- *
2317
- * **When to use**
2318
- *
2319
- * Use when you need a thunk or callback that returns the same value on every
2320
- * invocation.
2321
- *
2322
- * **Example** (Creating a constant thunk)
2323
- *
2324
- * ```ts
2325
- * import { Function } from "effect"
2326
- *
2327
- * const constNull = Function.constant(null)
2328
- *
2329
- * constNull() // => null
2330
- * constNull() // => null
2331
- * ```
2332
- *
2333
- * @category constructors
2334
- * @since 2.0.0
2335
- */
2336
2042
  const constant = (value) => () => value;
2337
- /**
2338
- * Returns `true` when called.
2339
- *
2340
- * **When to use**
2341
- *
2342
- * Use when you need a thunk that returns `true` on every invocation.
2343
- *
2344
- * **Example** (Returning true from a thunk)
2345
- *
2346
- * ```ts
2347
- * import { Function } from "effect"
2348
- *
2349
- * Function.constTrue() // => true
2350
- * ```
2351
- *
2352
- * @category constants
2353
- * @since 2.0.0
2354
- */
2355
2043
  const constTrue = constant(true);
2356
- /**
2357
- * Returns `false` when called.
2358
- *
2359
- * **When to use**
2360
- *
2361
- * Use when you need a thunk that returns `false` on every invocation.
2362
- *
2363
- * **Example** (Returning false from a thunk)
2364
- *
2365
- * ```ts
2366
- * import { Function } from "effect"
2367
- *
2368
- * Function.constFalse() // => false
2369
- * ```
2370
- *
2371
- * @category constants
2372
- * @since 2.0.0
2373
- */
2374
2044
  const constFalse = constant(false);
2375
- /**
2376
- * Returns `null` when called.
2377
- *
2378
- * **When to use**
2379
- *
2380
- * Use when you need a thunk that returns `null` on every invocation.
2381
- *
2382
- * **Example** (Returning null from a thunk)
2383
- *
2384
- * ```ts
2385
- * import { Function } from "effect"
2386
- *
2387
- * Function.constNull() // => null
2388
- * ```
2389
- *
2390
- * @category constants
2391
- * @since 2.0.0
2392
- */
2393
2045
  const constNull = constant(null);
2394
- /**
2395
- * Returns `undefined` when called.
2396
- *
2397
- * **When to use**
2398
- *
2399
- * Use when you need a thunk that returns `undefined` on every invocation.
2400
- *
2401
- * **Example** (Returning undefined from a thunk)
2402
- *
2403
- * ```ts
2404
- * import { Function } from "effect"
2405
- *
2406
- * Function.constUndefined() // => undefined
2407
- * ```
2408
- *
2409
- * @category constants
2410
- * @since 2.0.0
2411
- */
2412
2046
  const constUndefined = constant(void 0);
2413
- /**
2414
- * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
2415
- * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
2416
- *
2417
- * **When to use**
2418
- *
2419
- * Use to compose exactly two unary functions into a reusable unary function.
2420
- *
2421
- * **Example** (Composing two functions)
2422
- *
2423
- * ```ts
2424
- * import { Function } from "effect"
2425
- *
2426
- * const increment = (n: number) => n + 1
2427
- * const square = (n: number) => n * n
2428
- *
2429
- * Function.compose(increment, square)(2) // => 9
2430
- * ```
2431
- *
2432
- * @see {@link flow} for composing a left-to-right sequence of functions
2433
- * @see {@link pipe} for applying a value through a left-to-right sequence immediately
2434
- *
2435
- * @category combinators
2436
- * @since 2.0.0
2437
- */
2438
2047
  const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
2439
- /**
2440
- * Marks an impossible branch by accepting a `never` value and returning any
2441
- * type.
2442
- *
2443
- * **When to use**
2444
- *
2445
- * Use when you need a return value in a branch that exhaustive checks prove
2446
- * cannot be reached.
2447
- *
2448
- * **Gotchas**
2449
- *
2450
- * Calling `absurd` throws, because a value of type `never` should be
2451
- * impossible at runtime.
2452
- *
2453
- * **Example** (Handling impossible values)
2454
- *
2455
- * ```ts
2456
- * import { absurd } from "effect"
2457
- *
2458
- * const handleNever = (value: never) => {
2459
- * return absurd(value) // This will throw an error if called
2460
- * }
2461
- * ```
2462
- *
2463
- * @category utility types
2464
- * @since 2.0.0
2465
- */
2466
2048
  const absurd = (_) => {
2467
2049
  throw new Error("Called `absurd` function which should be uncallable");
2468
2050
  };
@@ -2495,372 +2077,26 @@ function flow(ab, bc, cd, de, ef, fg, gh, hi, ij) {
2495
2077
  };
2496
2078
  }
2497
2079
  }
2498
- /**
2499
- * Creates a compile-time placeholder for a value of any type.
2500
- *
2501
- * **When to use**
2502
- *
2503
- * Use as a temporary typed placeholder while developing incomplete code.
2504
- *
2505
- * **Gotchas**
2506
- *
2507
- * `hole` is intended for temporary development use. If the placeholder is
2508
- * evaluated at runtime, it throws.
2509
- *
2510
- * **Example** (Creating a development placeholder)
2511
- *
2512
- * ```ts
2513
- * import { hole } from "effect"
2514
- *
2515
- * // Intentionally not called: `hole` throws if the placeholder is evaluated.
2516
- * const buildUser = (id: number): { readonly id: number; readonly name: string } => ({
2517
- * id,
2518
- * name: hole<string>()
2519
- * })
2520
- *
2521
- * ```
2522
- *
2523
- * @category utility types
2524
- * @since 2.0.0
2525
- */
2526
2080
  const hole = cast(absurd);
2527
2081
  function not(predicate) {
2528
2082
  return (data) => !predicate(data);
2529
2083
  }
2530
- /**
2531
- * Creates a predicate that returns `true` only if both predicates are `true`.
2532
- *
2533
- * **When to use**
2534
- *
2535
- * Use when you want to combine `Predicate`s with AND, accepting values that
2536
- * satisfy multiple conditions, including refinements that narrow to an
2537
- * intersection.
2538
- *
2539
- * **Details**
2540
- *
2541
- * Evaluation short-circuits on the first `false`. For refinements, the output
2542
- * type is an intersection.
2543
- *
2544
- * **Example** (Checking both conditions)
2545
- *
2546
- * ```ts
2547
- * import { Predicate } from "effect"
2548
- *
2549
- * const hasAAndB = Predicate.and(
2550
- * Predicate.hasProperty("a"),
2551
- * Predicate.hasProperty("b")
2552
- * )
2553
- *
2554
- * const input: unknown = JSON.parse(`{"a":1,"b":"ok"}`)
2555
- * if (hasAAndB(input)) {
2556
- * // input has both properties at this point
2557
- * const a = input.a
2558
- * const b = input.b
2559
- *
2560
- * const values = [a, b] // => [1, "ok"]
2561
- * }
2562
- * ```
2563
- *
2564
- * @see {@link or}
2565
- * @see {@link not}
2566
- * @category combinators
2567
- * @since 2.0.0
2568
- */
2569
2084
  const and = dual(2, (a, b) => (data) => a(data) && b(data));
2570
- /**
2571
- * Creates a predicate that returns `true` if either predicate is `true`.
2572
- *
2573
- * **When to use**
2574
- *
2575
- * Use when you want to combine `Predicate`s with OR, accepting values that
2576
- * satisfy at least one condition, including refinements that narrow to a union.
2577
- *
2578
- * **Details**
2579
- *
2580
- * Evaluation short-circuits on the first `true`. For refinements, the output
2581
- * type is a union.
2582
- *
2583
- * **Example** (Checking either condition)
2584
- *
2585
- * ```ts
2586
- * import { Predicate } from "effect"
2587
- *
2588
- * const isStringOrNumber = Predicate.or(Predicate.isString, Predicate.isNumber)
2589
- *
2590
- * isStringOrNumber("a") // => true
2591
- * ```
2592
- *
2593
- * @see {@link and}
2594
- * @see {@link xor}
2595
- * @category combinators
2596
- * @since 2.0.0
2597
- */
2598
2085
  const or = dual(2, (a, b) => (data) => a(data) || b(data));
2599
- /**
2600
- * Creates a predicate that returns `true` if exactly one predicate is `true`.
2601
- *
2602
- * **When to use**
2603
- *
2604
- * Use when you want to combine two `Predicate`s with exclusive-or semantics.
2605
- *
2606
- * **Details**
2607
- *
2608
- * Returns `true` when results differ.
2609
- *
2610
- * **Example** (Checking exclusive-or conditions)
2611
- *
2612
- * ```ts
2613
- * import { Predicate } from "effect"
2614
- *
2615
- * const isEven = (n: number) => n % 2 === 0
2616
- * const isPositive = (n: number) => n > 0
2617
- * const either = Predicate.xor(isEven, isPositive)
2618
- *
2619
- * either(-2) // => true
2620
- * ```
2621
- *
2622
- * @see {@link or}
2623
- * @see {@link and}
2624
- * @category combinators
2625
- * @since 2.0.0
2626
- */
2627
2086
  const xor = dual(2, (a, b) => (data) => a(data) !== b(data));
2628
- /**
2629
- * Creates a predicate that returns `true` when both predicates agree.
2630
- *
2631
- * **When to use**
2632
- *
2633
- * Use when you want to check equivalence of two `Predicate`s.
2634
- *
2635
- * **Details**
2636
- *
2637
- * Returns `true` when both results are equal.
2638
- *
2639
- * **Example** (Defining equivalence)
2640
- *
2641
- * ```ts
2642
- * import { Predicate } from "effect"
2643
- *
2644
- * const isEven = (n: number) => n % 2 === 0
2645
- * const same = Predicate.eqv(isEven, isEven)
2646
- *
2647
- * same(3) // => true
2648
- * ```
2649
- *
2650
- * @see {@link xor}
2651
- * @category combinators
2652
- * @since 2.0.0
2653
- */
2654
2087
  const eqv = dual(2, (a, b) => (data) => a(data) === b(data));
2655
- /**
2656
- * Creates a predicate representing logical implication: if `antecedent`, then `consequent`.
2657
- *
2658
- * **When to use**
2659
- *
2660
- * Use when you need to encode logical implication between `Predicate` rules,
2661
- * where one rule only applies when a precondition holds.
2662
- *
2663
- * **Details**
2664
- *
2665
- * Models constraints like "if A then B" and returns `true` when the antecedent
2666
- * is `false`.
2667
- *
2668
- * **Example** (Checking implication)
2669
- *
2670
- * ```ts
2671
- * import { Predicate } from "effect"
2672
- *
2673
- * const isAdult = (age: number) => age >= 18
2674
- * const canVote = (age: number) => age >= 18
2675
- * const implies = Predicate.implies(isAdult, canVote)
2676
- *
2677
- * implies(16) // => true
2678
- * ```
2679
- *
2680
- * @see {@link and}
2681
- * @see {@link or}
2682
- * @category combinators
2683
- * @since 2.0.0
2684
- */
2685
2088
  const implies = dual(2, (antecedent, consequent) => (data) => !antecedent(data) || consequent(data));
2686
- /**
2687
- * Creates a predicate that returns `true` when neither predicate is `true`.
2688
- *
2689
- * **When to use**
2690
- *
2691
- * Use when you want to combine two `Predicate`s with logical NOR semantics.
2692
- *
2693
- * **Details**
2694
- *
2695
- * Returns the negation of `or`.
2696
- *
2697
- * **Example** (Checking NOR conditions)
2698
- *
2699
- * ```ts
2700
- * import { Predicate } from "effect"
2701
- *
2702
- * const neither = Predicate.nor(Predicate.isString, Predicate.isNumber)
2703
- *
2704
- * neither(true) // => true
2705
- * ```
2706
- *
2707
- * @see {@link or}
2708
- * @see {@link not}
2709
- * @category combinators
2710
- * @since 2.0.0
2711
- */
2712
2089
  const nor = dual(2, (a, b) => (data) => !a(data) && !b(data));
2713
- /**
2714
- * Creates a predicate that returns `true` unless both predicates are `true`.
2715
- *
2716
- * **When to use**
2717
- *
2718
- * Use when you want to combine two `Predicate`s with logical NAND semantics.
2719
- *
2720
- * **Details**
2721
- *
2722
- * Returns the negation of `and`.
2723
- *
2724
- * **Example** (Checking NAND conditions)
2725
- *
2726
- * ```ts
2727
- * import { Predicate } from "effect"
2728
- *
2729
- * const notBoth = Predicate.nand(Predicate.isString, Predicate.isNumber)
2730
- *
2731
- * notBoth("a") // => true
2732
- * ```
2733
- *
2734
- * @see {@link and}
2735
- * @see {@link not}
2736
- * @category combinators
2737
- * @since 2.0.0
2738
- */
2739
2090
  const nand = dual(2, (a, b) => (data) => !a(data) || !b(data));
2740
- /**
2741
- * Checks whether a value is a `string`.
2742
- *
2743
- * **When to use**
2744
- *
2745
- * Use when you need a `Predicate` guard to narrow an `unknown` value to a
2746
- * string.
2747
- *
2748
- * **Details**
2749
- *
2750
- * Uses `typeof input === "string"`.
2751
- *
2752
- * **Example** (Guarding strings)
2753
- *
2754
- * ```ts
2755
- * import { Predicate } from "effect"
2756
- *
2757
- * const data: unknown = "hi"
2758
- *
2759
- * if (Predicate.isString(data)) {
2760
- * data.toUpperCase() // => "HI"
2761
- * }
2762
- * ```
2763
- *
2764
- * @see {@link isNumber}
2765
- * @see {@link isBoolean}
2766
- * @see {@link Refinement}
2767
- * @category guards
2768
- * @since 2.0.0
2769
- */
2770
2091
  function isString(input) {
2771
2092
  return typeof input === "string";
2772
2093
  }
2773
- /**
2774
- * Checks whether a value is a `function`.
2775
- *
2776
- * **When to use**
2777
- *
2778
- * Use when you need a `Predicate` guard to narrow an `unknown` value to a
2779
- * callable function.
2780
- *
2781
- * **Details**
2782
- *
2783
- * Uses `typeof input === "function"`.
2784
- *
2785
- * **Example** (Guarding functions)
2786
- *
2787
- * ```ts
2788
- * import { Predicate } from "effect"
2789
- *
2790
- * const data: unknown = () => 1
2791
- *
2792
- * if (Predicate.isFunction(data)) {
2793
- * data() // => 1
2794
- * }
2795
- * ```
2796
- *
2797
- * @see {@link isObjectKeyword}
2798
- * @category guards
2799
- * @since 2.0.0
2800
- */
2801
2094
  function isFunction(input) {
2802
2095
  return typeof input === "function";
2803
2096
  }
2804
- /**
2805
- * Checks whether a value is an `object` in the JavaScript sense (objects, arrays, functions).
2806
- *
2807
- * **When to use**
2808
- *
2809
- * Use when you need a `Predicate` guard that accepts arrays and functions as
2810
- * well as objects.
2811
- *
2812
- * **Details**
2813
- *
2814
- * Returns `true` for arrays and functions, and `false` for `null`.
2815
- *
2816
- * **Example** (Checking object keywords)
2817
- *
2818
- * ```ts
2819
- * import { Predicate } from "effect"
2820
- *
2821
- * Predicate.isObjectKeyword(() => 1) // => true
2822
- * Predicate.isObjectKeyword(null) // => false
2823
- * ```
2824
- *
2825
- * @see {@link isObject}
2826
- * @see {@link isObjectOrArray}
2827
- * @category guards
2828
- * @since 4.0.0
2829
- */
2830
2097
  function isObjectKeyword(input) {
2831
2098
  return typeof input === "object" && input !== null || isFunction(input);
2832
2099
  }
2833
- /**
2834
- * Checks whether a value has a given property key.
2835
- *
2836
- * **When to use**
2837
- *
2838
- * Use when you need a `Predicate` guard for property access on `unknown`
2839
- * values with a simple structural object check.
2840
- *
2841
- * **Details**
2842
- *
2843
- * Uses the `in` operator and `isObjectKeyword`. This does not check property
2844
- * value types.
2845
- *
2846
- * **Example** (Guarding object properties)
2847
- *
2848
- * ```ts
2849
- * import { Predicate } from "effect"
2850
- *
2851
- * const hasName = Predicate.hasProperty("name")
2852
- * const data: unknown = { name: "Ada" }
2853
- *
2854
- * if (hasName(data)) {
2855
- * data.name // => "Ada"
2856
- * }
2857
- * ```
2858
- *
2859
- * @see {@link isTagged}
2860
- * @see {@link isObjectKeyword}
2861
- * @category guards
2862
- * @since 2.0.0
2863
- */
2864
2100
  const hasProperty = dual(2, (data, property) => isObjectKeyword(data) && property in data);
2865
2101
  function getOrInsertComputed(map, key, callback) {
2866
2102
  if (map.has(key)) return map.get(key);
@@ -2868,31 +2104,6 @@ function getOrInsertComputed(map, key, callback) {
2868
2104
  map.set(key, value);
2869
2105
  return value;
2870
2106
  }
2871
- /**
2872
- * Drops elements from the start while the predicate holds, returning the rest.
2873
- *
2874
- * **When to use**
2875
- *
2876
- * Use to remove a leading prefix of elements that satisfy a predicate.
2877
- *
2878
- * **Details**
2879
- *
2880
- * The predicate receives `(element, index)`.
2881
- *
2882
- * **Example** (Dropping while condition holds)
2883
- *
2884
- * ```ts
2885
- * import { Array } from "effect"
2886
- *
2887
- * Array.dropWhile([1, 2, 3, 4, 5], (x) => x < 4) // => [4, 5]
2888
- * ```
2889
- *
2890
- * @see {@link takeWhile} — keep the matching prefix instead
2891
- * @see {@link drop} — drop a fixed count
2892
- *
2893
- * @category getters
2894
- * @since 2.0.0
2895
- */
2896
2107
  const dropWhile = dual(2, (self, predicate) => {
2897
2108
  const input = Array.isArray(self) ? self : Array.from(self);
2898
2109
  const len = input.length;
@@ -2900,35 +2111,6 @@ const dropWhile = dual(2, (self, predicate) => {
2900
2111
  while (idx < len && predicate(input[idx], idx)) idx++;
2901
2112
  return input.slice(idx);
2902
2113
  });
2903
- /**
2904
- * Takes elements from the start while the predicate holds, stopping at the
2905
- * first element that fails.
2906
- *
2907
- * **When to use**
2908
- *
2909
- * Use to keep the leading elements of an iterable while each element satisfies
2910
- * a predicate, returning the retained prefix as an array.
2911
- *
2912
- * **Details**
2913
- *
2914
- * Supports refinements for type narrowing. The predicate receives
2915
- * `(element, index)`.
2916
- *
2917
- * **Example** (Taking while condition holds)
2918
- *
2919
- * ```ts
2920
- * import { Array } from "effect"
2921
- *
2922
- * Array.takeWhile([1, 3, 2, 4, 1, 2], (x) => x < 4) // => [1, 3, 2]
2923
- * ```
2924
- *
2925
- * @see {@link take} for keeping a fixed number of leading elements
2926
- * @see {@link dropWhile} for removing the matching prefix and keeping the rest
2927
- * @see {@link span} for splitting the matching prefix from the remaining elements
2928
- *
2929
- * @category getters
2930
- * @since 2.0.0
2931
- */
2932
2114
  const takeWhile = dual(2, (self, predicate) => {
2933
2115
  const input = Array.isArray(self) ? self : Array.from(self);
2934
2116
  const len = input.length;
@@ -3014,7 +2196,7 @@ function create$38(context) {
3014
2196
  const { body } = component.body;
3015
2197
  for (const member of body) if (core.isComponentWillMount(member)) context.report({
3016
2198
  fix(fixer) {
3017
- if (!("key" in member)) return null;
2199
+ if (!hasProperty(member, "key")) return null;
3018
2200
  return fixer.replaceText(member.key, "UNSAFE_componentWillMount");
3019
2201
  },
3020
2202
  messageId: "default",
@@ -3047,7 +2229,7 @@ function create$37(context) {
3047
2229
  const { body } = component.body;
3048
2230
  for (const member of body) if (core.isComponentWillReceiveProps(member)) context.report({
3049
2231
  fix(fixer) {
3050
- if (!("key" in member)) return null;
2232
+ if (!hasProperty(member, "key")) return null;
3051
2233
  return fixer.replaceText(member.key, "UNSAFE_componentWillReceiveProps");
3052
2234
  },
3053
2235
  messageId: "default",
@@ -3080,7 +2262,7 @@ function create$36(context) {
3080
2262
  const { body } = component.body;
3081
2263
  for (const member of body) if (core.isComponentWillUpdate(member)) context.report({
3082
2264
  fix(fixer) {
3083
- if (!("key" in member)) return null;
2265
+ if (!hasProperty(member, "key")) return null;
3084
2266
  return fixer.replaceText(member.key, "UNSAFE_componentWillUpdate");
3085
2267
  },
3086
2268
  messageId: "default",
@@ -3325,14 +2507,6 @@ function create$31(context) {
3325
2507
  });
3326
2508
  } };
3327
2509
  }
3328
- /**
3329
- * Determine whether the given CallExpression can be safely auto-fixed by replacing
3330
- * the usage of `forwardRef` with passing `ref` as a prop
3331
- *
3332
- * @param context The rule context object
3333
- * @param node The CallExpression node to check
3334
- * @returns True if the call can be auto-fixed, false otherwise
3335
- */
3336
2510
  function couldFix(context, node) {
3337
2511
  const { importSource } = getSettingsFromContext(context);
3338
2512
  const initialScope = context.sourceCode.getScope(node);
@@ -3343,12 +2517,6 @@ function couldFix(context, node) {
3343
2517
  default: return false;
3344
2518
  }
3345
2519
  }
3346
- /**
3347
- * Generates the fix for the `forwardRef` call
3348
- * @param context The rule context
3349
- * @param node The `forwardRef` call expression
3350
- * @returns A fixer function that applies the changes
3351
- */
3352
2520
  function buildFix(context, node) {
3353
2521
  return (fixer) => {
3354
2522
  const [componentNode] = node.arguments;
@@ -3360,14 +2528,6 @@ function buildFix(context, node) {
3360
2528
  ];
3361
2529
  };
3362
2530
  }
3363
- /**
3364
- * Generates fixes for the component's props and ref arguments
3365
- * @param context The rule context
3366
- * @param fixer The rule fixer
3367
- * @param node The function component node
3368
- * @param typeArguments The type arguments from the `forwardRef` call
3369
- * @returns An array of fixes for the component's signature
3370
- */
3371
2531
  function buildFixForComponentProps(context, fixer, node, typeArguments) {
3372
2532
  const getText = (node) => context.sourceCode.getText(node);
3373
2533
  const [arg0, arg1] = node.params;
@@ -3413,22 +2573,6 @@ function buildFixForComponentProps(context, fixer, node, typeArguments) {
3413
2573
 
3414
2574
  //#endregion
3415
2575
  //#region src/utils/create-implicit-prop-listener.ts
3416
- /**
3417
- * Creates a listener that detects JSX spread attributes implicitly passing a given prop
3418
- * (ex: 'children', 'key', 'ref') to a component.
3419
- *
3420
- * For each union constituent of the spread argument's type, the prop is reported unless:
3421
- * 1. The prop symbol's fully qualified name is allowed (pass-through of React internally defined props)
3422
- * 2. The fully qualified name of the prop's type symbol (or its alias) is allowed (React type aliases)
3423
- *
3424
- * @param context The ESLint rule context
3425
- * @param options The prop name, the allow-list predicates (receive lowercased fully qualified names), and the report callback
3426
- * @param options.name The name of the prop to detect
3427
- * @param options.isAllowedProp A predicate that receives the prop symbol's lowercased fully qualified name and returns `true` if it is allowed
3428
- * @param options.isAllowedType A predicate that receives the prop's type symbol's lowercased fully qualified name and returns `true` if it is allowed
3429
- * @param options.onImplicitProp A callback invoked with the spread attribute node when an implicit prop is detected
3430
- * @returns A rule listener reporting on JSX spread attributes
3431
- */
3432
2576
  function createImplicitPropListener(context, options) {
3433
2577
  const { name, isAllowedProp, isAllowedType, onImplicitProp } = options;
3434
2578
  const services = ESLintUtils.getParserServices(context, false);
@@ -3564,12 +2708,6 @@ function create$27(context) {
3564
2708
  ...compare(version, "18.0.0", "<") ? [] : ["string", "falsy string"]
3565
2709
  ];
3566
2710
  const services = ESLintUtils.getParserServices(context, false);
3567
- /**
3568
- * Recursively inspects a node to find potential leaked conditional rendering
3569
- * @param node The AST node to inspect
3570
- * @param seen A set of visited identifier names to prevent infinite recursion.
3571
- * @returns A report descriptor if a problem is found, otherwise `null`
3572
- */
3573
2711
  function visit(node, seen = /* @__PURE__ */ new Set()) {
3574
2712
  if (node == null) return null;
3575
2713
  if (Check.isJSXExpressionContainer(node)) return visit(node.expression, seen);
@@ -3707,21 +2845,11 @@ function create$25(context) {
3707
2845
 
3708
2846
  //#endregion
3709
2847
  //#region src/rules/no-missing-key/lib.ts
3710
- /**
3711
- * Iterator-like methods whose callback's return value becomes an item in a rendered list,
3712
- * mapped to the position of the callback in the call's argument list.
3713
- * `from` covers `Array.from(iterable, mapFn)`.
3714
- */
3715
2848
  const INDEX_PARAM_POSITIONS = /* @__PURE__ */ new Map([
3716
2849
  ["flatMap", 0],
3717
2850
  ["from", 1],
3718
2851
  ["map", 0]
3719
2852
  ]);
3720
- /**
3721
- * Gets the nested return statements in the node that are within the same function
3722
- * @param node The AST node
3723
- * @returns The nested return statements in the node
3724
- */
3725
2853
  function getNestedReturnStatements$1(node) {
3726
2854
  const statements = [];
3727
2855
  const boundary = Check.isFunction(node) ? node : Traverse.findParent(node, Check.isFunction);
@@ -3750,11 +2878,6 @@ var no_missing_key_default = createRule({
3750
2878
  create: create$24,
3751
2879
  defaultOptions: []
3752
2880
  });
3753
- /**
3754
- * Gets the mapping callback of an iterator-like call expression (e.g. `.map(cb)`, `.flatMap(cb)`, `Array.from(it, cb)`).
3755
- * @param node The call expression to inspect.
3756
- * @returns The callback function node, or `null` if the call is not an iterator-like call with a function callback.
3757
- */
3758
2881
  function getIteratorCallback(node) {
3759
2882
  const callee = Extract.unwrap(node.callee);
3760
2883
  if (callee.type !== AST_NODE_TYPES.MemberExpression) return null;
@@ -3767,12 +2890,6 @@ function getIteratorCallback(node) {
3767
2890
  }
3768
2891
  function create$24(context) {
3769
2892
  let childrenToArrayDepth = 0;
3770
- /**
3771
- * Checks an expression that is rendered as an item of a list,
3772
- * recursing into the branches it may evaluate to.
3773
- * @param node The expression to check.
3774
- * @returns The report descriptors for the violations found.
3775
- */
3776
2893
  function visitItemExpression(node) {
3777
2894
  switch (node.type) {
3778
2895
  case AST_NODE_TYPES.ChainExpression:
@@ -3794,12 +2911,6 @@ function create$24(context) {
3794
2911
  default: return [];
3795
2912
  }
3796
2913
  }
3797
- /**
3798
- * Checks every value an iterator callback may produce as a list item,
3799
- * whether from an expression body or from return statements in a block body.
3800
- * @param node The callback function to check.
3801
- * @returns The report descriptors for the violations found.
3802
- */
3803
2914
  function visitIteratorCallback(node) {
3804
2915
  if (node.body.type !== AST_NODE_TYPES.BlockStatement) return visitItemExpression(node.body);
3805
2916
  return getNestedReturnStatements$1(node.body).flatMap((stmt) => stmt.argument == null ? [] : visitItemExpression(stmt.argument));
@@ -3830,23 +2941,9 @@ function create$24(context) {
3830
2941
 
3831
2942
  //#endregion
3832
2943
  //#region src/rules/no-misused-capture-owner-stack/lib.ts
3833
- /**
3834
- * Check if the given node is a member expression that accesses `process.env.NODE_ENV`
3835
- * @param context The rule context
3836
- * @param node The AST node
3837
- * @returns True if the node is a member expression that accesses `process.env.NODE_ENV`, false otherwise
3838
- */
3839
2944
  function isProcessEnvNodeEnv(context, node) {
3840
2945
  return node != null && core.isAPI("process.env.NODE_ENV")(context, node);
3841
2946
  }
3842
- /**
3843
- * Check if the given node is a binary expression that compares `process.env.NODE_ENV` with a string literal.
3844
- * @param context The rule context
3845
- * @param node The AST node
3846
- * @param operator The operator used in the comparison
3847
- * @param value The string literal value to compare against
3848
- * @returns True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise
3849
- */
3850
2947
  function isProcessEnvNodeEnvCompare(context, node, operator, value) {
3851
2948
  if (node == null) return false;
3852
2949
  if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
@@ -3908,44 +3005,21 @@ function create$23(context) {
3908
3005
 
3909
3006
  //#endregion
3910
3007
  //#region src/rules/no-nested-component-definitions/lib.ts
3911
- /** Check if the node is a call expression to react-redux's `connect`. */
3912
3008
  const isConnectCall = core.isAPICall("connect");
3913
- /** Check if the node is a call expression to Relay's `createFragmentContainer`. */
3914
3009
  const isCreateFragmentContainerCall = core.isAPICall("createFragmentContainer");
3915
- /** Check if the node is a call expression to Relay's `createPaginationContainer`. */
3916
3010
  const isCreatePaginationContainerCall = core.isAPICall("createPaginationContainer");
3917
- /** Check if the node is a call expression to Relay's `createRefetchContainer`. */
3918
3011
  const isCreateRefetchContainerCall = core.isAPICall("createRefetchContainer");
3919
- /** Check if the node is a call expression to React's `forwardRef`. */
3920
3012
  const isForwardRefCall = core.isAPICall("forwardRef");
3921
- /** Check if the node is a call expression to a `graphql` tag function (e.g. from Relay or Apollo). */
3922
3013
  const isGraphqlCall = core.isAPICall("graphql");
3923
- /** Check if the node is a call expression to React's `memo`. */
3924
3014
  const isMemoCall = core.isAPICall("memo");
3925
- /** Check if the node is a call expression to MobX's `observer`. */
3926
3015
  const isObserverCall = core.isAPICall("observer");
3927
- /** Check if the node is a call expression to React's `useCallback`. */
3928
3016
  const isUseCallbackCall = core.isAPICall("useCallback");
3929
- /** Check if the node is a call expression to Formik's `withFormik`. */
3930
3017
  const isWithFormikCall = core.isAPICall("withFormik");
3931
- /** Check if the node is a call expression to recompose's `withHandlers`. */
3932
3018
  const isWithHandlersCall = core.isAPICall("withHandlers");
3933
- /** Check if the node is a call expression to recompose's `withLifecycle`. */
3934
3019
  const isWithLifecycleCall = core.isAPICall("withLifecycle");
3935
- /** Check if the node is a call expression to recompose's `withProps`. */
3936
3020
  const isWithPropsCall = core.isAPICall("withProps");
3937
- /** Check if the node is a call expression to react-router v5's `withRouter`. */
3938
3021
  const isWithRouterCall = core.isAPICall("withRouter");
3939
- /** Check if the node is a call expression to recompose's `withState`. */
3940
3022
  const isWithStateCall = core.isAPICall("withState");
3941
- /**
3942
- * Check if a call is a well-known component wrapper call (e.g. `memo`, `connect`, `withFormik`).
3943
- * Curried forms like `connect(...)(Component)` are matched via the innermost callee call.
3944
- * @param context The rule context
3945
- * @param call The call expression to check
3946
- * @param arg The function node passed to the call
3947
- * @returns `true` if the call is a component wrapper call
3948
- */
3949
3023
  function isComponentWrapperCall(context, call, arg) {
3950
3024
  if (Extract.unwrap(call.callee) === arg) return false;
3951
3025
  call = getInnermostCall(call);
@@ -3966,12 +3040,6 @@ function isComponentWrapperCall(context, call, arg) {
3966
3040
  if (isWithStateCall(context, call)) return true;
3967
3041
  return false;
3968
3042
  }
3969
- /**
3970
- * Unwrap curried call wrappers like `connect(...)(Component)` to get the innermost call expression.
3971
- * Type expressions and chain expressions around each callee are unwrapped along the way.
3972
- * @param node The outermost call expression to inspect.
3973
- * @returns The innermost call expression, whose callee is not itself a call expression.
3974
- */
3975
3043
  function getInnermostCall(node) {
3976
3044
  let call = node;
3977
3045
  let callee = Extract.unwrap(call.callee);
@@ -3981,12 +3049,6 @@ function getInnermostCall(node) {
3981
3049
  }
3982
3050
  return call;
3983
3051
  }
3984
- /**
3985
- * Resolve the name a function is bound to through wrapping calls (e.g. `const C = useCallback(...)` → `C`).
3986
- * @param context The rule context
3987
- * @param node The function node to resolve the bound name for
3988
- * @returns The bound name, or `null` if the call chain does not end at an identifier declarator
3989
- */
3990
3052
  function getWrapperCallBoundName(context, node) {
3991
3053
  let current = node;
3992
3054
  let parent = current.parent;
@@ -4005,20 +3067,9 @@ function getWrapperCallBoundName(context, node) {
4005
3067
  if (parent.type !== AST_NODE_TYPES.VariableDeclarator || !Check.isIdentifier(parent.id)) return null;
4006
3068
  return parent.id.name;
4007
3069
  }
4008
- /**
4009
- * Check if the node is inside a JSX attribute value
4010
- * @param node The AST node to check
4011
- * @returns `true` if the node is inside a JSX attribute value
4012
- */
4013
3070
  function isInsideJSXAttributeValue(node) {
4014
3071
  return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
4015
3072
  }
4016
- /**
4017
- * Check if the node is declared inside a class component's render block
4018
- * Ex: class C extends React.Component { render() { const Nested = () => <div />; } }
4019
- * @param node The AST node to check
4020
- * @returns `true` if the node is inside a class component's render block
4021
- */
4022
3073
  function isInsideRenderMethod(node) {
4023
3074
  return Traverse.findParent(node, (n) => core.isRenderMethodLike(n) && core.isClassComponent(n.parent.parent)) != null;
4024
3075
  }
@@ -4386,7 +3437,7 @@ function isContextName(name, isReact18OrBelow) {
4386
3437
  }
4387
3438
  function getHumanReadableKind$1(node) {
4388
3439
  if (node.type === AST_NODE_TYPES.Literal) {
4389
- if ("regex" in node) return "regexp literal";
3440
+ if (hasProperty(node, "regex")) return "regexp literal";
4390
3441
  if (node.value === null) return "null literal";
4391
3442
  return `${typeof node.value} literal`;
4392
3443
  }
@@ -4423,7 +3474,7 @@ function create$13(context) {
4423
3474
  if (enclosingFunction == null) return;
4424
3475
  if (compilationMode === "annotation" && core.isFunctionHasDirective(enclosingFunction, "use memo")) return;
4425
3476
  const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
4426
- if (attribute == null || !("value" in attribute)) return;
3477
+ if (attribute == null || !hasProperty(attribute, "value")) return;
4427
3478
  const value = attribute.value;
4428
3479
  if (value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
4429
3480
  const valueExpression = value.expression;
@@ -4461,7 +3512,7 @@ const SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR = [
4461
3512
  ].join("");
4462
3513
  function getHumanReadableKind(node) {
4463
3514
  if (node.type === AST_NODE_TYPES.Literal) {
4464
- if ("regex" in node) return "regexp literal";
3515
+ if (hasProperty(node, "regex")) return "regexp literal";
4465
3516
  if (node.value === null) return "null literal";
4466
3517
  return `${typeof node.value} literal`;
4467
3518
  }
@@ -4848,9 +3899,6 @@ function create$8(context) {
4848
3899
 
4849
3900
  //#endregion
4850
3901
  //#region src/rules/purity/lib.ts
4851
- /**
4852
- * Known impure functions
4853
- */
4854
3902
  const IMPURE_FUNCS = /* @__PURE__ */ new Map([
4855
3903
  ["Atomics", /* @__PURE__ */ new Set([
4856
3904
  "add",
@@ -5101,9 +4149,6 @@ const IMPURE_FUNCS = /* @__PURE__ */ new Map([
5101
4149
  "structuredClone"
5102
4150
  ])]
5103
4151
  ]);
5104
- /**
5105
- * Known impure global constructors used with `new`
5106
- */
5107
4152
  const IMPURE_CTORS = /* @__PURE__ */ new Set([
5108
4153
  "Audio",
5109
4154
  "AudioContext",
@@ -5129,9 +4174,6 @@ const IMPURE_CTORS = /* @__PURE__ */ new Set([
5129
4174
  "Worker",
5130
4175
  "XMLHttpRequest"
5131
4176
  ]);
5132
- /**
5133
- * Known pure functions
5134
- */
5135
4177
  const PURE_FUNCS = /* @__PURE__ */ new Map([
5136
4178
  ["Array", /* @__PURE__ */ new Set([
5137
4179
  "from",
@@ -5239,18 +4281,9 @@ const PURE_FUNCS = /* @__PURE__ */ new Map([
5239
4281
  function isCatalogObject(name) {
5240
4282
  return IMPURE_FUNCS.has(name) || PURE_FUNCS.has(name);
5241
4283
  }
5242
- /**
5243
- * Check if the program has a top-level `use client` directive, marking the
5244
- * module as a client module in React Server Components conventions.
5245
- */
5246
4284
  function hasUseClientDirective(program) {
5247
4285
  return program.body.some((stmt) => stmt.type === AST_NODE_TYPES.ExpressionStatement && stmt.directive === "use client");
5248
4286
  }
5249
- /**
5250
- * Find the property key under which `name` is bound in an object destructuring
5251
- * pattern, e.g. `"random"` for `random` in `const { random } = Math` or for
5252
- * `r` in `const { random: r } = Math`.
5253
- */
5254
4287
  function getDestructuredPropertyName(pattern, name) {
5255
4288
  for (const property of pattern.properties) {
5256
4289
  if (property.type !== AST_NODE_TYPES.Property) continue;
@@ -5259,13 +4292,6 @@ function getDestructuredPropertyName(pattern, name) {
5259
4292
  }
5260
4293
  return null;
5261
4294
  }
5262
- /**
5263
- * Resolve a member expression to a builtin object name and property, e.g.
5264
- * `window.Math.random` resolves to `{ object: "Math", property: "random" }`.
5265
- * Intermediate segments are followed only while they name known catalog
5266
- * objects (`window`, `Math`, ...), so unknown-global chains like
5267
- * `foo.Math.random` do not resolve.
5268
- */
5269
4295
  function resolveBuiltinMember(context, node, seen = /* @__PURE__ */ new Set()) {
5270
4296
  const chain = Extract.getMemberChain(node);
5271
4297
  const rootId = chain.at(0);
@@ -5285,17 +4311,6 @@ function resolveBuiltinMember(context, node, seen = /* @__PURE__ */ new Set()) {
5285
4311
  property: names.at(-1) ?? null
5286
4312
  };
5287
4313
  }
5288
- /**
5289
- * Recursively resolve an identifier to a builtin global object name and
5290
- * optional property. Follows simple assignment chains like `const M = Math`,
5291
- * member-function aliases like `const random = Math.random`, and destructured
5292
- * aliases like `const { random } = Math`.
5293
- * Returns `null` if the identifier is locally defined (parameter, import, function declaration, etc.)
5294
- * or resolves to a non-builtin source.
5295
- * @param context - The rule context.
5296
- * @param node - The identifier node to resolve.
5297
- * @param seen - A set of already visited identifier names to prevent infinite loops.
5298
- */
5299
4314
  function resolveBuiltinObjectName(context, node, seen = /* @__PURE__ */ new Set()) {
5300
4315
  if (seen.has(node.name)) return null;
5301
4316
  seen.add(node.name);
@@ -5467,13 +4482,6 @@ function getRefAccess(node) {
5467
4482
  node
5468
4483
  };
5469
4484
  }
5470
- /**
5471
- * Check whether `node` (a `ref.current` MemberExpression) is assigned through a
5472
- * destructuring pattern or a for-in/of loop target, e.g.
5473
- * `({ a: ref.current } = value)`, `[ref.current] = value`,
5474
- * `({ a: ref.current.x } = value)`, or `for (ref.current of items)`. Defaults
5475
- * and computed keys inside patterns are reads, not writes.
5476
- */
5477
4485
  function isPatternWriteTarget(node) {
5478
4486
  let child = node;
5479
4487
  let current = node.parent;
@@ -5500,10 +4508,6 @@ function isPatternWriteTarget(node) {
5500
4508
  current = current.parent;
5501
4509
  }
5502
4510
  }
5503
- /**
5504
- * Check whether `node` (a `ref.current` MemberExpression) is being written to indirectly through
5505
- * a nested property write, e.g. `ref.current.inner = value` or `ref.current.inner++`.
5506
- */
5507
4511
  function isNestedRefCurrentWrite(node) {
5508
4512
  let outer = node;
5509
4513
  let sawNesting = false;
@@ -5522,11 +4526,6 @@ function isNestedRefCurrentWrite(node) {
5522
4526
  return false;
5523
4527
  }
5524
4528
  }
5525
- /**
5526
- * Parse an exact nullish check and return the branch where the checked value is null/undefined.
5527
- * Truthiness checks such as `!ref.current` are deliberately excluded: falsy ref values are not
5528
- * necessarily uninitialized.
5529
- */
5530
4529
  function getNullCheckBranch(test, isCheckedValue, isNullishValue) {
5531
4530
  const unwrapped = Extract.unwrap(test);
5532
4531
  if (unwrapped.type === AST_NODE_TYPES.UnaryExpression && unwrapped.operator === "!") {
@@ -5565,7 +4564,6 @@ function getGuardDisposition(node, getNullBranch) {
5565
4564
  }
5566
4565
  return null;
5567
4566
  }
5568
- /** Return whether every path through a statement exits the current function. */
5569
4567
  function isUnconditionallyTerminating(statement) {
5570
4568
  switch (statement.type) {
5571
4569
  case AST_NODE_TYPES.ReturnStatement:
@@ -5599,14 +4597,6 @@ function isAfterTerminatingNonNullGuard(node, getNullBranch) {
5599
4597
 
5600
4598
  //#endregion
5601
4599
  //#region src/rules/refs/collect.ts
5602
- /**
5603
- * Collect the raw facts the refs rule reasons about: identifier/member/function
5604
- * bindings with their source positions, JSX `ref` attribute targets, call
5605
- * expressions, ref pass sites (calls, constructor calls, tagged templates), and
5606
- * every `.current` member access. Facts outside any function are never
5607
- * reachable during render and are not collected. All inference is deferred to
5608
- * `Program:exit`.
5609
- */
5610
4600
  function createFactCollector$4() {
5611
4601
  const facts = {
5612
4602
  bindings: [],
@@ -5706,11 +4696,9 @@ function createFactCollector$4() {
5706
4696
 
5707
4697
  //#endregion
5708
4698
  //#region src/rules/refs/effects.ts
5709
- /** The nearest strict ancestor of `node` that is a component or hook. */
5710
4699
  function findBoundary(node, boundaries) {
5711
4700
  return Traverse.findParent(node, (candidate) => Check.isFunction(candidate) && boundaries.has(candidate));
5712
4701
  }
5713
- /** The boundary containing `node`, where `node` is the nearest enclosing function of the fact. */
5714
4702
  function getBoundaryOf(node, boundaries) {
5715
4703
  return boundaries.has(node) ? node : findBoundary(node, boundaries);
5716
4704
  }
@@ -5718,12 +4706,6 @@ function isReachedDuringRender(node, boundary, reachability) {
5718
4706
  const reached = reachability.get(boundary);
5719
4707
  return reached != null && isReachedThroughFunctions(node, boundary, reached);
5720
4708
  }
5721
- /**
5722
- * Resolve the collected call edges into a per-boundary render call graph.
5723
- * Direct calls, IIFEs, known synchronous callbacks, function declarations,
5724
- * aliases, and simple object-property bindings all share the same
5725
- * identity-based resolver. Each call target is resolved exactly once.
5726
- */
5727
4709
  function inferCallGraph(boundaries, callEdges, resolveCallable) {
5728
4710
  const callGraph = /* @__PURE__ */ new Map();
5729
4711
  for (const edge of callEdges) {
@@ -5746,10 +4728,6 @@ function inferCallGraph(boundaries, callEdges, resolveCallable) {
5746
4728
  }
5747
4729
  return callGraph;
5748
4730
  }
5749
- /**
5750
- * Walk the call graph from each render boundary and gather every function
5751
- * reached during that boundary's render.
5752
- */
5753
4731
  function collectReachableFunctions(boundaries, callGraph) {
5754
4732
  const reachedByBoundary = /* @__PURE__ */ new Map();
5755
4733
  for (const boundary of boundaries) {
@@ -5766,10 +4744,6 @@ function collectReachableFunctions(boundaries, callGraph) {
5766
4744
  }
5767
4745
  return reachedByBoundary;
5768
4746
  }
5769
- /**
5770
- * Validate the reached `.current` accesses and track the one permitted lazy
5771
- * initialization per ref.
5772
- */
5773
4747
  function inferRefViolations(accesses, boundaries, reachability, resolver) {
5774
4748
  const violations = [];
5775
4749
  const initializedRefs = /* @__PURE__ */ new Map();
@@ -5806,31 +4780,18 @@ function inferRefViolations(accesses, boundaries, reachability, resolver) {
5806
4780
  }
5807
4781
  return violations;
5808
4782
  }
5809
- /**
5810
- * Get the statically known name of a pass-site callee, whether it is a plain
5811
- * call, a constructor call, or a tagged template.
5812
- */
5813
4783
  function getPassSiteCalleeName(node) {
5814
4784
  const callee = Extract.unwrap(node.type === AST_NODE_TYPES.TaggedTemplateExpression ? node.tag : node.callee);
5815
4785
  if (Check.isIdentifier(callee)) return callee.name;
5816
4786
  if (callee.type === AST_NODE_TYPES.MemberExpression && !callee.computed && Check.isIdentifier(callee.property)) return callee.property.name;
5817
4787
  return null;
5818
4788
  }
5819
- /**
5820
- * The `mergeRefs` exemption is name-based but alias-aware: a simple variable
5821
- * alias of a `mergeRefs` binding keeps the exemption.
5822
- */
5823
4789
  function isMergeRefsCallee(callee, calleeName, position, resolver) {
5824
4790
  if (calleeName === "mergeRefs") return true;
5825
4791
  if (callee.type !== AST_NODE_TYPES.Identifier) return false;
5826
4792
  const variable = resolver.getVariable(callee);
5827
4793
  return variable != null && resolver.resolveAliasTarget(variable, position).name === "mergeRefs";
5828
4794
  }
5829
- /**
5830
- * Passing a ref to an unknown function can expose its value during render.
5831
- * Hook callbacks, mergeRefs, and the existing render-prop compatibility case
5832
- * remain exempt.
5833
- */
5834
4795
  function inferRefPassViolations(passSites, boundaries, reachability, resolver) {
5835
4796
  const violations = [];
5836
4797
  for (const site of passSites) {
@@ -5860,11 +4821,6 @@ function inferRefPassViolations(passSites, boundaries, reachability, resolver) {
5860
4821
 
5861
4822
  //#endregion
5862
4823
  //#region src/rules/refs/origins.ts
5863
- /**
5864
- * Resolve which variables hold refs and which resolve to callable functions.
5865
- * Maps are keyed by ESLint variables, not source names, so shadowed
5866
- * identifiers and separate components cannot contaminate each other.
5867
- */
5868
4824
  function createBindingResolver(context, facts) {
5869
4825
  const { additionalRefHooks } = getSettingsFromContext(context);
5870
4826
  const bindings = /* @__PURE__ */ new Map();
@@ -5957,11 +4913,6 @@ function createBindingResolver(context, facts) {
5957
4913
  case "unknown": return null;
5958
4914
  }
5959
4915
  }
5960
- /**
5961
- * Follow simple variable-to-variable aliases to the terminal variable, e.g.
5962
- * `const combine = mergeRefs` resolves to the `mergeRefs` variable itself.
5963
- * Position-aware, so a reassigned alias resolves to its latest source.
5964
- */
5965
4916
  function resolveAliasTarget(variable, position, seen = /* @__PURE__ */ new Set()) {
5966
4917
  if (seen.has(variable)) return variable;
5967
4918
  seen.add(variable);
@@ -6073,38 +5024,17 @@ function create$6(context) {
6073
5024
  function assert(cond, message) {
6074
5025
  if (!cond) throw new Error(message ?? "Assertion violated.");
6075
5026
  }
6076
- /**
6077
- * Checks whether or not a given segment is reachable.
6078
- */
6079
5027
  function isReachable$1(segment) {
6080
5028
  return segment.reachable;
6081
5029
  }
6082
- /**
6083
- * A code path segment.
6084
- */
6085
5030
  var CodePathSegment = class CodePathSegment {
6086
- /**
6087
- * The identifier of this code path.
6088
- * Rules use it to store additional information of each rule.
6089
- */
6090
5031
  id;
6091
- /** An array of the next reachable segments. */
6092
5032
  nextSegments;
6093
- /** An array of the previous reachable segments. */
6094
5033
  prevSegments;
6095
- /** An array of all next segments (including unreachable). */
6096
5034
  allNextSegments;
6097
- /** An array of all previous segments (including unreachable). */
6098
5035
  allPrevSegments;
6099
- /** Whether this segment is reachable. */
6100
5036
  reachable;
6101
- /** Internal bookkeeping data. */
6102
5037
  internal;
6103
- /**
6104
- * @param id An identifier.
6105
- * @param allPrevSegments An array of the previous segments (including unreachable).
6106
- * @param reachable Whether this segment is reachable.
6107
- */
6108
5038
  constructor(id, allPrevSegments, reachable) {
6109
5039
  this.id = id;
6110
5040
  this.nextSegments = [];
@@ -6117,44 +5047,23 @@ var CodePathSegment = class CodePathSegment {
6117
5047
  loopedPrevSegments: []
6118
5048
  };
6119
5049
  }
6120
- /**
6121
- * Checks if a given previous segment is coming from the end of a loop.
6122
- */
6123
5050
  isLoopedPrevSegment(segment) {
6124
5051
  return this.internal.loopedPrevSegments.includes(segment);
6125
5052
  }
6126
- /**
6127
- * Creates the root segment.
6128
- */
6129
5053
  static newRoot(id) {
6130
5054
  return new CodePathSegment(id, [], true);
6131
5055
  }
6132
- /**
6133
- * Creates a segment that follows given segments.
6134
- */
6135
5056
  static newNext(id, allPrevSegments) {
6136
5057
  return new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), allPrevSegments.some(isReachable$1));
6137
5058
  }
6138
- /**
6139
- * Creates an unreachable segment that follows given segments.
6140
- */
6141
5059
  static newUnreachable(id, allPrevSegments) {
6142
5060
  const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false);
6143
5061
  CodePathSegment.markUsed(segment);
6144
5062
  return segment;
6145
5063
  }
6146
- /**
6147
- * Creates a segment that follows given segments.
6148
- * This factory method does not connect with `allPrevSegments`.
6149
- * But this inherits `reachable` flag.
6150
- */
6151
5064
  static newDisconnected(id, allPrevSegments) {
6152
5065
  return new CodePathSegment(id, [], allPrevSegments.some(isReachable$1));
6153
5066
  }
6154
- /**
6155
- * Makes a given segment being used.
6156
- * Also registers the segment into the previous segments as a next.
6157
- */
6158
5067
  static markUsed(segment) {
6159
5068
  if (segment.internal.used) return;
6160
5069
  segment.internal.used = true;
@@ -6166,15 +5075,9 @@ var CodePathSegment = class CodePathSegment {
6166
5075
  }
6167
5076
  else for (i = 0; i < segment.allPrevSegments.length; ++i) segment.allPrevSegments[i].allNextSegments.push(segment);
6168
5077
  }
6169
- /**
6170
- * Marks a previous segment as looped.
6171
- */
6172
5078
  static markPrevSegmentAsLooped(segment, prevSegment) {
6173
5079
  segment.internal.loopedPrevSegments.push(prevSegment);
6174
5080
  }
6175
- /**
6176
- * Replaces unused segments with the previous segments of each unused segment.
6177
- */
6178
5081
  static flattenUnusedSegments(segments) {
6179
5082
  const done = Object.create(null);
6180
5083
  const retv = [];
@@ -6196,19 +5099,9 @@ var CodePathSegment = class CodePathSegment {
6196
5099
  return retv;
6197
5100
  }
6198
5101
  };
6199
- /**
6200
- * Gets whether or not a given segment is reachable.
6201
- */
6202
5102
  function isReachable(segment) {
6203
5103
  return segment.reachable;
6204
5104
  }
6205
- /**
6206
- * Creates new segments from the specific range of `context.segmentsList`.
6207
- *
6208
- * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and
6209
- * `end` is `-1`, this creates `[g, h]`. This `g` is from `a`, `c`, and `e`.
6210
- * This `h` is from `b`, `d`, and `f`.
6211
- */
6212
5105
  function makeSegments(context, begin, end, create) {
6213
5106
  const list = context.segmentsList;
6214
5107
  const normalizedBegin = begin >= 0 ? begin : list.length + begin;
@@ -6221,12 +5114,6 @@ function makeSegments(context, begin, end, create) {
6221
5114
  }
6222
5115
  return segments;
6223
5116
  }
6224
- /**
6225
- * `segments` becomes doubly in a `finally` block. Then if a code path exits by a
6226
- * control statement (such as `break`, `continue`) from the `finally` block, the
6227
- * destination's segments may be half of the source segments. In that case, this
6228
- * merges segments.
6229
- */
6230
5117
  function mergeExtraSegments(context, segments) {
6231
5118
  let currentSegments = segments;
6232
5119
  while (currentSegments.length > context.count) {
@@ -6236,9 +5123,6 @@ function mergeExtraSegments(context, segments) {
6236
5123
  }
6237
5124
  return currentSegments;
6238
5125
  }
6239
- /**
6240
- * A class to manage forking.
6241
- */
6242
5126
  var ForkContext = class ForkContext {
6243
5127
  idGenerator;
6244
5128
  upper;
@@ -6250,91 +5134,51 @@ var ForkContext = class ForkContext {
6250
5134
  this.count = count;
6251
5135
  this.segmentsList = [];
6252
5136
  }
6253
- /** The head segments. */
6254
5137
  get head() {
6255
5138
  const list = this.segmentsList;
6256
5139
  return list.length === 0 ? [] : list[list.length - 1];
6257
5140
  }
6258
- /** Whether the segments list is empty. */
6259
5141
  get empty() {
6260
5142
  return this.segmentsList.length === 0;
6261
5143
  }
6262
- /** Whether any head segment is reachable. */
6263
5144
  get reachable() {
6264
5145
  const segments = this.head;
6265
5146
  return segments.length > 0 && segments.some(isReachable);
6266
5147
  }
6267
- /**
6268
- * Creates new segments from this context.
6269
- */
6270
5148
  makeNext(begin, end) {
6271
5149
  return makeSegments(this, begin, end, CodePathSegment.newNext);
6272
5150
  }
6273
- /**
6274
- * Creates new unreachable segments from this context.
6275
- */
6276
5151
  makeUnreachable(begin, end) {
6277
5152
  return makeSegments(this, begin, end, CodePathSegment.newUnreachable);
6278
5153
  }
6279
- /**
6280
- * Creates new disconnected segments from this context.
6281
- * The new segments don't have connections for previous segments,
6282
- * but inherit the reachable flag.
6283
- */
6284
5154
  makeDisconnected(begin, end) {
6285
5155
  return makeSegments(this, begin, end, CodePathSegment.newDisconnected);
6286
5156
  }
6287
- /**
6288
- * Adds segments into this context. The added segments become the head.
6289
- */
6290
5157
  add(segments) {
6291
5158
  assert(segments.length >= this.count, `${segments.length} >= ${this.count}`);
6292
5159
  this.segmentsList.push(mergeExtraSegments(this, segments));
6293
5160
  }
6294
- /**
6295
- * Replaces the head segments with given segments.
6296
- * The current head segments are removed.
6297
- */
6298
5161
  replaceHead(segments) {
6299
5162
  assert(segments.length >= this.count, `${segments.length} >= ${this.count}`);
6300
5163
  this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments));
6301
5164
  }
6302
- /**
6303
- * Adds all segments of a given fork context into this context.
6304
- */
6305
5165
  addAll(context) {
6306
5166
  assert(context.count === this.count);
6307
5167
  const source = context.segmentsList;
6308
5168
  for (let i = 0; i < source.length; ++i) this.segmentsList.push(source[i]);
6309
5169
  }
6310
- /**
6311
- * Clears all segments in this context.
6312
- */
6313
5170
  clear() {
6314
5171
  this.segmentsList = [];
6315
5172
  }
6316
- /**
6317
- * Creates the root fork context.
6318
- */
6319
5173
  static newRoot(idGenerator) {
6320
5174
  const context = new ForkContext(idGenerator, null, 1);
6321
5175
  context.add([CodePathSegment.newRoot(idGenerator.next())]);
6322
5176
  return context;
6323
5177
  }
6324
- /**
6325
- * Creates an empty fork context preceded by a given context.
6326
- */
6327
5178
  static newEmpty(parentContext, forkLeavingPath) {
6328
5179
  return new ForkContext(parentContext.idGenerator, parentContext, (forkLeavingPath ? 2 : 1) * parentContext.count);
6329
5180
  }
6330
5181
  };
6331
- /**
6332
- * Adds given segments into the `dest` array.
6333
- * If the `others` array does not include the given segments, adds to the `all`
6334
- * array as well.
6335
- *
6336
- * This adds only reachable and used segments.
6337
- */
6338
5182
  function addToReturnedOrThrown(dest, others, all, segments) {
6339
5183
  for (let i = 0; i < segments.length; ++i) {
6340
5184
  const segment = segments[i];
@@ -6342,9 +5186,6 @@ function addToReturnedOrThrown(dest, others, all, segments) {
6342
5186
  if (!others.includes(segment)) all.push(segment);
6343
5187
  }
6344
5188
  }
6345
- /**
6346
- * Gets a loop-context for a `continue` statement.
6347
- */
6348
5189
  function getContinueContext(state, label) {
6349
5190
  if (!label) return state.loopContext;
6350
5191
  let context = state.loopContext;
@@ -6355,9 +5196,6 @@ function getContinueContext(state, label) {
6355
5196
  /* c8 ignore next */
6356
5197
  return null;
6357
5198
  }
6358
- /**
6359
- * Gets a context for a `break` statement.
6360
- */
6361
5199
  function getBreakContext(state, label) {
6362
5200
  let context = state.breakContext;
6363
5201
  while (context) {
@@ -6367,9 +5205,6 @@ function getBreakContext(state, label) {
6367
5205
  /* c8 ignore next */
6368
5206
  return null;
6369
5207
  }
6370
- /**
6371
- * Gets a context for a `return` statement.
6372
- */
6373
5208
  function getReturnContext(state) {
6374
5209
  let context = state.tryContext;
6375
5210
  while (context) {
@@ -6378,9 +5213,6 @@ function getReturnContext(state) {
6378
5213
  }
6379
5214
  return state;
6380
5215
  }
6381
- /**
6382
- * Gets a context for a `throw` statement.
6383
- */
6384
5216
  function getThrowContext(state) {
6385
5217
  let context = state.tryContext;
6386
5218
  while (context) {
@@ -6389,19 +5221,9 @@ function getThrowContext(state) {
6389
5221
  }
6390
5222
  return state;
6391
5223
  }
6392
- /**
6393
- * Removes a given element from a given array.
6394
- */
6395
5224
  function remove(xs, x) {
6396
5225
  xs.splice(xs.indexOf(x), 1);
6397
5226
  }
6398
- /**
6399
- * Disconnect given segments.
6400
- *
6401
- * This is used in a process for switch statements.
6402
- * If there is the "default" chunk before other cases, the order is different
6403
- * between node's and running's.
6404
- */
6405
5227
  function removeConnection(prevSegments, nextSegments) {
6406
5228
  for (let i = 0; i < prevSegments.length; ++i) {
6407
5229
  const prevSegment = prevSegments[i];
@@ -6412,9 +5234,6 @@ function removeConnection(prevSegments, nextSegments) {
6412
5234
  remove(nextSegment.allPrevSegments, prevSegment);
6413
5235
  }
6414
5236
  }
6415
- /**
6416
- * Creates looping path.
6417
- */
6418
5237
  function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) {
6419
5238
  const fromSegments = CodePathSegment.flattenUnusedSegments(unflattenedFromSegments);
6420
5239
  const toSegments = CodePathSegment.flattenUnusedSegments(unflattenedToSegments);
@@ -6430,12 +5249,6 @@ function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) {
6430
5249
  state.notifyLooped(fromSegment, toSegment);
6431
5250
  }
6432
5251
  }
6433
- /**
6434
- * Finalizes segments of `test` chunk of a ForStatement.
6435
- *
6436
- * - Adds `false` paths to paths which are leaving from the loop.
6437
- * - Sets `true` paths to paths which go to the body.
6438
- */
6439
5252
  function finalizeTestSegmentsOfFor(context, choiceContext, head) {
6440
5253
  if (!choiceContext.processed) {
6441
5254
  choiceContext.trueForkContext.add(head);
@@ -6445,9 +5258,6 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
6445
5258
  if (context.test !== true) context.brokenForkContext.addAll(choiceContext.falseForkContext);
6446
5259
  context.endOfTestSegments = choiceContext.trueForkContext.makeNext(0, -1);
6447
5260
  }
6448
- /**
6449
- * A class which manages state to analyze code paths.
6450
- */
6451
5261
  var CodePathState = class {
6452
5262
  idGenerator;
6453
5263
  notifyLooped;
@@ -6484,60 +5294,29 @@ var CodePathState = class {
6484
5294
  returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final);
6485
5295
  thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final);
6486
5296
  }
6487
- /** The head segments. */
6488
5297
  get headSegments() {
6489
5298
  return this.forkContext.head;
6490
5299
  }
6491
- /**
6492
- * The parent forking context.
6493
- * This is used for the root of new forks.
6494
- */
6495
5300
  get parentForkContext() {
6496
5301
  const current = this.forkContext;
6497
5302
  return current && current.upper;
6498
5303
  }
6499
- /**
6500
- * Creates and stacks new forking context.
6501
- */
6502
5304
  pushForkContext(forkLeavingPath) {
6503
5305
  this.forkContext = ForkContext.newEmpty(this.forkContext, forkLeavingPath);
6504
5306
  return this.forkContext;
6505
5307
  }
6506
- /**
6507
- * Pops and merges the last forking context.
6508
- */
6509
5308
  popForkContext() {
6510
5309
  const lastContext = this.forkContext;
6511
5310
  this.forkContext = lastContext.upper;
6512
5311
  this.forkContext.replaceHead(lastContext.makeNext(0, -1));
6513
5312
  return lastContext;
6514
5313
  }
6515
- /**
6516
- * Creates a new path.
6517
- */
6518
5314
  forkPath() {
6519
5315
  this.forkContext.add(this.parentForkContext.makeNext(-1, -1));
6520
5316
  }
6521
- /**
6522
- * Creates a bypass path.
6523
- * This is used for such as IfStatement which does not have "else" chunk.
6524
- */
6525
5317
  forkBypassPath() {
6526
5318
  this.forkContext.add(this.parentForkContext.head);
6527
5319
  }
6528
- /**
6529
- * Creates a context for ConditionalExpression, LogicalExpression,
6530
- * AssignmentExpression (logical assignments only), IfStatement,
6531
- * WhileStatement, DoWhileStatement, or ForStatement.
6532
- *
6533
- * @param kind A kind string.
6534
- * If the new context is LogicalExpression's or AssignmentExpression's,
6535
- * this is `"&&"` or `"||"` or `"??"`.
6536
- * If it's IfStatement's or ConditionalExpression's, this is `"test"`.
6537
- * Otherwise, this is `"loop"`.
6538
- * @param isForkingAsResult A flag that shows that goes different
6539
- * paths between `true` and `false`.
6540
- */
6541
5320
  pushChoiceContext(kind, isForkingAsResult) {
6542
5321
  this.choiceContext = {
6543
5322
  upper: this.choiceContext,
@@ -6549,9 +5328,6 @@ var CodePathState = class {
6549
5328
  processed: false
6550
5329
  };
6551
5330
  }
6552
- /**
6553
- * Pops the last choice context and finalizes it.
6554
- */
6555
5331
  popChoiceContext() {
6556
5332
  const context = this.choiceContext;
6557
5333
  this.choiceContext = context.upper;
@@ -6592,10 +5368,6 @@ var CodePathState = class {
6592
5368
  forkContext.replaceHead(prevForkContext.makeNext(0, -1));
6593
5369
  return context;
6594
5370
  }
6595
- /**
6596
- * Makes a code path segment of the right-hand operand of a logical
6597
- * expression.
6598
- */
6599
5371
  makeLogicalRight() {
6600
5372
  const context = this.choiceContext;
6601
5373
  const forkContext = this.forkContext;
@@ -6633,9 +5405,6 @@ var CodePathState = class {
6633
5405
  forkContext.replaceHead(forkContext.makeNext(-1, -1));
6634
5406
  }
6635
5407
  }
6636
- /**
6637
- * Makes a code path segment of the `if` block.
6638
- */
6639
5408
  makeIfConsequent() {
6640
5409
  const context = this.choiceContext;
6641
5410
  const forkContext = this.forkContext;
@@ -6647,9 +5416,6 @@ var CodePathState = class {
6647
5416
  context.processed = false;
6648
5417
  forkContext.replaceHead(context.trueForkContext.makeNext(0, -1));
6649
5418
  }
6650
- /**
6651
- * Makes a code path segment of the `else` block.
6652
- */
6653
5419
  makeIfAlternate() {
6654
5420
  const context = this.choiceContext;
6655
5421
  const forkContext = this.forkContext;
@@ -6658,50 +5424,26 @@ var CodePathState = class {
6658
5424
  context.processed = true;
6659
5425
  forkContext.replaceHead(context.falseForkContext.makeNext(0, -1));
6660
5426
  }
6661
- /**
6662
- * Push a new `ChainExpression` context to the stack.
6663
- * This method is called on entering to each `ChainExpression` node.
6664
- * This context is used to count forking in the optional chain then merge
6665
- * them on exiting from the `ChainExpression` node.
6666
- */
6667
5427
  pushChainContext() {
6668
5428
  this.chainContext = {
6669
5429
  upper: this.chainContext,
6670
5430
  countChoiceContexts: 0
6671
5431
  };
6672
5432
  }
6673
- /**
6674
- * Pop a `ChainExpression` context from the stack.
6675
- * This method is called on exiting from each `ChainExpression` node.
6676
- * This merges all forks of the last optional chaining.
6677
- */
6678
5433
  popChainContext() {
6679
5434
  const context = this.chainContext;
6680
5435
  this.chainContext = context.upper;
6681
5436
  for (let i = context.countChoiceContexts; i > 0; --i) this.popChoiceContext();
6682
5437
  }
6683
- /**
6684
- * Create a choice context for optional access.
6685
- * This method is called on entering to each `(Call|Member)Expression[optional=true]` node.
6686
- * This creates a choice context as similar to `LogicalExpression[operator="??"]` node.
6687
- */
6688
5438
  makeOptionalNode() {
6689
5439
  if (this.chainContext) {
6690
5440
  this.chainContext.countChoiceContexts += 1;
6691
5441
  this.pushChoiceContext("??", false);
6692
5442
  }
6693
5443
  }
6694
- /**
6695
- * Create a fork.
6696
- * This method is called on entering to the `arguments|property` property
6697
- * of each `(Call|Member)Expression` node.
6698
- */
6699
5444
  makeOptionalRight() {
6700
5445
  if (this.chainContext) this.makeLogicalRight();
6701
5446
  }
6702
- /**
6703
- * Creates a context object of SwitchStatement and stacks it.
6704
- */
6705
5447
  pushSwitchContext(hasCase, label) {
6706
5448
  this.switchContext = {
6707
5449
  upper: this.switchContext,
@@ -6714,14 +5456,6 @@ var CodePathState = class {
6714
5456
  };
6715
5457
  this.pushBreakContext(true, label);
6716
5458
  }
6717
- /**
6718
- * Pops the last context of SwitchStatement and finalizes it.
6719
- *
6720
- * - Disposes all forking stack for `case` and `default`.
6721
- * - Creates the next code path segment from `context.brokenForkContext`.
6722
- * - If the last `SwitchCase` node is not a `default` part, creates a path
6723
- * to the `default` body.
6724
- */
6725
5459
  popSwitchContext() {
6726
5460
  const context = this.switchContext;
6727
5461
  this.switchContext = context.upper;
@@ -6747,9 +5481,6 @@ var CodePathState = class {
6747
5481
  for (let i = 0; i < context.countForks; ++i) this.forkContext = this.forkContext.upper;
6748
5482
  this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
6749
5483
  }
6750
- /**
6751
- * Makes a code path segment for a `SwitchCase` node.
6752
- */
6753
5484
  makeSwitchCaseBody(isEmpty, isDefault) {
6754
5485
  const context = this.switchContext;
6755
5486
  if (!context.hasCase) return;
@@ -6767,9 +5498,6 @@ var CodePathState = class {
6767
5498
  context.lastIsDefault = isDefault;
6768
5499
  context.countForks += 1;
6769
5500
  }
6770
- /**
6771
- * Creates a context object of TryStatement and stacks it.
6772
- */
6773
5501
  pushTryContext(hasFinalizer) {
6774
5502
  this.tryContext = {
6775
5503
  upper: this.tryContext,
@@ -6781,9 +5509,6 @@ var CodePathState = class {
6781
5509
  lastOfCatchIsReachable: false
6782
5510
  };
6783
5511
  }
6784
- /**
6785
- * Pops the last context of TryStatement and finalizes it.
6786
- */
6787
5512
  popTryContext() {
6788
5513
  const context = this.tryContext;
6789
5514
  this.tryContext = context.upper;
@@ -6803,9 +5528,6 @@ var CodePathState = class {
6803
5528
  this.forkContext.replaceHead(normalSegments);
6804
5529
  if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) this.forkContext.makeUnreachable(-1, -1);
6805
5530
  }
6806
- /**
6807
- * Makes a code path segment for a `catch` block.
6808
- */
6809
5531
  makeCatchBlock() {
6810
5532
  const context = this.tryContext;
6811
5533
  const forkContext = this.forkContext;
@@ -6819,13 +5541,6 @@ var CodePathState = class {
6819
5541
  this.forkBypassPath();
6820
5542
  this.forkContext.add(thrownSegments);
6821
5543
  }
6822
- /**
6823
- * Makes a code path segment for a `finally` block.
6824
- *
6825
- * In the `finally` block, parallel paths are created. The parallel paths
6826
- * are used as leaving-paths. The leaving-paths are paths from `return`
6827
- * statements and `throw` statements in a `try` block or a `catch` block.
6828
- */
6829
5544
  makeFinallyBlock() {
6830
5545
  const context = this.tryContext;
6831
5546
  let forkContext = this.forkContext;
@@ -6849,10 +5564,6 @@ var CodePathState = class {
6849
5564
  this.pushForkContext(true);
6850
5565
  this.forkContext.add(segments);
6851
5566
  }
6852
- /**
6853
- * Makes a code path segment from the first throwable node to the `catch`
6854
- * block or the `finally` block.
6855
- */
6856
5567
  makeFirstThrowablePathInTryBlock() {
6857
5568
  const forkContext = this.forkContext;
6858
5569
  if (!forkContext.reachable) return;
@@ -6861,9 +5572,6 @@ var CodePathState = class {
6861
5572
  context.thrownForkContext.add(forkContext.head);
6862
5573
  forkContext.replaceHead(forkContext.makeNext(-1, -1));
6863
5574
  }
6864
- /**
6865
- * Creates a context object of a loop statement and stacks it.
6866
- */
6867
5575
  pushLoopContext(type, label) {
6868
5576
  const forkContext = this.forkContext;
6869
5577
  const breakContext = this.pushBreakContext(true, label);
@@ -6923,9 +5631,6 @@ var CodePathState = class {
6923
5631
  default: throw new Error(`unknown type: "${type}"`);
6924
5632
  }
6925
5633
  }
6926
- /**
6927
- * Pops the last context of a loop statement and finalizes it.
6928
- */
6929
5634
  popLoopContext() {
6930
5635
  const context = this.loopContext;
6931
5636
  this.loopContext = context.upper;
@@ -6958,9 +5663,6 @@ var CodePathState = class {
6958
5663
  if (brokenForkContext.empty) forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
6959
5664
  else forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
6960
5665
  }
6961
- /**
6962
- * Makes a code path segment for the test part of a WhileStatement.
6963
- */
6964
5666
  makeWhileTest(test) {
6965
5667
  const context = this.loopContext;
6966
5668
  const forkContext = this.forkContext;
@@ -6969,9 +5671,6 @@ var CodePathState = class {
6969
5671
  context.continueDestSegments = testSegments;
6970
5672
  forkContext.replaceHead(testSegments);
6971
5673
  }
6972
- /**
6973
- * Makes a code path segment for the body part of a WhileStatement.
6974
- */
6975
5674
  makeWhileBody() {
6976
5675
  const context = this.loopContext;
6977
5676
  const choiceContext = this.choiceContext;
@@ -6983,9 +5682,6 @@ var CodePathState = class {
6983
5682
  if (context.test !== true) context.brokenForkContext.addAll(choiceContext.falseForkContext);
6984
5683
  forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1));
6985
5684
  }
6986
- /**
6987
- * Makes a code path segment for the body part of a DoWhileStatement.
6988
- */
6989
5685
  makeDoWhileBody() {
6990
5686
  const context = this.loopContext;
6991
5687
  const forkContext = this.forkContext;
@@ -6993,9 +5689,6 @@ var CodePathState = class {
6993
5689
  context.entrySegments = bodySegments;
6994
5690
  forkContext.replaceHead(bodySegments);
6995
5691
  }
6996
- /**
6997
- * Makes a code path segment for the test part of a DoWhileStatement.
6998
- */
6999
5692
  makeDoWhileTest(test) {
7000
5693
  const context = this.loopContext;
7001
5694
  const forkContext = this.forkContext;
@@ -7006,9 +5699,6 @@ var CodePathState = class {
7006
5699
  forkContext.replaceHead(testSegments);
7007
5700
  }
7008
5701
  }
7009
- /**
7010
- * Makes a code path segment for the test part of a ForStatement.
7011
- */
7012
5702
  makeForTest(test) {
7013
5703
  const context = this.loopContext;
7014
5704
  const forkContext = this.forkContext;
@@ -7019,9 +5709,6 @@ var CodePathState = class {
7019
5709
  context.continueDestSegments = context.testSegments = testSegments;
7020
5710
  forkContext.replaceHead(testSegments);
7021
5711
  }
7022
- /**
7023
- * Makes a code path segment for the update part of a ForStatement.
7024
- */
7025
5712
  makeForUpdate() {
7026
5713
  const context = this.loopContext;
7027
5714
  const choiceContext = this.choiceContext;
@@ -7032,9 +5719,6 @@ var CodePathState = class {
7032
5719
  context.continueDestSegments = context.updateSegments = updateSegments;
7033
5720
  forkContext.replaceHead(updateSegments);
7034
5721
  }
7035
- /**
7036
- * Makes a code path segment for the body part of a ForStatement.
7037
- */
7038
5722
  makeForBody() {
7039
5723
  const context = this.loopContext;
7040
5724
  const choiceContext = this.choiceContext;
@@ -7054,10 +5738,6 @@ var CodePathState = class {
7054
5738
  context.continueDestSegments = context.continueDestSegments || bodySegments;
7055
5739
  forkContext.replaceHead(bodySegments);
7056
5740
  }
7057
- /**
7058
- * Makes a code path segment for the left part of a ForInStatement and a
7059
- * ForOfStatement.
7060
- */
7061
5741
  makeForInOfLeft() {
7062
5742
  const context = this.loopContext;
7063
5743
  const forkContext = this.forkContext;
@@ -7066,10 +5746,6 @@ var CodePathState = class {
7066
5746
  context.leftSegments = context.continueDestSegments = leftSegments;
7067
5747
  forkContext.replaceHead(leftSegments);
7068
5748
  }
7069
- /**
7070
- * Makes a code path segment for the right part of a ForInStatement and a
7071
- * ForOfStatement.
7072
- */
7073
5749
  makeForInOfRight() {
7074
5750
  const context = this.loopContext;
7075
5751
  const forkContext = this.forkContext;
@@ -7079,10 +5755,6 @@ var CodePathState = class {
7079
5755
  context.endOfLeftSegments = forkContext.head;
7080
5756
  forkContext.replaceHead(rightSegments);
7081
5757
  }
7082
- /**
7083
- * Makes a code path segment for the body part of a ForInStatement and a
7084
- * ForOfStatement.
7085
- */
7086
5758
  makeForInOfBody() {
7087
5759
  const context = this.loopContext;
7088
5760
  const forkContext = this.forkContext;
@@ -7093,9 +5765,6 @@ var CodePathState = class {
7093
5765
  context.brokenForkContext.add(forkContext.head);
7094
5766
  forkContext.replaceHead(bodySegments);
7095
5767
  }
7096
- /**
7097
- * Creates new context for BreakStatement.
7098
- */
7099
5768
  pushBreakContext(breakable, label) {
7100
5769
  this.breakContext = {
7101
5770
  upper: this.breakContext,
@@ -7105,9 +5774,6 @@ var CodePathState = class {
7105
5774
  };
7106
5775
  return this.breakContext;
7107
5776
  }
7108
- /**
7109
- * Removes the top item of the break context stack.
7110
- */
7111
5777
  popBreakContext() {
7112
5778
  const context = this.breakContext;
7113
5779
  const forkContext = this.forkContext;
@@ -7121,12 +5787,6 @@ var CodePathState = class {
7121
5787
  }
7122
5788
  return context;
7123
5789
  }
7124
- /**
7125
- * Makes a path for a `break` statement.
7126
- *
7127
- * It registers the head segment to a context of `break`.
7128
- * It makes new unreachable segment, then it set the head with the segment.
7129
- */
7130
5790
  makeBreak(label) {
7131
5791
  const forkContext = this.forkContext;
7132
5792
  if (!forkContext.reachable) return;
@@ -7135,12 +5795,6 @@ var CodePathState = class {
7135
5795
  /* c8 ignore next */
7136
5796
  forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
7137
5797
  }
7138
- /**
7139
- * Makes a path for a `continue` statement.
7140
- *
7141
- * It makes a looping path.
7142
- * It makes new unreachable segment, then it set the head with the segment.
7143
- */
7144
5798
  makeContinue(label) {
7145
5799
  const forkContext = this.forkContext;
7146
5800
  if (!forkContext.reachable) return;
@@ -7153,12 +5807,6 @@ var CodePathState = class {
7153
5807
  }
7154
5808
  forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
7155
5809
  }
7156
- /**
7157
- * Makes a path for a `return` statement.
7158
- *
7159
- * It registers the head segment to a context of `return`.
7160
- * It makes new unreachable segment, then it set the head with the segment.
7161
- */
7162
5810
  makeReturn() {
7163
5811
  const forkContext = this.forkContext;
7164
5812
  if (forkContext.reachable) {
@@ -7166,12 +5814,6 @@ var CodePathState = class {
7166
5814
  forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
7167
5815
  }
7168
5816
  }
7169
- /**
7170
- * Makes a path for a `throw` statement.
7171
- *
7172
- * It registers the head segment to a context of `throw`.
7173
- * It makes new unreachable segment, then it set the head with the segment.
7174
- */
7175
5817
  makeThrow() {
7176
5818
  const forkContext = this.forkContext;
7177
5819
  if (forkContext.reachable) {
@@ -7179,17 +5821,11 @@ var CodePathState = class {
7179
5821
  forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
7180
5822
  }
7181
5823
  }
7182
- /**
7183
- * Makes the final path.
7184
- */
7185
5824
  makeFinal() {
7186
5825
  const segments = this.currentSegments;
7187
5826
  if (segments.length > 0 && segments[0].reachable) this.returnedForkContext.add(segments);
7188
5827
  }
7189
5828
  };
7190
- /**
7191
- * A generator for unique ids.
7192
- */
7193
5829
  var IdGenerator = class {
7194
5830
  prefix;
7195
5831
  n;
@@ -7197,9 +5833,6 @@ var IdGenerator = class {
7197
5833
  this.prefix = String(prefix);
7198
5834
  this.n = 0;
7199
5835
  }
7200
- /**
7201
- * Generates id.
7202
- */
7203
5836
  next() {
7204
5837
  this.n = 1 + this.n | 0;
7205
5838
  /* c8 ignore start */
@@ -7207,22 +5840,11 @@ var IdGenerator = class {
7207
5840
  return this.prefix + this.n;
7208
5841
  }
7209
5842
  };
7210
- /**
7211
- * A code path.
7212
- */
7213
5843
  var CodePath = class {
7214
- /** The identifier of this code path. */
7215
5844
  id;
7216
- /**
7217
- * The reason that this code path was started. May be "program",
7218
- * "function", "class-field-initializer", or "class-static-block".
7219
- */
7220
5845
  origin;
7221
- /** The code path of the upper function scope. */
7222
5846
  upper;
7223
- /** The code paths of nested function scopes. */
7224
5847
  childCodePaths;
7225
- /** Internal state for the code path. */
7226
5848
  internal;
7227
5849
  constructor({ id, origin, upper, onLooped }) {
7228
5850
  this.id = id;
@@ -7232,48 +5854,24 @@ var CodePath = class {
7232
5854
  this.internal = new CodePathState(new IdGenerator(`${id}_`), onLooped);
7233
5855
  if (upper) upper.childCodePaths.push(this);
7234
5856
  }
7235
- /**
7236
- * Gets the state of a given code path.
7237
- */
7238
5857
  static getState(codePath) {
7239
5858
  return codePath.internal;
7240
5859
  }
7241
- /** The initial code path segment. */
7242
5860
  get initialSegment() {
7243
5861
  return this.internal.initialSegment;
7244
5862
  }
7245
- /**
7246
- * Final code path segments.
7247
- * This array is a mix of `returnedSegments` and `thrownSegments`.
7248
- */
7249
5863
  get finalSegments() {
7250
5864
  return this.internal.finalSegments;
7251
5865
  }
7252
- /**
7253
- * Final code path segments which is with `return` statements.
7254
- * This array contains the last path segment if it's reachable.
7255
- * Since the reachable last path returns `undefined`.
7256
- */
7257
5866
  get returnedSegments() {
7258
5867
  return this.internal.returnedForkContext;
7259
5868
  }
7260
- /** Final code path segments which is with `throw` statements. */
7261
5869
  get thrownSegments() {
7262
5870
  return this.internal.thrownForkContext;
7263
5871
  }
7264
- /** Current code path segments. */
7265
5872
  get currentSegments() {
7266
5873
  return this.internal.currentSegments;
7267
5874
  }
7268
- /**
7269
- * Traverses all segments in this code path.
7270
- *
7271
- * This method enumerates segments in order from the head.
7272
- *
7273
- * The `controller` object has two methods:
7274
- * - `controller.skip()` - Skip the following segments in this branch.
7275
- * - `controller.break()` - Skip all following segments.
7276
- */
7277
5875
  traverseSegments(options, callback) {
7278
5876
  let resolvedOptions;
7279
5877
  let resolvedCallback;
@@ -7339,45 +5937,23 @@ var CodePath = class {
7339
5937
  }
7340
5938
  };
7341
5939
  const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/u;
7342
- /**
7343
- * Checks whether or not a given node is a `case` node (not `default` node).
7344
- */
7345
5940
  function isCaseNode(node) {
7346
5941
  return Boolean(node.test);
7347
5942
  }
7348
- /**
7349
- * Checks if a given node appears as the value of a PropertyDefinition node.
7350
- */
7351
5943
  function isPropertyDefinitionValue(node) {
7352
5944
  const parent = node.parent;
7353
5945
  return parent && parent.type === "PropertyDefinition" && parent.value === node;
7354
5946
  }
7355
- /**
7356
- * Checks whether the given logical operator is taken into account for the code
7357
- * path analysis.
7358
- */
7359
5947
  function isHandledLogicalOperator(operator) {
7360
5948
  return operator === "&&" || operator === "||" || operator === "??";
7361
5949
  }
7362
- /**
7363
- * Checks whether the given assignment operator is a logical assignment operator.
7364
- * Logical assignments are taken into account for the code path analysis
7365
- * because of their short-circuiting semantics.
7366
- */
7367
5950
  function isLogicalAssignmentOperator(operator) {
7368
5951
  return operator === "&&=" || operator === "||=" || operator === "??=";
7369
5952
  }
7370
- /**
7371
- * Gets the label if the parent node of a given node is a LabeledStatement.
7372
- */
7373
5953
  function getLabel(node) {
7374
5954
  if (node.parent.type === "LabeledStatement") return node.parent.label.name;
7375
5955
  return null;
7376
5956
  }
7377
- /**
7378
- * Checks whether or not a given logical expression node goes different path
7379
- * between the `true` case and the `false` case.
7380
- */
7381
5957
  function isForkingByTrueOrFalse(node) {
7382
5958
  const parent = node.parent;
7383
5959
  switch (parent.type) {
@@ -7391,21 +5967,9 @@ function isForkingByTrueOrFalse(node) {
7391
5967
  default: return false;
7392
5968
  }
7393
5969
  }
7394
- /**
7395
- * Gets the boolean value of a given literal node.
7396
- *
7397
- * This is used to detect infinity loops (ex: `while (true) {}`).
7398
- * Statements preceded by an infinity loop are unreachable if the loop didn't
7399
- * have any `break` statement.
7400
- */
7401
5970
  function getBooleanValueIfSimpleConstant(node) {
7402
5971
  if (node.type === "Literal") return Boolean(node.value);
7403
5972
  }
7404
- /**
7405
- * Checks that a given identifier node is a reference or not.
7406
- *
7407
- * This is used to detect the first throwable node in a `try` block.
7408
- */
7409
5973
  function isIdentifierReference(node) {
7410
5974
  const parent = node.parent;
7411
5975
  switch (parent.type) {
@@ -7433,15 +5997,6 @@ function isIdentifierReference(node) {
7433
5997
  default: return true;
7434
5998
  }
7435
5999
  }
7436
- /**
7437
- * Updates the current segment with the head segment.
7438
- * This is similar to local branches and tracking branches of git.
7439
- *
7440
- * To separate the current and the head is in order to not make useless segments.
7441
- *
7442
- * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd"
7443
- * events are fired.
7444
- */
7445
6000
  function forwardCurrentToHead(analyzer, node) {
7446
6001
  const codePath = analyzer.codePath;
7447
6002
  const state = CodePath.getState(codePath);
@@ -7468,10 +6023,6 @@ function forwardCurrentToHead(analyzer, node) {
7468
6023
  }
7469
6024
  }
7470
6025
  }
7471
- /**
7472
- * Updates the current segment with empty.
7473
- * This is called at the last of functions or the program.
7474
- */
7475
6026
  function leaveFromCurrentSegment(analyzer, node) {
7476
6027
  const state = CodePath.getState(analyzer.codePath);
7477
6028
  const currentSegments = state.currentSegments;
@@ -7481,13 +6032,6 @@ function leaveFromCurrentSegment(analyzer, node) {
7481
6032
  }
7482
6033
  state.currentSegments = [];
7483
6034
  }
7484
- /**
7485
- * Updates the code path due to the position of a given node in the parent node
7486
- * thereof.
7487
- *
7488
- * For example, if the node is `parent.consequent`, this creates a fork from the
7489
- * current path.
7490
- */
7491
6035
  function preprocess(analyzer, node) {
7492
6036
  const codePath = analyzer.codePath;
7493
6037
  const state = CodePath.getState(codePath);
@@ -7552,17 +6096,10 @@ function preprocess(analyzer, node) {
7552
6096
  }
7553
6097
  }
7554
6098
  }
7555
- /**
7556
- * Updates the code path due to the type of a given node in entering.
7557
- */
7558
6099
  function processCodePathToEnter(analyzer, node) {
7559
6100
  let codePath = analyzer.codePath;
7560
6101
  let state = codePath && CodePath.getState(codePath);
7561
6102
  const parent = node.parent;
7562
- /**
7563
- * Creates a new code path and trigger the onCodePathStart event
7564
- * based on the currently selected node.
7565
- */
7566
6103
  function startCodePath(origin) {
7567
6104
  if (codePath) forwardCurrentToHead(analyzer, node);
7568
6105
  codePath = analyzer.codePath = new CodePath({
@@ -7628,9 +6165,6 @@ function processCodePathToEnter(analyzer, node) {
7628
6165
  }
7629
6166
  forwardCurrentToHead(analyzer, node);
7630
6167
  }
7631
- /**
7632
- * Updates the code path due to the type of a given node in leaving.
7633
- */
7634
6168
  function processCodePathToExit(analyzer, node) {
7635
6169
  const codePath = analyzer.codePath;
7636
6170
  const state = CodePath.getState(codePath);
@@ -7706,9 +6240,6 @@ function processCodePathToExit(analyzer, node) {
7706
6240
  }
7707
6241
  if (!dontForward) forwardCurrentToHead(analyzer, node);
7708
6242
  }
7709
- /**
7710
- * Updates the code path to finalize the current code path.
7711
- */
7712
6243
  function postprocess(analyzer, node) {
7713
6244
  function endCodePath() {
7714
6245
  const codePath = analyzer.codePath;
@@ -7731,10 +6262,6 @@ function postprocess(analyzer, node) {
7731
6262
  }
7732
6263
  if (isPropertyDefinitionValue(node)) endCodePath();
7733
6264
  }
7734
- /**
7735
- * The class to analyze code paths.
7736
- * This class implements the EventGenerator interface.
7737
- */
7738
6265
  var CodePathAnalyzer = class {
7739
6266
  emitter;
7740
6267
  codePath;
@@ -7750,30 +6277,18 @@ var CodePathAnalyzer = class {
7750
6277
  this.currentNode = null;
7751
6278
  this.onLooped = this._onLooped.bind(this);
7752
6279
  }
7753
- /**
7754
- * Does the process to enter a given AST node.
7755
- * This updates state of analysis and calls `enterNode` of the wrapped.
7756
- */
7757
6280
  enterNode(node) {
7758
6281
  this.currentNode = node;
7759
6282
  if (node.parent) preprocess(this, node);
7760
6283
  processCodePathToEnter(this, node);
7761
6284
  this.currentNode = null;
7762
6285
  }
7763
- /**
7764
- * Does the process to leave a given AST node.
7765
- * This updates state of analysis and calls `leaveNode` of the wrapped.
7766
- */
7767
6286
  leaveNode(node) {
7768
6287
  this.currentNode = node;
7769
6288
  processCodePathToExit(this, node);
7770
6289
  postprocess(this, node);
7771
6290
  this.currentNode = null;
7772
6291
  }
7773
- /**
7774
- * This is called on a code path looped.
7775
- * Then this raises a looped event.
7776
- */
7777
6292
  _onLooped(fromSegment, toSegment) {
7778
6293
  if (fromSegment.reachable && toSegment.reachable) this.emitter.emit("onCodePathSegmentLoop", fromSegment, toSegment, this.currentNode);
7779
6294
  }
@@ -7781,17 +6296,9 @@ var CodePathAnalyzer = class {
7781
6296
 
7782
6297
  //#endregion
7783
6298
  //#region src/rules/rules-of-hooks/rules-of-hooks.ts
7784
- /**
7785
- * Catch all identifiers that begin with "use" followed by an uppercase Latin
7786
- * character to exclude identifiers like "user".
7787
- */
7788
6299
  function isHookName(s) {
7789
6300
  return s === "use" || /^use[A-Z0-9]/.test(s);
7790
6301
  }
7791
- /**
7792
- * We consider hooks to be a hook name identifier or a member expression
7793
- * containing a hook name.
7794
- */
7795
6302
  function isHook(node) {
7796
6303
  const expr = Extract.unwrap(node);
7797
6304
  if (expr.type === "Identifier") return isHookName(expr.name);
@@ -7800,27 +6307,15 @@ function isHook(node) {
7800
6307
  return obj.type === "Identifier" && /^[A-Z].*/.test(obj.name);
7801
6308
  } else return false;
7802
6309
  }
7803
- /**
7804
- * Checks if the node is a React component name. React component names must
7805
- * always start with an uppercase letter.
7806
- */
7807
6310
  function isComponentName(node) {
7808
6311
  return node.type === "Identifier" && /^[A-Z]/.test(node.name);
7809
6312
  }
7810
6313
  function isReactFunction(node, functionName) {
7811
6314
  return "name" in node && node.name === functionName || node.type === "MemberExpression" && "name" in node.object && node.object.name === "React" && "name" in node.property && node.property.name === functionName;
7812
6315
  }
7813
- /**
7814
- * Checks if the node is a callback argument of forwardRef. This render function
7815
- * should follow the rules of hooks.
7816
- */
7817
6316
  function isForwardRefCallback(node) {
7818
6317
  return !!(node.parent && "callee" in node.parent && node.parent.callee && isReactFunction(node.parent.callee, "forwardRef"));
7819
6318
  }
7820
- /**
7821
- * Checks if the node is a callback argument of React.memo. This anonymous
7822
- * functional component should follow the rules of hooks.
7823
- */
7824
6319
  function isMemoCallback(node) {
7825
6320
  return !!(node.parent && "callee" in node.parent && node.parent.callee && isReactFunction(node.parent.callee, "memo"));
7826
6321
  }
@@ -7899,17 +6394,11 @@ const rule = {
7899
6394
  }
7900
6395
  }
7901
6396
  }
7902
- /**
7903
- * SourceCode that also works down to ESLint 3.0.0
7904
- */
7905
6397
  const getSourceCode = typeof context.getSourceCode === "function" ? () => {
7906
6398
  return context.getSourceCode();
7907
6399
  } : () => {
7908
6400
  return context.sourceCode;
7909
6401
  };
7910
- /**
7911
- * SourceCode#getScope that also works down to ESLint 3.0.0
7912
- */
7913
6402
  const getScope = typeof context.getScope === "function" ? () => {
7914
6403
  return context.getScope();
7915
6404
  } : (node) => {
@@ -7929,27 +6418,6 @@ const rule = {
7929
6418
  if (reactHooksMap?.size === 0) return;
7930
6419
  else if (typeof reactHooksMap === "undefined") throw new Error("Unexpected undefined reactHooksMap");
7931
6420
  const cyclic = /* @__PURE__ */ new Set();
7932
- /**
7933
- * Count the number of code paths from the start of the function to this
7934
- * segment. For example:
7935
- *
7936
- * ```js
7937
- * function MyComponent() {
7938
- * if (condition) {
7939
- * // Segment 1
7940
- * } else {
7941
- * // Segment 2
7942
- * }
7943
- * // Segment 3
7944
- * }
7945
- * ```
7946
- *
7947
- * Segments 1 and 2 have one path to the beginning of `MyComponent` and
7948
- * segment 3 has two paths to the beginning of `MyComponent` since we
7949
- * could have either taken the path of segment 1 or segment 2.
7950
- *
7951
- * Populates `cyclic` with cyclic segments.
7952
- */
7953
6421
  function countPathsFromStart(segment, pathHistory) {
7954
6422
  const { cache } = countPathsFromStart;
7955
6423
  let paths = cache.get(segment.id);
@@ -7972,27 +6440,6 @@ const rule = {
7972
6440
  else cache.set(segment.id, paths);
7973
6441
  return paths;
7974
6442
  }
7975
- /**
7976
- * Count the number of code paths from this segment to the end of the
7977
- * function. For example:
7978
- *
7979
- * ```js
7980
- * function MyComponent() {
7981
- * // Segment 1
7982
- * if (condition) {
7983
- * // Segment 2
7984
- * } else {
7985
- * // Segment 3
7986
- * }
7987
- * }
7988
- * ```
7989
- *
7990
- * Segments 2 and 3 have one path to the end of `MyComponent` and
7991
- * segment 1 has two paths to the end of `MyComponent` since we could
7992
- * either take the path of segment 1 or segment 2.
7993
- *
7994
- * Populates `cyclic` with cyclic segments.
7995
- */
7996
6443
  function countPathsToEnd(segment, pathHistory) {
7997
6444
  const { cache } = countPathsToEnd;
7998
6445
  let paths = cache.get(segment.id);
@@ -8014,27 +6461,6 @@ const rule = {
8014
6461
  cache.set(segment.id, paths);
8015
6462
  return paths;
8016
6463
  }
8017
- /**
8018
- * Gets the shortest path length to the start of a code path.
8019
- * For example:
8020
- *
8021
- * ```js
8022
- * function MyComponent() {
8023
- * if (condition) {
8024
- * // Segment 1
8025
- * }
8026
- * // Segment 2
8027
- * }
8028
- * ```
8029
- *
8030
- * There is only one path from segment 1 to the code path start. Its
8031
- * length is one so that is the shortest path.
8032
- *
8033
- * There are two paths from segment 2 to the code path start. One
8034
- * through segment 1 with a length of two and another directly to the
8035
- * start with a length of one. The shortest path has a length of one
8036
- * so we would return that.
8037
- */
8038
6464
  function shortestPathLengthToStart(segment) {
8039
6465
  const { cache } = shortestPathLengthToStart;
8040
6466
  let length = cache.get(segment.id);
@@ -8178,13 +6604,6 @@ const rule = {
8178
6604
  };
8179
6605
  }
8180
6606
  };
8181
- /**
8182
- * Gets the static name of a function AST node. For function declarations it is
8183
- * easy. For anonymous function expressions it is much harder. If you search for
8184
- * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
8185
- * where JS gives anonymous function expressions names. We roughly detect the
8186
- * same AST nodes with some exceptions to better fit our use case.
8187
- */
8188
6607
  function getFunctionName(node) {
8189
6608
  if (node.type === "ComponentDeclaration" || node.type === "HookDeclaration" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression" && node.id) return node.id;
8190
6609
  else if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
@@ -8195,9 +6614,6 @@ function getFunctionName(node) {
8195
6614
  else return;
8196
6615
  } else return;
8197
6616
  }
8198
- /**
8199
- * Convenience function for peeking the last item in a stack.
8200
- */
8201
6617
  function last(array) {
8202
6618
  return array[array.length - 1];
8203
6619
  }
@@ -8240,11 +6656,6 @@ const IDENTIFIER_VISITOR_KEYS = {
8240
6656
  [AST_NODE_TYPES.UpdateExpression]: ["argument"],
8241
6657
  [AST_NODE_TYPES.YieldExpression]: ["argument"]
8242
6658
  };
8243
- /**
8244
- * Get all nested identifiers in a expression like node
8245
- * @param node The node to get the nested identifiers from
8246
- * @returns All nested identifiers
8247
- */
8248
6659
  function getNestedIdentifiers(node) {
8249
6660
  const identifiers = [];
8250
6661
  simpleTraverse(node, {
@@ -8273,23 +6684,10 @@ function isTerminatingStatement(node) {
8273
6684
  if (node.type === AST_NODE_TYPES.BlockStatement) return node.body.some(isTerminatingStatement);
8274
6685
  return false;
8275
6686
  }
8276
- /**
8277
- * Get the display name of a setState call reference for reporting.
8278
- * @param node The setState call node (CallExpression or Identifier)
8279
- * @param getText The source text getter
8280
- * @returns The fully qualified name of the call
8281
- */
8282
6687
  function getCallName(node, getText) {
8283
6688
  if (node.type === AST_NODE_TYPES.CallExpression) return Extract.getFullyQualifiedName(node.callee, getText);
8284
6689
  return Extract.getFullyQualifiedName(node, getText);
8285
6690
  }
8286
- /**
8287
- * Get the actual CallExpression node from a setState call reference.
8288
- * When the node is an Identifier that is the callee of a CallExpression,
8289
- * returns the parent CallExpression; otherwise returns the node itself.
8290
- * @param node The setState call node (CallExpression or Identifier)
8291
- * @returns The actual CallExpression node
8292
- */
8293
6691
  function getSetStateCallExpression(node) {
8294
6692
  return Check.isIdentifier(node) && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node ? node.parent : node;
8295
6693
  }
@@ -8377,13 +6775,6 @@ function createFactCollector$3(additionalStateHooks, additionalEffectHooks) {
8377
6775
 
8378
6776
  //#endregion
8379
6777
  //#region src/rules/set-state-in-effect/origins.ts
8380
- /**
8381
- * Create a resolver that answers whether an identifier or call originates from
8382
- * a `useState`-like hook's setter function (the element at index 1 of the
8383
- * returned tuple).
8384
- * @param context The rule context
8385
- * @returns The setState provenance resolver
8386
- */
8387
6778
  function createSetStateResolver$1(context) {
8388
6779
  const { additionalStateHooks } = getSettingsFromContext(context);
8389
6780
  function isUseStateCall(node) {
@@ -8395,7 +6786,7 @@ function createSetStateResolver$1(context) {
8395
6786
  if (initNode.type !== AST_NODE_TYPES.CallExpression) return false;
8396
6787
  if (!isUseStateCall(initNode)) return false;
8397
6788
  const variableNodeParent = initNode.parent;
8398
- if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
6789
+ if (!hasProperty(variableNodeParent, "id") || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
8399
6790
  return variableNodeParent.id.elements.findIndex((e) => e != null && Check.isIdentifier(e, id.name)) === at;
8400
6791
  }
8401
6792
  function isSetStateCall(node) {
@@ -8404,7 +6795,7 @@ function createSetStateResolver$1(context) {
8404
6795
  case AST_NODE_TYPES.CallExpression: {
8405
6796
  const innerCallee = Extract.unwrap(callee.callee);
8406
6797
  if (innerCallee.type !== AST_NODE_TYPES.MemberExpression) return false;
8407
- if (!("name" in innerCallee.object)) return false;
6798
+ if (!hasProperty(innerCallee.object, "name")) return false;
8408
6799
  const isAt = Extract.getCalleeName(callee) === "at";
8409
6800
  const [index] = callee.arguments;
8410
6801
  if (!isAt || index == null) return false;
@@ -8413,7 +6804,7 @@ function createSetStateResolver$1(context) {
8413
6804
  }
8414
6805
  case AST_NODE_TYPES.Identifier: return isSetStateId(callee, 1);
8415
6806
  case AST_NODE_TYPES.MemberExpression: {
8416
- if (!("name" in callee.object)) return false;
6807
+ if (!hasProperty(callee.object, "name")) return false;
8417
6808
  const property = callee.property;
8418
6809
  const propertyScope = context.sourceCode.getScope(node);
8419
6810
  return getStaticValue(property, propertyScope)?.value === 1 && isSetStateId(callee.object, 1);
@@ -8461,12 +6852,6 @@ function isInitializedFromRef(context, name, initialScope, seen = /* @__PURE__ *
8461
6852
  }
8462
6853
  return false;
8463
6854
  }
8464
- /**
8465
- * Check if the setState call is using a ref value, which is safe to use in an effect (ex: `setState(ref.current.scrollTop)`)
8466
- * @param context The rule context
8467
- * @param node The setState call argument to check
8468
- * @returns `true` if the argument value is derived from a ref
8469
- */
8470
6855
  function isArgumentUsingRefValue(context, node) {
8471
6856
  const isUsingRefValue = (n) => {
8472
6857
  switch (n.type) {
@@ -8492,13 +6877,6 @@ function isArgumentUsingRefValue(context, node) {
8492
6877
  if (isUsingRefValue(node)) return true;
8493
6878
  return Check.isFunction(node) && context.sourceCode.getScope(node.body).references.some((r) => isUsingRefValue(r.identifier));
8494
6879
  }
8495
- /**
8496
- * Check if a setState call is inside a conditional block whose test expression
8497
- * is derived from a ref value (e.g. `if (prevRef.current !== value) setState(...)`).
8498
- * @param context The ESLint rule context
8499
- * @param node The AST node to check
8500
- * @returns `true` if the node is inside a ref-gated conditional block
8501
- */
8502
6880
  function isRefGatedContext(context, node) {
8503
6881
  let child = node;
8504
6882
  let current = node.parent;
@@ -8526,11 +6904,6 @@ function isRefGatedContext(context, node) {
8526
6904
  function isRefInExpression(context, node) {
8527
6905
  return getNestedIdentifiers(node).some((id) => isInitializedFromRef(context, id.name, context.sourceCode.getScope(id)));
8528
6906
  }
8529
- /**
8530
- * Get the name that identifies the source of a `.current` member access.
8531
- * @param node The object of the member expression
8532
- * @returns The identifier name, the last property name of a member chain, or null
8533
- */
8534
6907
  function getRefSourceName(node) {
8535
6908
  switch (node.type) {
8536
6909
  case AST_NODE_TYPES.Identifier: return node.name;
@@ -8544,15 +6917,6 @@ function getRefSourceName(node) {
8544
6917
 
8545
6918
  //#endregion
8546
6919
  //#region src/rules/set-state-in-effect/effects.ts
8547
- /**
8548
- * Infer the setState calls that run synchronously during an effect setup from
8549
- * the collected facts: calls made directly in the setup body (or an IIFE within
8550
- * it), and calls reached indirectly through local functions, hook callbacks, or
8551
- * setup identifiers passed to the effect.
8552
- * @param context The rule context
8553
- * @param facts The collected facts
8554
- * @returns The violations to report, in report order
8555
- */
8556
6920
  function inferViolations$2(context, facts) {
8557
6921
  const { additionalEffectHooks } = getSettingsFromContext(context);
8558
6922
  const resolver = createSetStateResolver$1(context);
@@ -8773,13 +7137,6 @@ function createFactCollector$2(additionalStateHooks) {
8773
7137
 
8774
7138
  //#endregion
8775
7139
  //#region src/rules/set-state-in-render/origins.ts
8776
- /**
8777
- * Create a resolver that answers whether an identifier or call originates from
8778
- * a `useState`-like hook's setter function (the element at index 1 of the
8779
- * returned tuple).
8780
- * @param context The rule context
8781
- * @returns The setState provenance resolver
8782
- */
8783
7140
  function createSetStateResolver(context) {
8784
7141
  const { additionalStateHooks } = getSettingsFromContext(context);
8785
7142
  function isUseStateCall(node) {
@@ -8791,7 +7148,7 @@ function createSetStateResolver(context) {
8791
7148
  if (initNode.type !== AST_NODE_TYPES.CallExpression) return false;
8792
7149
  if (!isUseStateCall(initNode)) return false;
8793
7150
  const variableNodeParent = initNode.parent;
8794
- if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
7151
+ if (!hasProperty(variableNodeParent, "id") || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
8795
7152
  return variableNodeParent.id.elements.findIndex((e) => e != null && Check.isIdentifier(e, id.name)) === at;
8796
7153
  }
8797
7154
  function isSetStateCall(node) {
@@ -8800,7 +7157,7 @@ function createSetStateResolver(context) {
8800
7157
  case AST_NODE_TYPES.CallExpression: {
8801
7158
  const innerCallee = Extract.unwrap(callee.callee);
8802
7159
  if (innerCallee.type !== AST_NODE_TYPES.MemberExpression) return false;
8803
- if (!("name" in innerCallee.object)) return false;
7160
+ if (!hasProperty(innerCallee.object, "name")) return false;
8804
7161
  const isAt = Extract.getCalleeName(callee) === "at";
8805
7162
  const [index] = callee.arguments;
8806
7163
  if (!isAt || index == null) return false;
@@ -8809,7 +7166,7 @@ function createSetStateResolver(context) {
8809
7166
  }
8810
7167
  case AST_NODE_TYPES.Identifier: return isSetStateId(callee, 1);
8811
7168
  case AST_NODE_TYPES.MemberExpression: {
8812
- if (!("name" in callee.object)) return false;
7169
+ if (!hasProperty(callee.object, "name")) return false;
8813
7170
  const property = callee.property;
8814
7171
  const propertyScope = context.sourceCode.getScope(node);
8815
7172
  return getStaticValue(property, propertyScope)?.value === 1 && isSetStateId(callee.object, 1);
@@ -8826,14 +7183,6 @@ function createSetStateResolver(context) {
8826
7183
 
8827
7184
  //#endregion
8828
7185
  //#region src/rules/set-state-in-render/effects.ts
8829
- /**
8830
- * Infer the setState calls that run unconditionally during render from the
8831
- * collected facts: calls made directly in a component function body that are
8832
- * neither guarded by a conditional nor positioned after an early return.
8833
- * @param context The rule context
8834
- * @param facts The collected facts
8835
- * @returns The violations to report, in report order
8836
- */
8837
7186
  function inferViolations$1(context, facts) {
8838
7187
  const resolver = createSetStateResolver(context);
8839
7188
  const getText = (n) => context.sourceCode.getText(n);
@@ -8900,10 +7249,6 @@ function createFactCollector$1() {
8900
7249
 
8901
7250
  //#endregion
8902
7251
  //#region src/rules/static-components/helpers.ts
8903
- /**
8904
- * Expression kinds that always produce a brand-new value on every evaluation, and are
8905
- * therefore considered "dynamically created" when used as a component's value.
8906
- */
8907
7252
  const KNOWN_DYNAMIC_EXPRESSION_TYPES = /* @__PURE__ */ new Set([
8908
7253
  AST_NODE_TYPES.ArrowFunctionExpression,
8909
7254
  AST_NODE_TYPES.CallExpression,
@@ -8911,10 +7256,6 @@ const KNOWN_DYNAMIC_EXPRESSION_TYPES = /* @__PURE__ */ new Set([
8911
7256
  AST_NODE_TYPES.FunctionExpression,
8912
7257
  AST_NODE_TYPES.NewExpression
8913
7258
  ]);
8914
- /**
8915
- * Builds a predicate that tells whether a given node lies within the body of one of the
8916
- * collected function or class components, i.e. whether it is "created during render".
8917
- */
8918
7259
  function createRenderBoundaryChecker(componentNodes) {
8919
7260
  const components = new Set(componentNodes);
8920
7261
  return (node) => Traverse.findParent(node, (n) => (Check.isFunction(n) || Check.isClass(n)) && components.has(n)) != null;
@@ -8922,11 +7263,6 @@ function createRenderBoundaryChecker(componentNodes) {
8922
7263
 
8923
7264
  //#endregion
8924
7265
  //#region src/rules/static-components/origins.ts
8925
- /**
8926
- * Resolves an expression down to the node that dynamically created its value, if any.
8927
- * Recurses through identifier references, both branches of ternaries and logical
8928
- * expressions, and the final element of sequence expressions.
8929
- */
8930
7266
  function findDynamicCreationSite(context, node, isInsideRender, seen) {
8931
7267
  const expr = Extract.unwrap(node);
8932
7268
  if (KNOWN_DYNAMIC_EXPRESSION_TYPES.has(expr.type)) return expr;
@@ -8946,10 +7282,6 @@ function findDynamicCreationSite(context, node, isInsideRender, seen) {
8946
7282
  default: return null;
8947
7283
  }
8948
7284
  }
8949
- /**
8950
- * Looks for a reassignment of `variable` (e.g. `Component = createComponent();`) whose
8951
- * right-hand side is dynamically created.
8952
- */
8953
7285
  function findReassignmentCreationSite(context, variable, isInsideRender, seen) {
8954
7286
  for (const ref of variable.references) {
8955
7287
  if (!ref.isWrite()) continue;
@@ -8960,10 +7292,6 @@ function findReassignmentCreationSite(context, variable, isInsideRender, seen) {
8960
7292
  }
8961
7293
  return null;
8962
7294
  }
8963
- /**
8964
- * Resolves a component binding to the node that dynamically created its value, if the
8965
- * value is created during render (a fresh function/class/call result on every render).
8966
- */
8967
7295
  function resolveDynamicComponentOrigin(context, variable, isInsideRender, seen = /* @__PURE__ */ new Set()) {
8968
7296
  if (seen.has(variable)) return {
8969
7297
  creationNode: null,
@@ -8997,11 +7325,6 @@ function resolveDynamicComponentOrigin(context, variable, isInsideRender, seen =
8997
7325
 
8998
7326
  //#endregion
8999
7327
  //#region src/rules/static-components/effects.ts
9000
- /**
9001
- * Turn collected JSX component usages into effects: a usage is an effect when the
9002
- * binding it refers to is declared inside a component's render body and its value is
9003
- * dynamically created, i.e. the component is recreated on every render.
9004
- */
9005
7328
  function inferCreatedComponents(context, componentUsages, isInsideRender) {
9006
7329
  const effects = [];
9007
7330
  for (const usage of componentUsages) {
@@ -9142,22 +7465,11 @@ function create$2(context) {
9142
7465
 
9143
7466
  //#endregion
9144
7467
  //#region src/rules/use-memo/helpers.ts
9145
- /**
9146
- * Check whether the result of a `useMemo` call is used (assigned, returned,
9147
- * passed as an argument, etc.) rather than discarded as a bare statement.
9148
- * @param node The `useMemo` call expression
9149
- * @returns `true` when the call result flows into a surrounding expression
9150
- */
9151
7468
  function isResultUsed(node) {
9152
7469
  let parent = node.parent;
9153
7470
  while (Check.isTypeExpression(parent)) parent = parent.parent;
9154
7471
  return parent.type === AST_NODE_TYPES.VariableDeclarator || parent.type === AST_NODE_TYPES.AssignmentExpression || parent.type === AST_NODE_TYPES.AssignmentPattern || parent.type === AST_NODE_TYPES.Property || parent.type === AST_NODE_TYPES.ReturnStatement || parent.type === AST_NODE_TYPES.JSXExpressionContainer || parent.type === AST_NODE_TYPES.CallExpression || parent.type === AST_NODE_TYPES.NewExpression || parent.type === AST_NODE_TYPES.ArrayExpression || parent.type === AST_NODE_TYPES.ConditionalExpression || parent.type === AST_NODE_TYPES.LogicalExpression || parent.type === AST_NODE_TYPES.SequenceExpression || parent.type === AST_NODE_TYPES.SpreadElement || parent.type === AST_NODE_TYPES.TemplateLiteral || parent.type === AST_NODE_TYPES.BinaryExpression || parent.type === AST_NODE_TYPES.UnaryExpression || parent.type === AST_NODE_TYPES.MemberExpression || parent.type === AST_NODE_TYPES.TaggedTemplateExpression || parent.type === AST_NODE_TYPES.ChainExpression || parent.type === AST_NODE_TYPES.ArrowFunctionExpression || parent.type === AST_NODE_TYPES.ForOfStatement || parent.type === AST_NODE_TYPES.ForInStatement;
9155
7472
  }
9156
- /**
9157
- * Gets the nested return statements in the node that are within the same function
9158
- * @param node The AST node
9159
- * @returns The nested return statements in the node
9160
- */
9161
7473
  function getNestedReturnStatements(node) {
9162
7474
  const statements = [];
9163
7475
  const boundary = Check.isFunction(node) ? node : Traverse.findParent(node, Check.isFunction);
@@ -9226,15 +7538,6 @@ function isDeclaredInsideCallback(variable, callback) {
9226
7538
  }
9227
7539
  return false;
9228
7540
  }
9229
- /**
9230
- * Resolve whether an identifier written inside a `useMemo` callback refers to a
9231
- * variable declared outside the callback. Unresolved identifiers and variables
9232
- * without definitions are treated as outer variables.
9233
- * @param context The rule context
9234
- * @param target The written identifier
9235
- * @param callback The `useMemo` callback the write occurs in
9236
- * @returns `true` when the write reassigns an outer variable
9237
- */
9238
7541
  function isOuterVariable(context, target, callback) {
9239
7542
  const scope = context.sourceCode.getScope(target);
9240
7543
  const variable = findVariable(scope, target);
@@ -9244,14 +7547,6 @@ function isOuterVariable(context, target, callback) {
9244
7547
 
9245
7548
  //#endregion
9246
7549
  //#region src/rules/use-memo/effects.ts
9247
- /**
9248
- * Infer the `useMemo` usage violations from the collected facts: unused
9249
- * results, callbacks with parameters, async or generator callbacks, outer
9250
- * variable reassignments, and callbacks that never return a value.
9251
- * @param context The rule context
9252
- * @param facts The collected facts
9253
- * @returns The violations to report, in report order
9254
- */
9255
7550
  function inferViolations(context, facts) {
9256
7551
  const violations = [];
9257
7552
  for (const fact of facts.calls) {
@@ -9384,12 +7679,6 @@ const EXPRESSION_VISITOR_KEYS = {
9384
7679
  [AST_NODE_TYPES.WhileStatement]: ["test"],
9385
7680
  [AST_NODE_TYPES.YieldExpression]: ["argument"]
9386
7681
  };
9387
- /**
9388
- * Get all nested expressions of type T in an expression like node
9389
- * @param type The type of the expression to retrieve within the node
9390
- * @returns A partially applied function bound to a predicate of type AST. The returned function can be called passing a
9391
- * node, and it will return an array of all nested expressions of type AST.
9392
- */
9393
7682
  function getNestedExpressionsOfType(type) {
9394
7683
  const isNodeOfType = Check.is(type);
9395
7684
  const recurse = (node) => {
@@ -9405,17 +7694,7 @@ function getNestedExpressionsOfType(type) {
9405
7694
  };
9406
7695
  return recurse;
9407
7696
  }
9408
- /**
9409
- * Get all nested new expressions in an expression like node
9410
- * @param node The node to get the nested new expressions from
9411
- * @returns All nested new expressions
9412
- */
9413
7697
  const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExpression);
9414
- /**
9415
- * Get all nested call expressions in a expression like node
9416
- * @param node The node to get the nested call expressions from
9417
- * @returns All nested call expressions
9418
- */
9419
7698
  const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
9420
7699
 
9421
7700
  //#endregion
@@ -9468,7 +7747,7 @@ function create(context) {
9468
7747
  const [useStateInput] = node.arguments;
9469
7748
  if (useStateInput != null) {
9470
7749
  for (const expr of getNestedNewExpressions(useStateInput)) {
9471
- if (!("name" in expr.callee)) continue;
7750
+ if (!hasProperty(expr.callee, "name")) continue;
9472
7751
  if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
9473
7752
  if (Traverse.findParent(expr, (n) => core.isUseCall(context, n)) != null) continue;
9474
7753
  context.report({
@@ -9477,7 +7756,7 @@ function create(context) {
9477
7756
  });
9478
7757
  }
9479
7758
  for (const expr of getNestedCallExpressions(useStateInput)) {
9480
- if (!("name" in expr.callee)) continue;
7759
+ if (!hasProperty(expr.callee, "name")) continue;
9481
7760
  if (core.isHookName(expr.callee.name)) continue;
9482
7761
  if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
9483
7762
  if (Traverse.findParent(expr, (n) => core.isUseCall(context, n)) != null) continue;
@@ -9749,45 +8028,15 @@ function createConfig(base) {
9749
8028
  const finalPlugin = {
9750
8029
  ...plugin,
9751
8030
  configs: {
9752
- /**
9753
- * Disable rules in `eslint-plugin-react` that conflict with rules in this plugin
9754
- */
9755
8031
  ["disable-conflict-eslint-plugin-react"]: createConfig(disable_conflict_eslint_plugin_react_exports),
9756
- /**
9757
- * Disable rules in `eslint-plugin-react-hooks` that conflict with rules in this plugin
9758
- */
9759
8032
  ["disable-conflict-eslint-plugin-react-hooks"]: createConfig(disable_conflict_eslint_plugin_react_hooks_exports),
9760
- /**
9761
- * Disable experimental rules that might be subject to change in the future
9762
- */
9763
8033
  ["disable-experimental"]: createConfig(disable_experimental_exports),
9764
- /**
9765
- * Disable rules that can be enforced by TypeScript
9766
- */
9767
8034
  ["disable-type-checked"]: createConfig(disable_type_checked_exports),
9768
- /**
9769
- * Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects
9770
- */
9771
8035
  ["recommended"]: createConfig(recommended_exports),
9772
- /**
9773
- * Same as the `recommended-typescript` preset but enables additional rules that require type information
9774
- */
9775
8036
  ["recommended-type-checked"]: createConfig(recommended_type_checked_exports),
9776
- /**
9777
- * Same as the `recommended` preset but disables rules that can be enforced by TypeScript
9778
- */
9779
8037
  ["recommended-typescript"]: createConfig(recommended_typescript_exports),
9780
- /**
9781
- * More strict version of the `recommended` preset
9782
- */
9783
8038
  ["strict"]: createConfig(strict_exports),
9784
- /**
9785
- * Same as the `strict-typescript` preset but enables additional rules that require type information
9786
- */
9787
8039
  ["strict-type-checked"]: createConfig(strict_type_checked_exports),
9788
- /**
9789
- * Same as the `strict` preset but disables rules that can be enforced by TypeScript
9790
- */
9791
8040
  ["strict-typescript"]: createConfig(strict_typescript_exports)
9792
8041
  }
9793
8042
  };