miniread 1.120.0 → 1.120.2
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/get-url-construction-kind.js +8 -1
- package/dist/transforms/preset-stats.json +2 -2
- package/dist/transforms/url-usage-heuristics.js +2 -2
- package/dist/transforms-by-id/expand-undefined-literals/expand-undefined-literals-transform.js +43 -3
- package/dist/transforms-by-id/expand-undefined-literals/manifest.json +3 -3
- package/dist/transforms-by-id/remove-redundant-else/does-switch-interrupt-boundary.d.ts +5 -0
- package/dist/transforms-by-id/remove-redundant-else/does-switch-interrupt-boundary.js +39 -0
- package/dist/transforms-by-id/remove-redundant-else/get-guaranteed-switch-case-index.d.ts +3 -0
- package/dist/transforms-by-id/remove-redundant-else/get-guaranteed-switch-case-index.js +58 -0
- package/dist/transforms-by-id/remove-redundant-else/get-last-non-empty-statement-index.d.ts +3 -0
- package/dist/transforms-by-id/remove-redundant-else/get-last-non-empty-statement-index.js +28 -0
- package/dist/transforms-by-id/remove-redundant-else/has-non-interrupting-switch-exit.d.ts +5 -0
- package/dist/transforms-by-id/remove-redundant-else/has-non-interrupting-switch-exit.js +44 -0
- package/dist/transforms-by-id/remove-redundant-else/is-interrupting-branch.d.ts +3 -0
- package/dist/transforms-by-id/remove-redundant-else/is-interrupting-branch.js +124 -0
- package/dist/transforms-by-id/remove-redundant-else/manifest.json +3 -3
- package/dist/transforms-by-id/remove-redundant-else/remove-redundant-else-transform.js +52 -40
- package/dist/transforms-by-id/rename-deferred-resolve-parameters-v2/deferred-executor-heuristics.js +1 -11
- package/dist/transforms-by-id/rename-deferred-resolve-parameters-v2/manifest.json +3 -3
- package/dist/transforms-by-id/rename-deferred-resolve-parameters-v2/rename-deferred-resolve-parameters-v2-transform.js +16 -23
- package/dist/transforms-by-id/rename-error-first-callback-parameters-v2/get-leading-error-first-guard.js +10 -2
- package/dist/transforms-by-id/rename-error-first-callback-parameters-v2/manifest.json +5 -5
- package/dist/transforms-by-id/rename-error-first-callback-parameters-v2/match-error-first-reject-resolve-pattern.d.ts +1 -1
- package/dist/transforms-by-id/rename-error-first-callback-parameters-v2/match-error-first-reject-resolve-pattern.js +17 -10
- package/dist/transforms-by-id/rename-error-first-callback-parameters-v2/rename-error-first-callback-parameters-v2-transform.js +7 -5
- package/dist/transforms-by-id/rename-event-parameters/event-property-names.d.ts +5 -0
- package/dist/transforms-by-id/rename-event-parameters/event-property-names.js +76 -9
- package/dist/transforms-by-id/rename-event-parameters/get-target-event-name.js +38 -3
- package/dist/transforms-by-id/rename-event-parameters/manifest.json +4 -4
- package/dist/transforms-by-id/rename-event-parameters/process-event-handler-function.js +34 -35
- package/dist/transforms-by-id/rename-execfile-arguments/detect-execfile-call.d.ts +1 -0
- package/dist/transforms-by-id/rename-execfile-arguments/detect-execfile-call.js +28 -62
- package/dist/transforms-by-id/rename-execfile-arguments/is-child-process-execfile-binding.d.ts +2 -0
- package/dist/transforms-by-id/rename-execfile-arguments/is-child-process-execfile-binding.js +50 -0
- package/dist/transforms-by-id/rename-execfile-arguments/manifest.json +3 -3
- package/dist/transforms-by-id/rename-execfile-arguments/rename-execfile-arguments-transform.js +45 -27
- package/dist/transforms-by-id/rename-file-reader-variables/get-file-reader-event-handler-name.js +5 -5
- package/dist/transforms-by-id/rename-file-reader-variables/get-file-reader-handler-function.js +6 -0
- package/dist/transforms-by-id/rename-file-reader-variables/get-file-reader-receiver-match.d.ts +10 -0
- package/dist/transforms-by-id/rename-file-reader-variables/get-file-reader-receiver-match.js +36 -0
- package/dist/transforms-by-id/rename-file-reader-variables/is-file-reader-constructor-expression.d.ts +2 -0
- package/dist/transforms-by-id/rename-file-reader-variables/is-file-reader-constructor-expression.js +36 -0
- package/dist/transforms-by-id/rename-file-reader-variables/is-known-file-reader-binding-identifier.d.ts +3 -0
- package/dist/transforms-by-id/rename-file-reader-variables/is-known-file-reader-binding-identifier.js +9 -0
- package/dist/transforms-by-id/rename-file-reader-variables/manifest.json +3 -3
- package/dist/transforms-by-id/rename-file-reader-variables/queue-file-reader-event-rename.js +28 -22
- package/dist/transforms-by-id/rename-file-reader-variables/rename-file-reader-variables-transform.js +41 -48
- package/dist/transforms-by-id/rename-file-reader-variables/track-file-reader-binding-assignment.d.ts +8 -0
- package/dist/transforms-by-id/rename-file-reader-variables/track-file-reader-binding-assignment.js +32 -0
- package/dist/transforms-by-id/rename-object-entries-parameters/is-object-entries-consumer-call.d.ts +1 -0
- package/dist/transforms-by-id/rename-object-entries-parameters/is-object-entries-consumer-call.js +12 -0
- package/dist/transforms-by-id/rename-object-entries-parameters/manifest.json +3 -3
- package/dist/transforms-by-id/rename-object-entries-parameters/rename-object-entries-parameters-transform.js +53 -26
- package/dist/transforms-by-id/rename-object-keys-variables/is-safe-keys-reassignment.d.ts +7 -2
- package/dist/transforms-by-id/rename-object-keys-variables/is-safe-keys-reassignment.js +73 -1
- package/dist/transforms-by-id/rename-object-keys-variables/manifest.json +3 -3
- package/dist/transforms-by-id/rename-object-keys-variables/rename-object-keys-variables-transform.js +59 -42
- package/dist/transforms-by-id/rename-object-property-value-variables/get-object-property-value-base-name.js +37 -12
- package/dist/transforms-by-id/rename-object-property-value-variables/manifest.json +5 -5
- package/dist/transforms-by-id/rename-object-property-value-variables/rename-object-property-value-variables-transform.js +8 -7
- package/dist/transforms-by-id/rename-sanitized-string-variables/manifest.json +5 -5
- package/dist/transforms-by-id/rename-sanitized-string-variables/rename-sanitized-string-variables-transform.js +52 -34
- package/dist/transforms-by-id/rename-timeout-ids/add-rename-candidate-for-timer-assignment.d.ts +12 -0
- package/dist/transforms-by-id/rename-timeout-ids/add-rename-candidate-for-timer-assignment.js +59 -0
- package/dist/transforms-by-id/rename-timeout-ids/is-global-timer-function-reference.d.ts +4 -0
- package/dist/transforms-by-id/rename-timeout-ids/is-global-timer-function-reference.js +64 -0
- package/dist/transforms-by-id/rename-timeout-ids/is-timer-function-reference.d.ts +3 -0
- package/dist/transforms-by-id/rename-timeout-ids/is-timer-function-reference.js +85 -0
- package/dist/transforms-by-id/rename-timeout-ids/manifest.json +4 -4
- package/dist/transforms-by-id/rename-timeout-ids/rename-timeout-ids-transform.js +15 -36
- package/dist/transforms-by-id/rename-uint8array-concat-variables/find-loop-copy-match.js +25 -1
- package/dist/transforms-by-id/rename-uint8array-concat-variables/find-uint8array-concat-match.js +13 -1
- package/dist/transforms-by-id/rename-uint8array-concat-variables/find-uint8array-output-rename-matches.d.ts +2 -0
- package/dist/transforms-by-id/rename-uint8array-concat-variables/find-uint8array-output-rename-matches.js +44 -0
- package/dist/transforms-by-id/rename-uint8array-concat-variables/manifest.json +4 -4
- package/dist/transforms-by-id/rename-uint8array-concat-variables/rename-uint8array-concat-variables-transform.js +7 -0
- package/dist/transforms-by-id/rename-url-variables/is-allowed-url-construction.d.ts +3 -0
- package/dist/transforms-by-id/rename-url-variables/is-allowed-url-construction.js +71 -0
- package/dist/transforms-by-id/rename-url-variables/manifest.json +3 -3
- package/dist/transforms-by-id/rename-url-variables/rename-url-variables-transform.js +51 -83
- package/dist/transforms-by-id/stabilize-deferred-stable-rhs/check-rhs-stability.d.ts +1 -1
- package/dist/transforms-by-id/stabilize-deferred-stable-rhs/check-rhs-stability.js +16 -43
- package/dist/transforms-by-id/stabilize-deferred-stable-rhs/manifest.json +4 -4
- package/dist/transforms-by-id/use-object-property-shorthand/manifest.json +5 -5
- package/dist/transforms-by-id/use-object-property-shorthand/use-object-property-shorthand-transform.js +3 -4
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isAllowedUrlNamespaceBindingInScope } from "./is-allowed-url-namespace-binding-in-scope.js";
|
|
2
|
+
const globalUrlNamespaceObjects = new Set(["globalThis", "window", "self"]);
|
|
2
3
|
export const getUrlConstructionKind = (scope, node, constructorName) => {
|
|
3
4
|
if (node?.type !== "NewExpression")
|
|
4
5
|
return undefined;
|
|
@@ -40,7 +41,13 @@ export const getUrlConstructionKind = (scope, node, constructorName) => {
|
|
|
40
41
|
return undefined;
|
|
41
42
|
if (callee.object.type !== "Identifier")
|
|
42
43
|
return undefined;
|
|
43
|
-
if (
|
|
44
|
+
if (isAllowedUrlNamespaceBindingInScope(scope, callee.object.name)) {
|
|
45
|
+
return "member";
|
|
46
|
+
}
|
|
47
|
+
if (!globalUrlNamespaceObjects.has(callee.object.name)) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (scope.getBinding(callee.object.name)) {
|
|
44
51
|
return undefined;
|
|
45
52
|
}
|
|
46
53
|
return "member";
|
|
@@ -38,13 +38,13 @@ export const hasUrlDestructure = (referencePath) => {
|
|
|
38
38
|
if (parent.isVariableDeclarator() &&
|
|
39
39
|
parent.node.init === referencePath.node &&
|
|
40
40
|
parent.node.id.type === "ObjectPattern") {
|
|
41
|
-
return countUrlProperties(parent.node.id) >=
|
|
41
|
+
return countUrlProperties(parent.node.id) >= 1;
|
|
42
42
|
}
|
|
43
43
|
if (parent.isAssignmentExpression() &&
|
|
44
44
|
parent.node.operator === "=" &&
|
|
45
45
|
parent.node.right === referencePath.node &&
|
|
46
46
|
parent.node.left.type === "ObjectPattern") {
|
|
47
|
-
return countUrlProperties(parent.node.left) >=
|
|
47
|
+
return countUrlProperties(parent.node.left) >= 1;
|
|
48
48
|
}
|
|
49
49
|
return false;
|
|
50
50
|
};
|
package/dist/transforms-by-id/expand-undefined-literals/expand-undefined-literals-transform.js
CHANGED
|
@@ -6,6 +6,36 @@ const require = createRequire(import.meta.url);
|
|
|
6
6
|
const traverse = require("@babel/traverse").default;
|
|
7
7
|
const VOID_OPERATOR = "void";
|
|
8
8
|
const UNDEFINED_NAME = "undefined";
|
|
9
|
+
const isWithinWithStatement = (path) => {
|
|
10
|
+
return path.findParent((parentPath) => parentPath.isWithStatement()) !== null;
|
|
11
|
+
};
|
|
12
|
+
const isSafeVoidArgument = (node) => {
|
|
13
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return (node.type === "NumericLiteral" ||
|
|
17
|
+
node.type === "StringLiteral" ||
|
|
18
|
+
node.type === "BooleanLiteral" ||
|
|
19
|
+
node.type === "NullLiteral" ||
|
|
20
|
+
node.type === "BigIntLiteral" ||
|
|
21
|
+
node.type === "RegExpLiteral" ||
|
|
22
|
+
node.type === "FunctionExpression" ||
|
|
23
|
+
node.type === "ArrowFunctionExpression" ||
|
|
24
|
+
node.type === "ClassExpression");
|
|
25
|
+
};
|
|
26
|
+
const isSafeIdentifierVoidArgument = (path) => {
|
|
27
|
+
if (isWithinWithStatement(path))
|
|
28
|
+
return false;
|
|
29
|
+
const argument = path.node.argument;
|
|
30
|
+
if (argument.type !== "Identifier")
|
|
31
|
+
return false;
|
|
32
|
+
const binding = path.scope.getBinding(argument.name);
|
|
33
|
+
if (!binding)
|
|
34
|
+
return false;
|
|
35
|
+
return (binding.kind === "param" ||
|
|
36
|
+
binding.kind === "hoisted" ||
|
|
37
|
+
binding.kind === "var");
|
|
38
|
+
};
|
|
9
39
|
const hasVoidOperator = (ast) => {
|
|
10
40
|
const nodesToVisit = [ast.program];
|
|
11
41
|
while (nodesToVisit.length > 0) {
|
|
@@ -36,13 +66,14 @@ const hasVoidOperator = (ast) => {
|
|
|
36
66
|
};
|
|
37
67
|
export const expandUndefinedLiteralsTransform = {
|
|
38
68
|
id: "expand-undefined-literals",
|
|
39
|
-
description: "Expands void
|
|
69
|
+
description: "Expands side-effect-free void expressions to undefined",
|
|
40
70
|
scope: "file",
|
|
41
71
|
parallelizable: true,
|
|
42
72
|
transform(context) {
|
|
43
73
|
let nodesVisited = 0;
|
|
44
74
|
let transformationsApplied = 0;
|
|
45
75
|
for (const fileInfo of getFilesToProcess(context)) {
|
|
76
|
+
const injectedVoidZeroSentinels = new WeakSet();
|
|
46
77
|
// This string precheck intentionally allows false positives for speed.
|
|
47
78
|
// `hasVoidOperator` on the current AST prevents false negatives.
|
|
48
79
|
if (!fileInfo.content.includes(VOID_OPERATOR) &&
|
|
@@ -55,9 +86,18 @@ export const expandUndefinedLiteralsTransform = {
|
|
|
55
86
|
const { operator, argument } = path.node;
|
|
56
87
|
if (operator !== VOID_OPERATOR)
|
|
57
88
|
return;
|
|
58
|
-
if (
|
|
89
|
+
if (injectedVoidZeroSentinels.has(path.node) &&
|
|
90
|
+
isWithinWithStatement(path))
|
|
91
|
+
return;
|
|
92
|
+
if (!path.get("argument").isPure()) {
|
|
93
|
+
const voidZeroSentinel = t.unaryExpression(VOID_OPERATOR, t.numericLiteral(0), true);
|
|
94
|
+
injectedVoidZeroSentinels.add(voidZeroSentinel);
|
|
95
|
+
path.replaceWith(t.sequenceExpression([argument, voidZeroSentinel]));
|
|
96
|
+
transformationsApplied++;
|
|
59
97
|
return;
|
|
60
|
-
|
|
98
|
+
}
|
|
99
|
+
if (!isSafeVoidArgument(argument) &&
|
|
100
|
+
!isSafeIdentifierVoidArgument(path))
|
|
61
101
|
return;
|
|
62
102
|
if (path.scope.hasBinding(UNDEFINED_NAME, true))
|
|
63
103
|
return;
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
5
|
"diffSizePercent": 100,
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
6
|
+
"evaluatedAt": "2026-02-23T06:04:26.719Z",
|
|
7
|
+
"changedLines": 12700,
|
|
8
|
+
"durationSeconds": 63.882494208000004,
|
|
9
9
|
"stableNames": 1357
|
|
10
10
|
}
|
|
11
11
|
},
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { IfStatement, Statement } from "@babel/types";
|
|
3
|
+
type InterruptingBranchCheck = (statementPath: NodePath<Statement>, boundaryIfPath: NodePath<IfStatement>) => boolean;
|
|
4
|
+
export declare function doesSwitchInterruptBoundary(switchPath: NodePath<Statement>, boundaryIfPath: NodePath<IfStatement>, isInterruptingBranch: InterruptingBranchCheck): boolean;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getGuaranteedSwitchCaseIndex } from "./get-guaranteed-switch-case-index.js";
|
|
2
|
+
import { getLastNonEmptyStatementIndex } from "./get-last-non-empty-statement-index.js";
|
|
3
|
+
import { hasNonInterruptingSwitchExitBeforeIndex } from "./has-non-interrupting-switch-exit.js";
|
|
4
|
+
export function doesSwitchInterruptBoundary(switchPath, boundaryIfPath, isInterruptingBranch) {
|
|
5
|
+
if (!switchPath.isSwitchStatement())
|
|
6
|
+
return false;
|
|
7
|
+
const casePaths = switchPath.get("cases");
|
|
8
|
+
if (casePaths.length === 0)
|
|
9
|
+
return false;
|
|
10
|
+
const caseInterrupts = getCaseInterruptions(casePaths, boundaryIfPath, isInterruptingBranch);
|
|
11
|
+
const hasDefaultCase = casePaths.some((casePath) => casePath.node.test === null);
|
|
12
|
+
if (hasDefaultCase)
|
|
13
|
+
return caseInterrupts.every(Boolean);
|
|
14
|
+
const guaranteedCaseIndex = getGuaranteedSwitchCaseIndex(switchPath);
|
|
15
|
+
if (guaranteedCaseIndex === undefined)
|
|
16
|
+
return false;
|
|
17
|
+
return caseInterrupts[guaranteedCaseIndex] === true;
|
|
18
|
+
}
|
|
19
|
+
function getCaseInterruptions(casePaths, boundaryIfPath, isInterruptingBranch) {
|
|
20
|
+
const caseInterrupts = Array.from({ length: casePaths.length }).fill(false);
|
|
21
|
+
for (let index = casePaths.length - 1; index >= 0; index -= 1) {
|
|
22
|
+
const casePath = casePaths[index];
|
|
23
|
+
if (!casePath)
|
|
24
|
+
continue;
|
|
25
|
+
const consequentPaths = casePath.get("consequent");
|
|
26
|
+
const lastStatementIndex = getLastNonEmptyStatementIndex(consequentPaths);
|
|
27
|
+
if (lastStatementIndex !== undefined &&
|
|
28
|
+
isInterruptingBranch(consequentPaths[lastStatementIndex], boundaryIfPath) &&
|
|
29
|
+
!hasNonInterruptingSwitchExitBeforeIndex(consequentPaths, lastStatementIndex, boundaryIfPath, isInterruptingBranch)) {
|
|
30
|
+
caseInterrupts[index] = true;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (caseInterrupts[index + 1] &&
|
|
34
|
+
!hasNonInterruptingSwitchExitBeforeIndex(consequentPaths, consequentPaths.length, boundaryIfPath, isInterruptingBranch)) {
|
|
35
|
+
caseInterrupts[index] = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return caseInterrupts;
|
|
39
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export function getGuaranteedSwitchCaseIndex(switchPath) {
|
|
2
|
+
const discriminantValue = getStaticExpressionValue(switchPath.get("discriminant"));
|
|
3
|
+
if (discriminantValue === undefined)
|
|
4
|
+
return undefined;
|
|
5
|
+
const casePaths = switchPath.get("cases");
|
|
6
|
+
for (const [index, casePath] of casePaths.entries()) {
|
|
7
|
+
const testPath = casePath.get("test");
|
|
8
|
+
if (!testPath.node)
|
|
9
|
+
continue;
|
|
10
|
+
const testValue = getStaticExpressionValue(testPath);
|
|
11
|
+
if (testValue !== discriminantValue)
|
|
12
|
+
continue;
|
|
13
|
+
return index;
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
function getStaticExpressionValue(expressionPath) {
|
|
18
|
+
try {
|
|
19
|
+
const evaluation = expressionPath.evaluate();
|
|
20
|
+
if (evaluation.confident) {
|
|
21
|
+
if (typeof evaluation.value === "string")
|
|
22
|
+
return evaluation.value;
|
|
23
|
+
if (typeof evaluation.value === "number")
|
|
24
|
+
return evaluation.value;
|
|
25
|
+
if (typeof evaluation.value === "boolean")
|
|
26
|
+
return evaluation.value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Some expressions cannot be statically evaluated by Babel.
|
|
31
|
+
}
|
|
32
|
+
const expression = expressionPath.node;
|
|
33
|
+
if (expression.type === "StringLiteral")
|
|
34
|
+
return expression.value;
|
|
35
|
+
if (expression.type === "NumericLiteral")
|
|
36
|
+
return expression.value;
|
|
37
|
+
if (expression.type === "BooleanLiteral")
|
|
38
|
+
return expression.value;
|
|
39
|
+
if (expression.type === "NullLiteral")
|
|
40
|
+
return undefined;
|
|
41
|
+
if (expression.type !== "UnaryExpression")
|
|
42
|
+
return undefined;
|
|
43
|
+
if (expression.operator === "void")
|
|
44
|
+
return undefined;
|
|
45
|
+
const argumentValue = getStaticExpressionValue(expressionPath.get("argument"));
|
|
46
|
+
if (argumentValue === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (expression.operator === "+" && typeof argumentValue === "number") {
|
|
49
|
+
return argumentValue;
|
|
50
|
+
}
|
|
51
|
+
if (expression.operator === "-" && typeof argumentValue === "number") {
|
|
52
|
+
return -argumentValue;
|
|
53
|
+
}
|
|
54
|
+
if (expression.operator === "!" && typeof argumentValue === "boolean") {
|
|
55
|
+
return !argumentValue;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function getLastNonEmptyStatementIndex(statements) {
|
|
2
|
+
for (let index = statements.length - 1; index >= 0; index -= 1) {
|
|
3
|
+
const statementPath = statements[index];
|
|
4
|
+
if (!statementPath?.node)
|
|
5
|
+
continue;
|
|
6
|
+
if (statementPath.isEmptyStatement())
|
|
7
|
+
continue;
|
|
8
|
+
if (isIgnorableTrailingStatement(statementPath))
|
|
9
|
+
continue;
|
|
10
|
+
return index;
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
function isIgnorableTrailingStatement(statementPath) {
|
|
15
|
+
if (statementPath.isVariableDeclaration())
|
|
16
|
+
return true;
|
|
17
|
+
if (statementPath.isClassDeclaration())
|
|
18
|
+
return true;
|
|
19
|
+
if (statementPath.isFunctionDeclaration())
|
|
20
|
+
return true;
|
|
21
|
+
if (statementPath.isTSDeclareFunction())
|
|
22
|
+
return true;
|
|
23
|
+
if (statementPath.isTSTypeAliasDeclaration())
|
|
24
|
+
return true;
|
|
25
|
+
if (statementPath.isTSInterfaceDeclaration())
|
|
26
|
+
return true;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { IfStatement, Statement } from "@babel/types";
|
|
3
|
+
type InterruptingBranchCheck = (statementPath: NodePath<Statement>, boundaryIfPath: NodePath<IfStatement>) => boolean;
|
|
4
|
+
export declare function hasNonInterruptingSwitchExitBeforeIndex(statements: NodePath<Statement>[], stopIndex: number, boundaryIfPath: NodePath<IfStatement>, isInterruptingBranch: InterruptingBranchCheck): boolean;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function hasNonInterruptingSwitchExitBeforeIndex(statements, stopIndex, boundaryIfPath, isInterruptingBranch) {
|
|
2
|
+
for (let index = 0; index < stopIndex; index += 1) {
|
|
3
|
+
const statementPath = statements[index];
|
|
4
|
+
if (!statementPath?.node)
|
|
5
|
+
continue;
|
|
6
|
+
if (statementPath.isEmptyStatement())
|
|
7
|
+
continue;
|
|
8
|
+
if (hasPotentialNonInterruptingSwitchExit(statementPath, boundaryIfPath, isInterruptingBranch)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (isInterruptingBranch(statementPath, boundaryIfPath))
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
function hasPotentialNonInterruptingSwitchExit(statementPath, boundaryIfPath, isInterruptingBranch) {
|
|
17
|
+
if (statementPath.isBreakStatement() || statementPath.isContinueStatement()) {
|
|
18
|
+
return !isInterruptingBranch(statementPath, boundaryIfPath);
|
|
19
|
+
}
|
|
20
|
+
if (statementPath.isIfStatement()) {
|
|
21
|
+
const consequentPath = statementPath.get("consequent");
|
|
22
|
+
if (hasPotentialNonInterruptingSwitchExit(consequentPath, boundaryIfPath, isInterruptingBranch)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const alternatePath = statementPath.get("alternate");
|
|
26
|
+
if (!alternatePath.node)
|
|
27
|
+
return false;
|
|
28
|
+
return hasPotentialNonInterruptingSwitchExit(alternatePath, boundaryIfPath, isInterruptingBranch);
|
|
29
|
+
}
|
|
30
|
+
if (statementPath.isLabeledStatement()) {
|
|
31
|
+
return hasPotentialNonInterruptingSwitchExit(statementPath.get("body"), boundaryIfPath, isInterruptingBranch);
|
|
32
|
+
}
|
|
33
|
+
if (statementPath.isBlockStatement()) {
|
|
34
|
+
const bodyPaths = statementPath.get("body");
|
|
35
|
+
for (const bodyPath of bodyPaths) {
|
|
36
|
+
if (hasPotentialNonInterruptingSwitchExit(bodyPath, boundaryIfPath, isInterruptingBranch)) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
if (isInterruptingBranch(bodyPath, boundaryIfPath))
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { doesJumpInterruptBoundary } from "./does-jump-interrupt-boundary.js";
|
|
2
|
+
import { doesSwitchInterruptBoundary } from "./does-switch-interrupt-boundary.js";
|
|
3
|
+
export function isInterruptingBranch(statementPath, boundaryIfPath) {
|
|
4
|
+
if (isInterruptingStatement(statementPath, boundaryIfPath))
|
|
5
|
+
return true;
|
|
6
|
+
if (statementPath.isIfStatement()) {
|
|
7
|
+
const alternatePath = statementPath.get("alternate");
|
|
8
|
+
if (!alternatePath.node)
|
|
9
|
+
return false;
|
|
10
|
+
return (isInterruptingBranch(statementPath.get("consequent"), boundaryIfPath) &&
|
|
11
|
+
isInterruptingBranch(alternatePath, boundaryIfPath));
|
|
12
|
+
}
|
|
13
|
+
if (statementPath.isTryStatement()) {
|
|
14
|
+
const blockPath = statementPath.get("block");
|
|
15
|
+
const finalizerPath = statementPath.get("finalizer");
|
|
16
|
+
if (finalizerPath.node &&
|
|
17
|
+
isInterruptingBranch(finalizerPath, boundaryIfPath)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (!isInterruptingBranch(blockPath, boundaryIfPath)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const handlerPath = statementPath.get("handler");
|
|
24
|
+
if (!handlerPath.node)
|
|
25
|
+
return true;
|
|
26
|
+
return isInterruptingBranch(handlerPath.get("body"), boundaryIfPath);
|
|
27
|
+
}
|
|
28
|
+
if (statementPath.isSwitchStatement()) {
|
|
29
|
+
return doesSwitchInterruptBoundary(statementPath, boundaryIfPath, isInterruptingBranch);
|
|
30
|
+
}
|
|
31
|
+
if (statementPath.isLabeledStatement()) {
|
|
32
|
+
return isInterruptingBranch(statementPath.get("body"), boundaryIfPath);
|
|
33
|
+
}
|
|
34
|
+
if (!statementPath.isBlockStatement())
|
|
35
|
+
return false;
|
|
36
|
+
const firstPath = getFirstNonEmptyStatementPath(statementPath.get("body"));
|
|
37
|
+
if (firstPath && isInterruptingBranch(firstPath, boundaryIfPath)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const linearInterruptingPath = getInterruptingPathAfterLinearPrefix(statementPath.get("body"), boundaryIfPath);
|
|
41
|
+
if (linearInterruptingPath)
|
|
42
|
+
return true;
|
|
43
|
+
const lastPath = getLastNonEmptyStatementPath(statementPath.get("body"));
|
|
44
|
+
if (!lastPath)
|
|
45
|
+
return false;
|
|
46
|
+
return isInterruptingBranch(lastPath, boundaryIfPath);
|
|
47
|
+
}
|
|
48
|
+
function isInterruptingStatement(statementPath, boundaryIfPath) {
|
|
49
|
+
if (statementPath.isReturnStatement())
|
|
50
|
+
return true;
|
|
51
|
+
if (statementPath.isThrowStatement())
|
|
52
|
+
return true;
|
|
53
|
+
if (statementPath.isBreakStatement() || statementPath.isContinueStatement()) {
|
|
54
|
+
return doesJumpInterruptBoundary(statementPath, boundaryIfPath);
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
function getLastNonEmptyStatementPath(statements) {
|
|
59
|
+
for (let index = statements.length - 1; index >= 0; index -= 1) {
|
|
60
|
+
const statementPath = statements[index];
|
|
61
|
+
if (!statementPath?.node)
|
|
62
|
+
continue;
|
|
63
|
+
if (statementPath.isEmptyStatement())
|
|
64
|
+
continue;
|
|
65
|
+
if (isIgnorableTrailingStatement(statementPath))
|
|
66
|
+
continue;
|
|
67
|
+
return statementPath;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
function getFirstNonEmptyStatementPath(statements) {
|
|
72
|
+
for (const statementPath of statements) {
|
|
73
|
+
if (statementPath.isEmptyStatement())
|
|
74
|
+
continue;
|
|
75
|
+
return statementPath;
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
function getInterruptingPathAfterLinearPrefix(statements, boundaryIfPath) {
|
|
80
|
+
for (const statementPath of statements) {
|
|
81
|
+
if (statementPath.isEmptyStatement())
|
|
82
|
+
continue;
|
|
83
|
+
if (isInterruptingBranch(statementPath, boundaryIfPath))
|
|
84
|
+
return statementPath;
|
|
85
|
+
if (isStatementGuaranteedToContinue(statementPath))
|
|
86
|
+
continue;
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
function isStatementGuaranteedToContinue(statementPath) {
|
|
92
|
+
if (statementPath.isExpressionStatement())
|
|
93
|
+
return true;
|
|
94
|
+
if (statementPath.isDebuggerStatement())
|
|
95
|
+
return true;
|
|
96
|
+
if (statementPath.isVariableDeclaration())
|
|
97
|
+
return true;
|
|
98
|
+
if (statementPath.isClassDeclaration())
|
|
99
|
+
return true;
|
|
100
|
+
if (statementPath.isFunctionDeclaration())
|
|
101
|
+
return true;
|
|
102
|
+
if (statementPath.isTSDeclareFunction())
|
|
103
|
+
return true;
|
|
104
|
+
if (statementPath.isTSTypeAliasDeclaration())
|
|
105
|
+
return true;
|
|
106
|
+
if (statementPath.isTSInterfaceDeclaration())
|
|
107
|
+
return true;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
function isIgnorableTrailingStatement(statementPath) {
|
|
111
|
+
if (statementPath.isVariableDeclaration())
|
|
112
|
+
return true;
|
|
113
|
+
if (statementPath.isClassDeclaration())
|
|
114
|
+
return true;
|
|
115
|
+
if (statementPath.isFunctionDeclaration())
|
|
116
|
+
return true;
|
|
117
|
+
if (statementPath.isTSDeclareFunction())
|
|
118
|
+
return true;
|
|
119
|
+
if (statementPath.isTSTypeAliasDeclaration())
|
|
120
|
+
return true;
|
|
121
|
+
if (statementPath.isTSInterfaceDeclaration())
|
|
122
|
+
return true;
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
5
|
"diffSizePercent": 100,
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
6
|
+
"evaluatedAt": "2026-02-23T06:47:04.680Z",
|
|
7
|
+
"changedLines": 6872,
|
|
8
|
+
"durationSeconds": 40.238378,
|
|
9
9
|
"stableNames": 1357
|
|
10
10
|
}
|
|
11
11
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { getBindingIdentifiers } from "@babel/types";
|
|
3
3
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isInterruptingBranch } from "./is-interrupting-branch.js";
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
7
|
const traverse = require("@babel/traverse").default;
|
|
@@ -21,7 +21,7 @@ export const removeRedundantElseTransform = {
|
|
|
21
21
|
if (!alternate)
|
|
22
22
|
return;
|
|
23
23
|
const interrupts = isInterruptingBranch(path.get("consequent"), path);
|
|
24
|
-
if (!interrupts)
|
|
24
|
+
if (!interrupts && !isRedundantElseIfChain(path.node))
|
|
25
25
|
return;
|
|
26
26
|
// Remove alternate
|
|
27
27
|
// eslint-disable-next-line unicorn/no-null
|
|
@@ -48,53 +48,65 @@ export const removeRedundantElseTransform = {
|
|
|
48
48
|
});
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
function isRedundantElseIfChain(ifNode) {
|
|
52
|
+
const outerTest = getStrictIdentifierLiteralEquality(ifNode.test);
|
|
53
|
+
if (!outerTest)
|
|
54
|
+
return false;
|
|
55
|
+
const outerLiteralValue = outerTest.literalValue;
|
|
56
|
+
let alternateNode = ifNode.alternate;
|
|
57
|
+
if (!alternateNode)
|
|
58
|
+
return false;
|
|
59
|
+
for (;;) {
|
|
60
|
+
if (alternateNode.type !== "IfStatement")
|
|
57
61
|
return false;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
if (statementPath.isTryStatement()) {
|
|
62
|
-
const blockPath = statementPath.get("block");
|
|
63
|
-
if (!isInterruptingBranch(blockPath, boundaryIfPath)) {
|
|
62
|
+
const alternateTest = getStrictIdentifierLiteralEquality(alternateNode.test);
|
|
63
|
+
if (!alternateTest)
|
|
64
64
|
return false;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
65
|
+
if (alternateTest.identifierName !== outerTest.identifierName)
|
|
66
|
+
return false;
|
|
67
|
+
if (Object.is(alternateTest.literalValue, outerLiteralValue))
|
|
68
|
+
return false;
|
|
69
|
+
if (!alternateNode.alternate)
|
|
68
70
|
return true;
|
|
69
|
-
|
|
71
|
+
alternateNode = alternateNode.alternate;
|
|
70
72
|
}
|
|
71
|
-
if (!statementPath.isBlockStatement())
|
|
72
|
-
return false;
|
|
73
|
-
const lastPath = getLastNonEmptyStatementPath(statementPath.get("body"));
|
|
74
|
-
if (!lastPath)
|
|
75
|
-
return false;
|
|
76
|
-
return isInterruptingBranch(lastPath, boundaryIfPath);
|
|
77
73
|
}
|
|
78
|
-
function
|
|
79
|
-
if (
|
|
74
|
+
function getStrictIdentifierLiteralEquality(testExpression) {
|
|
75
|
+
if (testExpression.type !== "BinaryExpression")
|
|
76
|
+
return undefined;
|
|
77
|
+
if (testExpression.operator !== "===")
|
|
78
|
+
return undefined;
|
|
79
|
+
const left = testExpression.left;
|
|
80
|
+
const right = testExpression.right;
|
|
81
|
+
if (left.type === "Identifier" && isLiteralExpression(right)) {
|
|
82
|
+
return {
|
|
83
|
+
identifierName: left.name,
|
|
84
|
+
literalValue: getLiteralValue(right),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (right.type === "Identifier" && isLiteralExpression(left)) {
|
|
88
|
+
return {
|
|
89
|
+
identifierName: right.name,
|
|
90
|
+
literalValue: getLiteralValue(left),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
function isLiteralExpression(expression) {
|
|
96
|
+
if (expression.type === "StringLiteral")
|
|
80
97
|
return true;
|
|
81
|
-
if (
|
|
98
|
+
if (expression.type === "NumericLiteral")
|
|
99
|
+
return true;
|
|
100
|
+
if (expression.type === "BooleanLiteral")
|
|
101
|
+
return true;
|
|
102
|
+
if (expression.type === "NullLiteral")
|
|
82
103
|
return true;
|
|
83
|
-
if (statementPath.isBreakStatement() || statementPath.isContinueStatement()) {
|
|
84
|
-
return doesJumpInterruptBoundary(statementPath, boundaryIfPath);
|
|
85
|
-
}
|
|
86
104
|
return false;
|
|
87
105
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
continue;
|
|
93
|
-
if (statementPath.isEmptyStatement())
|
|
94
|
-
continue;
|
|
95
|
-
return statementPath;
|
|
96
|
-
}
|
|
97
|
-
return undefined;
|
|
106
|
+
function getLiteralValue(literal) {
|
|
107
|
+
if (literal.type === "NullLiteral")
|
|
108
|
+
return undefined;
|
|
109
|
+
return literal.value;
|
|
98
110
|
}
|
|
99
111
|
function shouldPreserveAlternateBlockScope(ifPath, alternate) {
|
|
100
112
|
const lexicalNames = getTopLevelLexicalNames(alternate);
|
package/dist/transforms-by-id/rename-deferred-resolve-parameters-v2/deferred-executor-heuristics.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { isAssignedToOnHandlerProperty, isCatchRejectionHandlerArgument, isDirectCallOfBinding, isErrorEventHandlerArgument, isErrorEventHandlerRemovalArgument, isThenFulfillmentHandlerArgument, isThenRejectionHandlerArgument, } from "../rename-promise-executor-parameters-v2/promise-executor-heuristics.js";
|
|
2
|
-
import { isValidBindingIdentifier } from "./is-valid-binding-identifier.js";
|
|
3
|
-
const isExecutorParameterEligible = (parameter) => {
|
|
4
|
-
if (!isValidBindingIdentifier(parameter.name))
|
|
5
|
-
return false;
|
|
6
|
-
return true;
|
|
7
|
-
};
|
|
8
2
|
export const getExecutorFunctionIfEligible = (path) => {
|
|
9
3
|
// Intentionally does not require `new Promise(...)`: minified bundles often alias
|
|
10
4
|
// Promise constructors, and matching `new X((a, b) => ...)` keeps this transform aligned
|
|
11
5
|
// with v1/v2 promise-executor heuristics elsewhere in the codebase.
|
|
12
|
-
if (path.node.arguments.length
|
|
6
|
+
if (path.node.arguments.length === 0)
|
|
13
7
|
return;
|
|
14
8
|
const executor = path.get("arguments.0");
|
|
15
9
|
if (!executor.isFunctionExpression() &&
|
|
@@ -26,10 +20,6 @@ export const getExecutorFunctionIfEligible = (path) => {
|
|
|
26
20
|
return;
|
|
27
21
|
if (secondParameter.type !== "Identifier")
|
|
28
22
|
return;
|
|
29
|
-
if (!isExecutorParameterEligible(firstParameter))
|
|
30
|
-
return;
|
|
31
|
-
if (!isExecutorParameterEligible(secondParameter))
|
|
32
|
-
return;
|
|
33
23
|
return executor;
|
|
34
24
|
};
|
|
35
25
|
const isArrayElementReference = (referencePath) => {
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
5
|
"diffSizePercent": 99.99246065403827,
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
6
|
+
"evaluatedAt": "2026-02-22T17:56:04.941Z",
|
|
7
|
+
"changedLines": 1740,
|
|
8
|
+
"durationSeconds": 238.50724275000002,
|
|
9
9
|
"stableNames": 1359
|
|
10
10
|
}
|
|
11
11
|
},
|