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.
- package/dist/transforms/preset-stats.json +2 -2
- package/dist/transforms-by-id/expand-typeof-undefined-comparisons/expand-typeof-undefined-comparisons-transform.js +8 -1
- package/dist/transforms-by-id/expand-typeof-undefined-comparisons/manifest.json +5 -5
- package/dist/transforms-by-id/expand-typeof-undefined-comparisons/resolve-typeof-equality.js +18 -5
- package/dist/transforms-by-id/expand-typeof-undefined-comparisons/resolve-typeof-undefined-comparison.js +10 -3
- package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.d.ts +17 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.js +1 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-expression.d.ts +4 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-expression.js +26 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-base-name.d.ts +2 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-base-name.js +33 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-condition-from-binary.d.ts +3 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-condition-from-binary.js +124 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-match.d.ts +3 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/get-arguments-length-match.js +41 -0
- package/dist/transforms-by-id/rename-arguments-length-flags/manifest.json +6 -6
- package/dist/transforms-by-id/rename-arguments-length-flags/rename-arguments-length-flags-transform.js +6 -87
- package/dist/transforms-by-id/rename-awaiter-parameters/awaiter-pattern.js +12 -6
- package/dist/transforms-by-id/rename-awaiter-parameters/manifest.json +7 -7
- package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-bindings.js +80 -1
- package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-parameters-transform.js +3 -3
- package/dist/transforms-by-id/rename-buffer-variables/is-allowed-buffer-binding.js +43 -7
- package/dist/transforms-by-id/rename-buffer-variables/is-allowed-buffer-factory-call.js +42 -11
- package/dist/transforms-by-id/rename-buffer-variables/manifest.json +4 -4
- package/dist/transforms-by-id/rename-buffer-variables/rename-buffer-variables-transform.js +30 -9
- package/dist/transforms-by-id/rename-default-options-parameters-v3/collect-options-like-reference-signals.d.ts +7 -0
- package/dist/transforms-by-id/rename-default-options-parameters-v3/collect-options-like-reference-signals.js +65 -0
- package/dist/transforms-by-id/rename-default-options-parameters-v3/manifest.json +3 -3
- package/dist/transforms-by-id/rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.js +14 -26
- package/dist/transforms-by-id/rename-fs-sync-variables/manifest.json +5 -5
- package/dist/transforms-by-id/rename-fs-sync-variables/rename-fs-sync-variables-transform.js +29 -2
- package/dist/transforms-by-id/rename-map-by-id-variables/get-map-by-id-pattern.d.ts +3 -1
- package/dist/transforms-by-id/rename-map-by-id-variables/get-map-by-id-pattern.js +56 -37
- package/dist/transforms-by-id/rename-map-by-id-variables/manifest.json +4 -4
- package/dist/transforms-by-id/rename-map-by-id-variables/rename-map-by-id-variables-transform.js +51 -21
- package/dist/transforms-by-id/rename-object-keys-reducer-parameters/is-object-keys-reduce-call.d.ts +3 -1
- package/dist/transforms-by-id/rename-object-keys-reducer-parameters/is-object-keys-reduce-call.js +37 -30
- package/dist/transforms-by-id/rename-object-keys-reducer-parameters/manifest.json +4 -4
- package/dist/transforms-by-id/rename-object-keys-reducer-parameters/rename-object-keys-reducer-parameters-transform.js +8 -4
- package/dist/transforms-by-id/rename-timeout-promises/add-assignment-timeout-promise-rename-candidate.d.ts +19 -0
- package/dist/transforms-by-id/rename-timeout-promises/add-assignment-timeout-promise-rename-candidate.js +76 -0
- package/dist/transforms-by-id/rename-timeout-promises/add-executor-parameter-renames.d.ts +4 -0
- package/dist/transforms-by-id/rename-timeout-promises/add-executor-parameter-renames.js +30 -0
- package/dist/transforms-by-id/rename-timeout-promises/get-promise-executor-parameters.d.ts +1 -1
- package/dist/transforms-by-id/rename-timeout-promises/get-promise-executor-parameters.js +3 -3
- package/dist/transforms-by-id/rename-timeout-promises/is-promise-constructor.d.ts +3 -0
- package/dist/transforms-by-id/rename-timeout-promises/is-promise-constructor.js +53 -0
- package/dist/transforms-by-id/rename-timeout-promises/manifest.json +4 -4
- package/dist/transforms-by-id/rename-timeout-promises/rename-timeout-promises-transform.js +18 -79
- package/dist/transforms-by-id/rename-timeout-promises/set-timeout-usage.js +0 -3
- package/dist/transforms-by-id/rename-url-parameters/manifest.json +4 -4
- package/dist/transforms-by-id/rename-url-parameters/rename-url-parameters-transform.js +7 -10
- package/dist/transforms-by-id/rename-url-parameters/url-parameter-rename-overlap.d.ts +1 -1
- package/dist/transforms-by-id/rename-url-parameters/url-parameter-rename-overlap.js +23 -43
- package/dist/transforms-by-id/simplify-boolean-negations/get-negated-static-binary-comparison.d.ts +3 -0
- package/dist/transforms-by-id/simplify-boolean-negations/get-negated-static-binary-comparison.js +108 -0
- package/dist/transforms-by-id/simplify-boolean-negations/get-simplified-negation-replacement.d.ts +3 -0
- package/dist/transforms-by-id/simplify-boolean-negations/get-simplified-negation-replacement.js +90 -0
- package/dist/transforms-by-id/simplify-boolean-negations/manifest.json +3 -3
- package/dist/transforms-by-id/simplify-boolean-negations/simplify-boolean-negations-transform.js +36 -41
- package/dist/transforms-by-id/use-object-shorthand/collect-dynamic-lookup-info.d.ts +8 -0
- package/dist/transforms-by-id/use-object-shorthand/collect-dynamic-lookup-info.js +65 -0
- package/dist/transforms-by-id/use-object-shorthand/manifest.json +4 -4
- package/dist/transforms-by-id/use-object-shorthand/use-object-shorthand-transform.js +13 -5
- package/package.json +1 -1
|
@@ -21,7 +21,14 @@ export const expandTypeofUndefinedComparisonsTransform = {
|
|
|
21
21
|
nodesVisited++;
|
|
22
22
|
const strictEquality = getStrictTypeofEquality(path.node);
|
|
23
23
|
if (strictEquality) {
|
|
24
|
-
const
|
|
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-
|
|
6
|
+
"evaluatedAt": "2026-02-22T07:02:45.911Z",
|
|
9
7
|
"changedLines": 1388,
|
|
10
|
-
"durationSeconds":
|
|
8
|
+
"durationSeconds": 187.91025176099998,
|
|
11
9
|
"stableNames": 1357
|
|
12
10
|
}
|
|
13
|
-
}
|
|
11
|
+
},
|
|
12
|
+
"recommended": true,
|
|
13
|
+
"recommendedOrder": 100
|
|
14
14
|
}
|
package/dist/transforms-by-id/expand-typeof-undefined-comparisons/resolve-typeof-equality.js
CHANGED
|
@@ -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 (
|
|
11
|
-
return
|
|
12
|
-
|
|
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 !== "==" &&
|
|
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
|
-
|
|
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 (
|
|
13
|
-
return
|
|
19
|
+
if (literalValue === "u" || literalValue === "undefined") {
|
|
20
|
+
return literalValue;
|
|
14
21
|
}
|
|
15
22
|
return undefined;
|
|
16
23
|
};
|
package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.d.ts
ADDED
|
@@ -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
|
+
};
|
package/dist/transforms-by-id/rename-arguments-length-flags/arguments-length-condition-types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,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,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,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-
|
|
9
|
-
"changedLines":
|
|
10
|
-
"durationSeconds":
|
|
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
|
|
29
|
+
if (!init)
|
|
111
30
|
return;
|
|
112
31
|
if (hasShadowedArgumentsBinding(path))
|
|
113
32
|
return;
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
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:
|
|
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 (!
|
|
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
|
|
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-
|
|
9
|
-
"changedLines":
|
|
10
|
-
"durationSeconds":
|
|
11
|
-
"stableNames":
|
|
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
|
}
|