miniread 1.118.0 → 1.119.0

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 (65) hide show
  1. package/dist/transforms/preset-stats.json +2 -2
  2. package/dist/transforms-by-id/expand-typeof-undefined-comparisons/expand-typeof-undefined-comparisons-transform.js +8 -1
  3. package/dist/transforms-by-id/expand-typeof-undefined-comparisons/manifest.json +5 -5
  4. package/dist/transforms-by-id/expand-typeof-undefined-comparisons/resolve-typeof-equality.js +18 -5
  5. package/dist/transforms-by-id/expand-typeof-undefined-comparisons/resolve-typeof-undefined-comparison.js +10 -3
  6. package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.d.ts +17 -0
  7. package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.js +1 -0
  8. package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-expression.d.ts +4 -0
  9. package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-expression.js +26 -0
  10. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-base-name.d.ts +2 -0
  11. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-base-name.js +33 -0
  12. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-condition-from-binary.d.ts +3 -0
  13. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-condition-from-binary.js +124 -0
  14. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-match.d.ts +3 -0
  15. package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-match.js +41 -0
  16. package/dist/transforms-by-id/rename-arguments-length-flags/manifest.json +6 -6
  17. package/dist/transforms-by-id/rename-arguments-length-flags/rename-arguments-length-flags-transform.js +6 -87
  18. package/dist/transforms-by-id/rename-awaiter-parameters/awaiter-pattern.js +12 -6
  19. package/dist/transforms-by-id/rename-awaiter-parameters/manifest.json +7 -7
  20. package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-bindings.js +80 -1
  21. package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-parameters-transform.js +3 -3
  22. package/dist/transforms-by-id/rename-buffer-variables/is-allowed-buffer-binding.js +43 -7
  23. package/dist/transforms-by-id/rename-buffer-variables/is-allowed-buffer-factory-call.js +42 -11
  24. package/dist/transforms-by-id/rename-buffer-variables/manifest.json +4 -4
  25. package/dist/transforms-by-id/rename-buffer-variables/rename-buffer-variables-transform.js +30 -9
  26. package/dist/transforms-by-id/rename-default-options-parameters-v3/collect-options-like-reference-signals.d.ts +7 -0
  27. package/dist/transforms-by-id/rename-default-options-parameters-v3/collect-options-like-reference-signals.js +65 -0
  28. package/dist/transforms-by-id/rename-default-options-parameters-v3/manifest.json +3 -3
  29. package/dist/transforms-by-id/rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.js +14 -26
  30. package/dist/transforms-by-id/rename-fs-sync-variables/manifest.json +5 -5
  31. package/dist/transforms-by-id/rename-fs-sync-variables/rename-fs-sync-variables-transform.js +29 -2
  32. package/dist/transforms-by-id/rename-map-by-id-variables/get-map-by-id-pattern.d.ts +3 -1
  33. package/dist/transforms-by-id/rename-map-by-id-variables/get-map-by-id-pattern.js +56 -37
  34. package/dist/transforms-by-id/rename-map-by-id-variables/manifest.json +4 -4
  35. package/dist/transforms-by-id/rename-map-by-id-variables/rename-map-by-id-variables-transform.js +51 -21
  36. package/dist/transforms-by-id/rename-object-keys-reducer-parameters/is-object-keys-reduce-call.d.ts +3 -1
  37. package/dist/transforms-by-id/rename-object-keys-reducer-parameters/is-object-keys-reduce-call.js +37 -30
  38. package/dist/transforms-by-id/rename-object-keys-reducer-parameters/manifest.json +4 -4
  39. package/dist/transforms-by-id/rename-object-keys-reducer-parameters/rename-object-keys-reducer-parameters-transform.js +8 -4
  40. package/dist/transforms-by-id/rename-timeout-promises/add-assignment-timeout-promise-rename-candidate.d.ts +19 -0
  41. package/dist/transforms-by-id/rename-timeout-promises/add-assignment-timeout-promise-rename-candidate.js +76 -0
  42. package/dist/transforms-by-id/rename-timeout-promises/add-executor-parameter-renames.d.ts +4 -0
  43. package/dist/transforms-by-id/rename-timeout-promises/add-executor-parameter-renames.js +30 -0
  44. package/dist/transforms-by-id/rename-timeout-promises/get-promise-executor-parameters.d.ts +1 -1
  45. package/dist/transforms-by-id/rename-timeout-promises/get-promise-executor-parameters.js +3 -3
  46. package/dist/transforms-by-id/rename-timeout-promises/is-promise-constructor.d.ts +3 -0
  47. package/dist/transforms-by-id/rename-timeout-promises/is-promise-constructor.js +53 -0
  48. package/dist/transforms-by-id/rename-timeout-promises/manifest.json +4 -4
  49. package/dist/transforms-by-id/rename-timeout-promises/rename-timeout-promises-transform.js +18 -79
  50. package/dist/transforms-by-id/rename-timeout-promises/set-timeout-usage.js +0 -3
  51. package/dist/transforms-by-id/rename-url-parameters/manifest.json +4 -4
  52. package/dist/transforms-by-id/rename-url-parameters/rename-url-parameters-transform.js +7 -10
  53. package/dist/transforms-by-id/rename-url-parameters/url-parameter-rename-overlap.d.ts +1 -1
  54. package/dist/transforms-by-id/rename-url-parameters/url-parameter-rename-overlap.js +23 -43
  55. package/dist/transforms-by-id/simplify-boolean-negations/get-negated-static-binary-comparison.d.ts +3 -0
  56. package/dist/transforms-by-id/simplify-boolean-negations/get-negated-static-binary-comparison.js +108 -0
  57. package/dist/transforms-by-id/simplify-boolean-negations/get-simplified-negation-replacement.d.ts +3 -0
  58. package/dist/transforms-by-id/simplify-boolean-negations/get-simplified-negation-replacement.js +90 -0
  59. package/dist/transforms-by-id/simplify-boolean-negations/manifest.json +3 -3
  60. package/dist/transforms-by-id/simplify-boolean-negations/simplify-boolean-negations-transform.js +36 -41
  61. package/dist/transforms-by-id/use-object-shorthand/collect-dynamic-lookup-info.d.ts +8 -0
  62. package/dist/transforms-by-id/use-object-shorthand/collect-dynamic-lookup-info.js +65 -0
  63. package/dist/transforms-by-id/use-object-shorthand/manifest.json +4 -4
  64. package/dist/transforms-by-id/use-object-shorthand/use-object-shorthand-transform.js +13 -5
  65. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "recommended": {
3
- "diffSizePercent": 26.024303586952414,
4
- "notes": "Measured with baseline none: 26.02% of original diff."
3
+ "diffSizePercent": 26.01296443285331,
4
+ "notes": "Measured with baseline none: 26.01% of original diff."
5
5
  }
6
6
  }
@@ -21,7 +21,14 @@ export const expandTypeofUndefinedComparisonsTransform = {
21
21
  nodesVisited++;
22
22
  const strictEquality = getStrictTypeofEquality(path.node);
23
23
  if (strictEquality) {
24
- const replacement = t.binaryExpression(strictEquality.operator, t.cloneNode(strictEquality.typeofExpression, true), t.cloneNode(strictEquality.literal, true));
24
+ const directTarget = strictEquality.literal.value === "undefined"
25
+ ? getDirectUndefinedComparisonTarget(path, strictEquality.typeofExpression)
26
+ : undefined;
27
+ const replacement = t.binaryExpression(strictEquality.operator, directTarget
28
+ ? t.cloneNode(directTarget, true)
29
+ : t.cloneNode(strictEquality.typeofExpression, true), directTarget
30
+ ? getUndefinedExpression(path)
31
+ : t.cloneNode(strictEquality.literal, true));
25
32
  path.replaceWith(replacement);
26
33
  transformationsApplied++;
27
34
  return;
@@ -1,14 +1,14 @@
1
1
  {
2
- "recommended": true,
3
- "recommendedOrder": 100,
4
2
  "notes": "Improves readability by expanding minified typeof comparisons; expected to be diff-neutral.",
5
3
  "evaluations": {
6
4
  "claude-code-2.1.10:claude-code-2.1.11": {
7
5
  "diffSizePercent": 100,
8
- "evaluatedAt": "2026-02-09T07:16:31.721Z",
6
+ "evaluatedAt": "2026-02-22T07:02:45.911Z",
9
7
  "changedLines": 1388,
10
- "durationSeconds": 37.124273,
8
+ "durationSeconds": 187.91025176099998,
11
9
  "stableNames": 1357
12
10
  }
13
- }
11
+ },
12
+ "recommended": true,
13
+ "recommendedOrder": 100
14
14
  }
@@ -7,15 +7,25 @@ const isTypeofExpression = (expression) => isExpression(expression) &&
7
7
  const getStringLiteral = (expression) => {
8
8
  if (!isExpression(expression))
9
9
  return undefined;
10
- if (!t.isStringLiteral(expression))
11
- return undefined;
12
- return expression;
10
+ if (t.isStringLiteral(expression))
11
+ return expression;
12
+ if (t.isTemplateLiteral(expression) &&
13
+ expression.expressions.length === 0 &&
14
+ expression.quasis.length === 1) {
15
+ return t.stringLiteral(expression.quasis[0]?.value.cooked ?? "");
16
+ }
17
+ return undefined;
13
18
  };
14
19
  export const getStrictTypeofEquality = (expression) => {
15
- if (expression.operator !== "==" && expression.operator !== "!=") {
20
+ if (expression.operator !== "==" &&
21
+ expression.operator !== "!=" &&
22
+ expression.operator !== "===" &&
23
+ expression.operator !== "!==") {
16
24
  return undefined;
17
25
  }
18
- const operator = expression.operator === "==" ? "===" : "!==";
26
+ const operator = expression.operator === "==" || expression.operator === "==="
27
+ ? "==="
28
+ : "!==";
19
29
  const leftTypeof = isTypeofExpression(expression.left)
20
30
  ? expression.left
21
31
  : undefined;
@@ -25,6 +35,9 @@ export const getStrictTypeofEquality = (expression) => {
25
35
  const leftLiteral = getStringLiteral(expression.left);
26
36
  const rightLiteral = getStringLiteral(expression.right);
27
37
  if (leftTypeof && rightLiteral) {
38
+ if (expression.operator === "===" || expression.operator === "!==") {
39
+ return undefined;
40
+ }
28
41
  return {
29
42
  typeofExpression: leftTypeof,
30
43
  operator,
@@ -7,10 +7,17 @@ const isTypeofExpression = (expression) => isExpression(expression) &&
7
7
  const getTypeofLiteralValue = (expression) => {
8
8
  if (!isExpression(expression))
9
9
  return undefined;
10
- if (!t.isStringLiteral(expression))
10
+ const literalValue = t.isStringLiteral(expression)
11
+ ? expression.value
12
+ : t.isTemplateLiteral(expression) &&
13
+ expression.expressions.length === 0 &&
14
+ expression.quasis.length === 1
15
+ ? expression.quasis[0]?.value.cooked
16
+ : undefined;
17
+ if (!literalValue)
11
18
  return undefined;
12
- if (expression.value === "u" || expression.value === "undefined") {
13
- return expression.value;
19
+ if (literalValue === "u" || literalValue === "undefined") {
20
+ return literalValue;
14
21
  }
15
22
  return undefined;
16
23
  };
@@ -0,0 +1,17 @@
1
+ export type ArgumentsLengthCondition = {
2
+ kind: "atLeast";
3
+ count: number;
4
+ } | {
5
+ kind: "fewerThan";
6
+ count: number;
7
+ } | {
8
+ kind: "exactly";
9
+ count: number;
10
+ } | {
11
+ kind: "notExactly";
12
+ count: number;
13
+ };
14
+ export type ArgumentsLengthMatch = {
15
+ condition: ArgumentsLengthCondition;
16
+ hasAdditionalCondition: boolean;
17
+ };
@@ -0,0 +1,4 @@
1
+ import type { Expression, PrivateName } from "@babel/types";
2
+ export declare const isArgumentsLengthExpression: (expression: Expression) => boolean;
3
+ export declare const getExpression: (node: Expression | PrivateName) => Expression | undefined;
4
+ export declare const getNumericLiteralValue: (node: Expression) => number | undefined;
@@ -0,0 +1,26 @@
1
+ import { isIdentifier, isMemberExpression, isNumericLiteral, isPrivateName, isStringLiteral, } from "@babel/types";
2
+ export const isArgumentsLengthExpression = (expression) => {
3
+ if (!isMemberExpression(expression))
4
+ return false;
5
+ if (!isIdentifier(expression.object))
6
+ return false;
7
+ if (expression.object.name !== "arguments")
8
+ return false;
9
+ if (expression.computed) {
10
+ return (isStringLiteral(expression.property) &&
11
+ expression.property.value === "length");
12
+ }
13
+ return (isIdentifier(expression.property) && expression.property.name === "length");
14
+ };
15
+ export const getExpression = (node) => {
16
+ if (isPrivateName(node))
17
+ return undefined;
18
+ return node;
19
+ };
20
+ export const getNumericLiteralValue = (node) => {
21
+ if (!isNumericLiteral(node))
22
+ return undefined;
23
+ if (!Number.isInteger(node.value))
24
+ return undefined;
25
+ return node.value;
26
+ };
@@ -0,0 +1,2 @@
1
+ import type { ArgumentsLengthMatch } from "./arguments-length-condition-types.js";
2
+ export declare const getArgumentsLengthBaseName: (match: ArgumentsLengthMatch) => string;
@@ -0,0 +1,33 @@
1
+ export const getArgumentsLengthBaseName = (match) => {
2
+ const { condition } = match;
3
+ if (condition.kind === "fewerThan") {
4
+ const base = condition.count === 1
5
+ ? "hasNoArgs"
6
+ : `hasFewerThan${condition.count}Args`;
7
+ if (!match.hasAdditionalCondition)
8
+ return base;
9
+ return `${base}AndCondition`;
10
+ }
11
+ if (condition.kind === "exactly") {
12
+ const base = condition.count === 1
13
+ ? "hasExactly1Arg"
14
+ : `hasExactly${condition.count}Args`;
15
+ if (!match.hasAdditionalCondition)
16
+ return base;
17
+ return `${base}AndCondition`;
18
+ }
19
+ if (condition.kind === "notExactly") {
20
+ const base = condition.count === 1
21
+ ? "doesNotHaveExactly1Arg"
22
+ : `doesNotHaveExactly${condition.count}Args`;
23
+ if (!match.hasAdditionalCondition)
24
+ return base;
25
+ return `${base}AndCondition`;
26
+ }
27
+ const base = condition.count === 1
28
+ ? "hasAtLeast1Arg"
29
+ : `hasAtLeast${condition.count}Args`;
30
+ if (!match.hasAdditionalCondition)
31
+ return base;
32
+ return `${base}AndCondition`;
33
+ };
@@ -0,0 +1,3 @@
1
+ import type { BinaryExpression } from "@babel/types";
2
+ import type { ArgumentsLengthMatch } from "./arguments-length-condition-types.js";
3
+ export declare const getArgumentsLengthConditionFromBinary: (init: BinaryExpression) => ArgumentsLengthMatch | undefined;
@@ -0,0 +1,124 @@
1
+ import { getExpression, getNumericLiteralValue, isArgumentsLengthExpression, } from "./arguments-length-expression.js";
2
+ export const getArgumentsLengthConditionFromBinary = (init) => {
3
+ const left = getExpression(init.left);
4
+ const right = getExpression(init.right);
5
+ if (!left || !right)
6
+ return undefined;
7
+ if (init.operator === ">" || init.operator === ">=") {
8
+ if (isArgumentsLengthExpression(left)) {
9
+ const value = getNumericLiteralValue(right);
10
+ if (value === undefined)
11
+ return undefined;
12
+ return {
13
+ condition: {
14
+ kind: "atLeast",
15
+ count: init.operator === ">" ? value + 1 : value,
16
+ },
17
+ hasAdditionalCondition: false,
18
+ };
19
+ }
20
+ if (isArgumentsLengthExpression(right)) {
21
+ const value = getNumericLiteralValue(left);
22
+ if (value === undefined)
23
+ return undefined;
24
+ return {
25
+ condition: {
26
+ kind: "fewerThan",
27
+ count: init.operator === ">" ? value : value + 1,
28
+ },
29
+ hasAdditionalCondition: false,
30
+ };
31
+ }
32
+ }
33
+ if (init.operator === "<" || init.operator === "<=") {
34
+ if (isArgumentsLengthExpression(left)) {
35
+ const value = getNumericLiteralValue(right);
36
+ if (value === undefined)
37
+ return undefined;
38
+ return {
39
+ condition: {
40
+ kind: "fewerThan",
41
+ count: init.operator === "<" ? value : value + 1,
42
+ },
43
+ hasAdditionalCondition: false,
44
+ };
45
+ }
46
+ if (isArgumentsLengthExpression(right)) {
47
+ const value = getNumericLiteralValue(left);
48
+ if (value === undefined)
49
+ return undefined;
50
+ return {
51
+ condition: {
52
+ kind: "atLeast",
53
+ count: init.operator === "<" ? value + 1 : value,
54
+ },
55
+ hasAdditionalCondition: false,
56
+ };
57
+ }
58
+ }
59
+ if (init.operator === "!=" || init.operator === "!==") {
60
+ if (isArgumentsLengthExpression(left)) {
61
+ const value = getNumericLiteralValue(right);
62
+ if (value === undefined || value < 0)
63
+ return undefined;
64
+ if (value === 0) {
65
+ return {
66
+ condition: { kind: "atLeast", count: 1 },
67
+ hasAdditionalCondition: false,
68
+ };
69
+ }
70
+ return {
71
+ condition: { kind: "notExactly", count: value },
72
+ hasAdditionalCondition: false,
73
+ };
74
+ }
75
+ if (isArgumentsLengthExpression(right)) {
76
+ const value = getNumericLiteralValue(left);
77
+ if (value === undefined || value < 0)
78
+ return undefined;
79
+ if (value === 0) {
80
+ return {
81
+ condition: { kind: "atLeast", count: 1 },
82
+ hasAdditionalCondition: false,
83
+ };
84
+ }
85
+ return {
86
+ condition: { kind: "notExactly", count: value },
87
+ hasAdditionalCondition: false,
88
+ };
89
+ }
90
+ }
91
+ if (init.operator === "==" || init.operator === "===") {
92
+ if (isArgumentsLengthExpression(left)) {
93
+ const value = getNumericLiteralValue(right);
94
+ if (value === undefined || value < 0)
95
+ return undefined;
96
+ if (value === 0) {
97
+ return {
98
+ condition: { kind: "fewerThan", count: 1 },
99
+ hasAdditionalCondition: false,
100
+ };
101
+ }
102
+ return {
103
+ condition: { kind: "exactly", count: value },
104
+ hasAdditionalCondition: false,
105
+ };
106
+ }
107
+ if (isArgumentsLengthExpression(right)) {
108
+ const value = getNumericLiteralValue(left);
109
+ if (value === undefined || value < 0)
110
+ return undefined;
111
+ if (value === 0) {
112
+ return {
113
+ condition: { kind: "fewerThan", count: 1 },
114
+ hasAdditionalCondition: false,
115
+ };
116
+ }
117
+ return {
118
+ condition: { kind: "exactly", count: value },
119
+ hasAdditionalCondition: false,
120
+ };
121
+ }
122
+ }
123
+ return undefined;
124
+ };
@@ -0,0 +1,3 @@
1
+ import type { Expression } from "@babel/types";
2
+ import type { ArgumentsLengthMatch } from "./arguments-length-condition-types.js";
3
+ export declare const getArgumentsLengthMatch: (init: Expression) => ArgumentsLengthMatch | undefined;
@@ -0,0 +1,41 @@
1
+ import { isUnaryExpression } from "@babel/types";
2
+ import { isArgumentsLengthExpression } from "./arguments-length-expression.js";
3
+ import { getArgumentsLengthConditionFromBinary } from "./get-arguments-length-condition-from-binary.js";
4
+ export const getArgumentsLengthMatch = (init) => {
5
+ if (init.type === "LogicalExpression" && init.operator === "&&") {
6
+ const leftMatch = getArgumentsLengthMatch(init.left);
7
+ if (leftMatch) {
8
+ return {
9
+ condition: leftMatch.condition,
10
+ hasAdditionalCondition: true,
11
+ };
12
+ }
13
+ const rightMatch = getArgumentsLengthMatch(init.right);
14
+ if (!rightMatch)
15
+ return undefined;
16
+ return {
17
+ condition: rightMatch.condition,
18
+ hasAdditionalCondition: true,
19
+ };
20
+ }
21
+ if (isUnaryExpression(init) && init.operator === "!") {
22
+ if (isArgumentsLengthExpression(init.argument)) {
23
+ return {
24
+ condition: { kind: "fewerThan", count: 1 },
25
+ hasAdditionalCondition: false,
26
+ };
27
+ }
28
+ if (isUnaryExpression(init.argument) &&
29
+ init.argument.operator === "!" &&
30
+ isArgumentsLengthExpression(init.argument.argument)) {
31
+ return {
32
+ condition: { kind: "atLeast", count: 1 },
33
+ hasAdditionalCondition: false,
34
+ };
35
+ }
36
+ return undefined;
37
+ }
38
+ if (init.type !== "BinaryExpression")
39
+ return undefined;
40
+ return getArgumentsLengthConditionFromBinary(init);
41
+ };
@@ -1,14 +1,14 @@
1
1
  {
2
- "recommended": true,
3
- "recommendedOrder": 100,
4
2
  "notes": "Measured with baseline none: 0.00%. Added to recommended for readability.",
5
3
  "evaluations": {
6
4
  "claude-code-2.1.10:claude-code-2.1.11": {
7
5
  "diffSizePercent": 100,
8
- "evaluatedAt": "2026-02-09T07:29:29.102Z",
9
- "changedLines": 32,
10
- "durationSeconds": 34.273026958,
6
+ "evaluatedAt": "2026-02-22T05:46:09.337Z",
7
+ "changedLines": 42,
8
+ "durationSeconds": 37.382712167,
11
9
  "stableNames": 1360
12
10
  }
13
- }
11
+ },
12
+ "recommended": true,
13
+ "recommendedOrder": 100
14
14
  }
@@ -1,93 +1,12 @@
1
1
  import { createRequire } from "node:module";
2
- import { isIdentifier, isMemberExpression, isNumericLiteral, isPrivateName, isStringLiteral, } from "@babel/types";
3
2
  import { RenameGroup, isStableRenamed } from "../../core/stable-naming.js";
4
3
  import { getFilesToProcess, } from "../../core/types.js";
4
+ import { getArgumentsLengthBaseName } from "./get-arguments-length-base-name.js";
5
+ import { getArgumentsLengthMatch } from "./get-arguments-length-match.js";
5
6
  import { hasShadowedArgumentsBinding } from "./has-shadowed-arguments-binding.js";
6
7
  const require = createRequire(import.meta.url);
7
8
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
8
9
  const traverse = require("@babel/traverse").default;
9
- const isArgumentsLengthExpression = (expression) => {
10
- if (!isMemberExpression(expression))
11
- return false;
12
- if (!isIdentifier(expression.object))
13
- return false;
14
- if (expression.object.name !== "arguments")
15
- return false;
16
- if (expression.computed) {
17
- return (isStringLiteral(expression.property) &&
18
- expression.property.value === "length");
19
- }
20
- return (isIdentifier(expression.property) && expression.property.name === "length");
21
- };
22
- const getExpression = (node) => {
23
- if (isPrivateName(node))
24
- return undefined;
25
- return node;
26
- };
27
- const getNumericLiteralValue = (node) => {
28
- if (!isNumericLiteral(node))
29
- return undefined;
30
- if (!Number.isInteger(node.value))
31
- return undefined;
32
- return node.value;
33
- };
34
- const getArgumentsLengthCondition = (init) => {
35
- const left = getExpression(init.left);
36
- const right = getExpression(init.right);
37
- if (!left || !right)
38
- return undefined;
39
- if (init.operator === ">" || init.operator === ">=") {
40
- if (isArgumentsLengthExpression(left)) {
41
- const value = getNumericLiteralValue(right);
42
- if (value === undefined)
43
- return undefined;
44
- return {
45
- kind: "atLeast",
46
- count: init.operator === ">" ? value + 1 : value,
47
- };
48
- }
49
- if (isArgumentsLengthExpression(right)) {
50
- const value = getNumericLiteralValue(left);
51
- if (value === undefined)
52
- return undefined;
53
- return {
54
- kind: "fewerThan",
55
- count: init.operator === ">" ? value : value + 1,
56
- };
57
- }
58
- }
59
- if (init.operator === "<" || init.operator === "<=") {
60
- if (isArgumentsLengthExpression(left)) {
61
- const value = getNumericLiteralValue(right);
62
- if (value === undefined)
63
- return undefined;
64
- return {
65
- kind: "fewerThan",
66
- count: init.operator === "<" ? value : value + 1,
67
- };
68
- }
69
- if (isArgumentsLengthExpression(right)) {
70
- const value = getNumericLiteralValue(left);
71
- if (value === undefined)
72
- return undefined;
73
- return {
74
- kind: "atLeast",
75
- count: init.operator === "<" ? value + 1 : value,
76
- };
77
- }
78
- }
79
- return undefined;
80
- };
81
- const getBaseName = (condition) => {
82
- if (condition.kind === "fewerThan") {
83
- if (condition.count === 1)
84
- return "hasNoArgs";
85
- return `hasFewerThan${condition.count}Args`;
86
- }
87
- if (condition.count === 1)
88
- return "hasAtLeast1Arg";
89
- return `hasAtLeast${condition.count}Args`;
90
- };
91
10
  export const renameArgumentsLengthFlagsTransform = {
92
11
  id: "rename-arguments-length-flags",
93
12
  description: "Rename arguments.length guards (>= N, < N) to $hasAtLeastNArgs/$hasFewerThanNArgs when stable",
@@ -107,12 +26,12 @@ export const renameArgumentsLengthFlagsTransform = {
107
26
  if (isStableRenamed(id.name))
108
27
  return;
109
28
  const init = path.node.init;
110
- if (init?.type !== "BinaryExpression")
29
+ if (!init)
111
30
  return;
112
31
  if (hasShadowedArgumentsBinding(path))
113
32
  return;
114
- const condition = getArgumentsLengthCondition(init);
115
- if (!condition || condition.count < 1)
33
+ const match = getArgumentsLengthMatch(init);
34
+ if (!match || match.condition.count < 1)
116
35
  return;
117
36
  const binding = path.scope.getBinding(id.name);
118
37
  if (!binding?.constant)
@@ -120,7 +39,7 @@ export const renameArgumentsLengthFlagsTransform = {
120
39
  renameGroup.add({
121
40
  scope: binding.scope,
122
41
  currentName: id.name,
123
- baseName: getBaseName(condition),
42
+ baseName: getArgumentsLengthBaseName(match),
124
43
  });
125
44
  },
126
45
  });
@@ -5,6 +5,13 @@ const isIdentifierParameters = (parameters) => {
5
5
  return parameters.every((parameter) => parameter.type === "Identifier");
6
6
  };
7
7
  const isIdentifierNamed = (node, name) => isIdentifier(node) && node.name === name;
8
+ const isStringLiteralNamed = (node, value) => node?.type === "StringLiteral" && node.value === value;
9
+ const isMemberPropertyNamed = (memberExpression, propertyName) => {
10
+ if (!memberExpression.computed) {
11
+ return isIdentifierNamed(memberExpression.property, propertyName);
12
+ }
13
+ return isStringLiteralNamed(memberExpression.property, propertyName);
14
+ };
8
15
  const isEmptyArrayExpression = (node) => node.elements.length === 0;
9
16
  const isArgumentsFallback = (node, argumentsName) => node.operator === "||" &&
10
17
  isIdentifierNamed(node.left, argumentsName) &&
@@ -14,11 +21,9 @@ const isGeneratorApplyCall = (node, generatorName, thisArgumentName, argumentsNa
14
21
  const callee = node.callee;
15
22
  if (callee.type !== "MemberExpression")
16
23
  return false;
17
- if (callee.computed)
18
- return false;
19
24
  if (!isIdentifierNamed(callee.object, generatorName))
20
25
  return false;
21
- if (!isIdentifierNamed(callee.property, "apply"))
26
+ if (!isMemberPropertyNamed(callee, "apply"))
22
27
  return false;
23
28
  if (node.arguments.length !== 2)
24
29
  return false;
@@ -27,6 +32,9 @@ const isGeneratorApplyCall = (node, generatorName, thisArgumentName, argumentsNa
27
32
  return false;
28
33
  if (!isIdentifierNamed(thisArgument, thisArgumentName))
29
34
  return false;
35
+ if (argumentsValue.type === "ArrayExpression") {
36
+ return isEmptyArrayExpression(argumentsValue);
37
+ }
30
38
  if (argumentsValue.type === "Identifier") {
31
39
  return argumentsValue.name === argumentsName;
32
40
  }
@@ -38,11 +46,9 @@ const isGeneratorMethodCall = (node, generatorName, methodName) => {
38
46
  const callee = node.callee;
39
47
  if (callee.type !== "MemberExpression")
40
48
  return false;
41
- if (callee.computed)
42
- return false;
43
49
  if (!isIdentifierNamed(callee.object, generatorName))
44
50
  return false;
45
- return isIdentifierNamed(callee.property, methodName);
51
+ return isMemberPropertyNamed(callee, methodName);
46
52
  };
47
53
  const isPromiseCtorNewExpression = (node, promiseCtorName) => {
48
54
  const callee = node.callee;
@@ -1,14 +1,14 @@
1
1
  {
2
- "recommended": true,
3
- "recommendedOrder": 100,
4
2
  "notes": "Measured with baseline none: 0.00%. Added to recommended for readability.",
5
3
  "evaluations": {
6
4
  "claude-code-2.1.10:claude-code-2.1.11": {
7
5
  "diffSizePercent": 100,
8
- "evaluatedAt": "2026-02-07T21:09:14.149Z",
9
- "changedLines": 196,
10
- "durationSeconds": 154.025962677,
11
- "stableNames": 1361
6
+ "evaluatedAt": "2026-02-22T10:26:55.132Z",
7
+ "changedLines": 280,
8
+ "durationSeconds": 31.154270667000002,
9
+ "stableNames": 1363
12
10
  }
13
- }
11
+ },
12
+ "recommended": true,
13
+ "recommendedOrder": 100
14
14
  }