miniread 1.5.0 → 1.7.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/core/normalize-code.d.ts +17 -0
- package/dist/core/normalize-code.js +35 -0
- package/dist/core/stable-naming.d.ts +61 -0
- package/dist/core/stable-naming.js +121 -0
- package/dist/scripts/evaluate/check-expected-evaluations.js +2 -0
- package/dist/scripts/evaluate/check-recommended-snapshot.d.ts +11 -0
- package/dist/scripts/evaluate/check-recommended-snapshot.js +53 -0
- package/dist/scripts/evaluate/check-snapshots.d.ts +1 -0
- package/dist/scripts/evaluate/check-snapshots.js +21 -2
- package/dist/scripts/evaluate/transform-content.d.ts +5 -0
- package/dist/scripts/evaluate/transform-content.js +23 -13
- package/dist/transforms/rename-catch-parameters/rename-catch-parameters-transform.js +15 -38
- package/dist/transforms/rename-destructured-aliases/rename-destructured-aliases-transform.js +13 -12
- package/dist/transforms/rename-event-parameters/process-event-handler-function.d.ts +2 -3
- package/dist/transforms/rename-event-parameters/process-event-handler-function.js +13 -9
- package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.d.ts +1 -1
- package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.js +10 -7
- package/dist/transforms/rename-loop-index-variables/rename-loop-index-variables-transform.js +19 -13
- package/dist/transforms/rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js +12 -5
- package/dist/transforms/rename-timeout-ids/rename-timeout-ids-transform.d.ts +1 -1
- package/dist/transforms/rename-timeout-ids/rename-timeout-ids-transform.js +10 -11
- package/dist/transforms/rename-use-reference-guards/rename-use-reference-guards-transform.js +10 -11
- package/dist/transforms/rename-use-reference-guards-v2/get-member-expression-for-reference.d.ts +3 -0
- package/dist/transforms/rename-use-reference-guards-v2/get-member-expression-for-reference.js +10 -0
- package/dist/transforms/rename-use-reference-guards-v2/get-reference-usage.d.ts +8 -0
- package/dist/transforms/rename-use-reference-guards-v2/get-reference-usage.js +58 -0
- package/dist/transforms/rename-use-reference-guards-v2/is-use-reference-false-initializer.d.ts +2 -0
- package/dist/transforms/rename-use-reference-guards-v2/is-use-reference-false-initializer.js +40 -0
- package/dist/transforms/rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.d.ts +3 -0
- package/dist/transforms/rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js +54 -0
- package/dist/transforms/transform-registry.js +2 -10
- package/package.json +1 -1
- package/transform-manifest.json +15 -55
- package/dist/transforms/expand-return-sequence/expand-return-sequence-transform.d.ts +0 -2
- package/dist/transforms/expand-return-sequence/expand-return-sequence-transform.js +0 -91
- package/dist/transforms/expand-sequence-expressions/expand-expression-statement-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions/expand-expression-statement-sequence.js +0 -57
- package/dist/transforms/expand-sequence-expressions/expand-sequence-expressions-transform.d.ts +0 -2
- package/dist/transforms/expand-sequence-expressions/expand-sequence-expressions-transform.js +0 -34
- package/dist/transforms/expand-sequence-expressions/expand-variable-declaration-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions/expand-variable-declaration-sequence.js +0 -93
- package/dist/transforms/expand-sequence-expressions-v2/expand-expression-statement-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v2/expand-expression-statement-sequence.js +0 -55
- package/dist/transforms/expand-sequence-expressions-v2/expand-return-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v2/expand-return-sequence.js +0 -86
- package/dist/transforms/expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.d.ts +0 -2
- package/dist/transforms/expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.js +0 -41
- package/dist/transforms/expand-sequence-expressions-v2/expand-variable-declaration-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v2/expand-variable-declaration-sequence.js +0 -93
- package/dist/transforms/expand-sequence-expressions-v3/expand-expression-statement-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v3/expand-expression-statement-sequence.js +0 -64
- package/dist/transforms/expand-sequence-expressions-v3/expand-return-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v3/expand-return-sequence.js +0 -91
- package/dist/transforms/expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.d.ts +0 -2
- package/dist/transforms/expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.js +0 -48
- package/dist/transforms/expand-sequence-expressions-v3/expand-throw-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v3/expand-throw-sequence.js +0 -101
- package/dist/transforms/expand-sequence-expressions-v3/expand-variable-declaration-sequence.d.ts +0 -3
- package/dist/transforms/expand-sequence-expressions-v3/expand-variable-declaration-sequence.js +0 -99
- package/dist/transforms/expand-throw-sequence/expand-throw-sequence-transform.d.ts +0 -2
- package/dist/transforms/expand-throw-sequence/expand-throw-sequence-transform.js +0 -117
- package/dist/transforms/rename-binding/get-target-name.d.ts +0 -4
- package/dist/transforms/rename-binding/get-target-name.js +0 -25
- package/dist/transforms/rename-binding/is-valid-binding-identifier.d.ts +0 -1
- package/dist/transforms/rename-binding/is-valid-binding-identifier.js +0 -10
- package/dist/transforms/rename-use-reference-guards/get-target-name.d.ts +0 -2
- package/dist/transforms/rename-use-reference-guards/get-target-name.js +0 -23
- package/dist/transforms/rename-use-reference-guards/is-valid-binding-identifier.d.ts +0 -1
- package/dist/transforms/rename-use-reference-guards/is-valid-binding-identifier.js +0 -10
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { RenameGroup } from "../../core/stable-naming.js";
|
|
3
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
2
4
|
import { processEventHandlerFunction } from "./process-event-handler-function.js";
|
|
3
5
|
const require = createRequire(import.meta.url);
|
|
4
6
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
@@ -9,28 +11,29 @@ export const renameEventParametersTransform = {
|
|
|
9
11
|
scope: "file",
|
|
10
12
|
parallelizable: true,
|
|
11
13
|
transform(context) {
|
|
12
|
-
const { projectGraph } = context;
|
|
13
14
|
let nodesVisited = 0;
|
|
14
|
-
|
|
15
|
-
for (const
|
|
15
|
+
let transformationsApplied = 0;
|
|
16
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
17
|
+
const group = new RenameGroup();
|
|
16
18
|
traverse(fileInfo.ast, {
|
|
17
19
|
FunctionDeclaration(path) {
|
|
18
20
|
nodesVisited++;
|
|
19
|
-
processEventHandlerFunction(path,
|
|
21
|
+
processEventHandlerFunction(path, group);
|
|
20
22
|
},
|
|
21
23
|
FunctionExpression(path) {
|
|
22
24
|
nodesVisited++;
|
|
23
|
-
processEventHandlerFunction(path,
|
|
25
|
+
processEventHandlerFunction(path, group);
|
|
24
26
|
},
|
|
25
27
|
ArrowFunctionExpression(path) {
|
|
26
28
|
nodesVisited++;
|
|
27
|
-
processEventHandlerFunction(path,
|
|
29
|
+
processEventHandlerFunction(path, group);
|
|
28
30
|
},
|
|
29
31
|
});
|
|
32
|
+
transformationsApplied += group.apply();
|
|
30
33
|
}
|
|
31
34
|
return Promise.resolve({
|
|
32
35
|
nodesVisited,
|
|
33
|
-
transformationsApplied
|
|
36
|
+
transformationsApplied,
|
|
34
37
|
});
|
|
35
38
|
},
|
|
36
39
|
};
|
package/dist/transforms/rename-loop-index-variables/rename-loop-index-variables-transform.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
2
3
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
3
4
|
const require = createRequire(import.meta.url);
|
|
4
5
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
@@ -15,10 +16,11 @@ const getRenamedAncestorLoopCount = (path, renamedLoops) => {
|
|
|
15
16
|
}
|
|
16
17
|
return count;
|
|
17
18
|
};
|
|
18
|
-
const
|
|
19
|
+
const BASE_NAME = "index";
|
|
20
|
+
const getTargetIndexBaseName = (renamedAncestorLoopCount) => {
|
|
19
21
|
if (renamedAncestorLoopCount === 0)
|
|
20
|
-
return
|
|
21
|
-
return
|
|
22
|
+
return BASE_NAME;
|
|
23
|
+
return `${BASE_NAME}${renamedAncestorLoopCount + 1}`;
|
|
22
24
|
};
|
|
23
25
|
const getLoopCounterNameIfEligible = (path) => {
|
|
24
26
|
const init = path.node.init;
|
|
@@ -91,31 +93,35 @@ const getLoopCounterNameIfEligible = (path) => {
|
|
|
91
93
|
};
|
|
92
94
|
export const renameLoopIndexVariablesTransform = {
|
|
93
95
|
id: "rename-loop-index-variables",
|
|
94
|
-
description: "Renames numeric for-loop counters to index
|
|
96
|
+
description: "Renames numeric for-loop counters to $index/$index2/... based on nesting depth",
|
|
95
97
|
scope: "file",
|
|
96
98
|
parallelizable: true,
|
|
97
99
|
transform(context) {
|
|
98
100
|
let nodesVisited = 0;
|
|
99
101
|
let transformationsApplied = 0;
|
|
100
102
|
for (const fileInfo of getFilesToProcess(context)) {
|
|
101
|
-
const
|
|
103
|
+
const group = new RenameGroup();
|
|
104
|
+
const eligibleLoops = new WeakMap();
|
|
102
105
|
traverse(fileInfo.ast, {
|
|
103
106
|
ForStatement(path) {
|
|
104
107
|
nodesVisited++;
|
|
105
108
|
const loopCounterName = getLoopCounterNameIfEligible(path);
|
|
106
109
|
if (!loopCounterName)
|
|
107
110
|
return;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (loopCounterName === targetName)
|
|
111
|
+
// Skip already-stable names
|
|
112
|
+
if (isStableRenamed(loopCounterName))
|
|
111
113
|
return;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
path.
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
const renamedAncestorLoopCount = getRenamedAncestorLoopCount(path, eligibleLoops);
|
|
115
|
+
const baseName = getTargetIndexBaseName(renamedAncestorLoopCount);
|
|
116
|
+
eligibleLoops.set(path.node, baseName);
|
|
117
|
+
group.add({
|
|
118
|
+
scope: path.scope,
|
|
119
|
+
currentName: loopCounterName,
|
|
120
|
+
baseName,
|
|
121
|
+
});
|
|
117
122
|
},
|
|
118
123
|
});
|
|
124
|
+
transformationsApplied += group.apply();
|
|
119
125
|
}
|
|
120
126
|
return Promise.resolve({
|
|
121
127
|
nodesVisited,
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { isStableRenamed } from "../../core/stable-naming.js";
|
|
2
3
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
3
4
|
import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, wouldShadowReferencedOuterBinding, } from "./promise-executor-heuristics.js";
|
|
4
5
|
import { canRenameBindingSafely, renameBindingIfSafe, } from "./rename-binding-if-safe.js";
|
|
6
|
+
const STABLE_PREFIX = "$";
|
|
5
7
|
const require = createRequire(import.meta.url);
|
|
6
8
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
7
9
|
const traverse = require("@babel/traverse").default;
|
|
8
10
|
export const renamePromiseExecutorParametersTransform = {
|
|
9
11
|
id: "rename-promise-executor-parameters",
|
|
10
|
-
description: "Renames promise-like executor parameters in `new X(executor)` to resolve
|
|
12
|
+
description: "Renames promise-like executor parameters in `new X(executor)` to $resolve/$reject when usage is high-confidence",
|
|
11
13
|
scope: "file",
|
|
12
14
|
parallelizable: true,
|
|
13
15
|
transform(context) {
|
|
@@ -22,6 +24,11 @@ export const renamePromiseExecutorParametersTransform = {
|
|
|
22
24
|
return;
|
|
23
25
|
const [resolveParameter, rejectParameter] = executorPath.node
|
|
24
26
|
.params;
|
|
27
|
+
// Skip already-stable names
|
|
28
|
+
if (isStableRenamed(resolveParameter.name))
|
|
29
|
+
return;
|
|
30
|
+
if (isStableRenamed(rejectParameter.name))
|
|
31
|
+
return;
|
|
25
32
|
const bindingScope = executorPath.scope;
|
|
26
33
|
const resolveBinding = bindingScope.getBinding(resolveParameter.name);
|
|
27
34
|
const rejectBinding = bindingScope.getBinding(rejectParameter.name);
|
|
@@ -41,10 +48,10 @@ export const renamePromiseExecutorParametersTransform = {
|
|
|
41
48
|
isAssignedToOnHandlerProperty(referencePath));
|
|
42
49
|
if (!rejectIsOnlyCalledOrHandlerAssigned)
|
|
43
50
|
return;
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
51
|
+
const targetResolveName = `${STABLE_PREFIX}resolve`;
|
|
52
|
+
const targetRejectName = `${STABLE_PREFIX}reject`;
|
|
53
|
+
const resolveWouldShadow = wouldShadowReferencedOuterBinding(executorPath, targetResolveName);
|
|
54
|
+
const rejectWouldShadow = wouldShadowReferencedOuterBinding(executorPath, targetRejectName);
|
|
48
55
|
const wantsResolveRename = resolveParameter.name !== targetResolveName;
|
|
49
56
|
const wantsRejectRename = rejectParameter.name !== targetRejectName;
|
|
50
57
|
const canRenameResolve = !wantsResolveRename ||
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Transform } from "../../core/types.js";
|
|
2
2
|
export declare const renameTimeoutIdsTransform: Transform;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
3
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
4
|
const require = createRequire(import.meta.url);
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
6
6
|
const traverse = require("@babel/traverse").default;
|
|
@@ -40,20 +40,22 @@ const isClearTimeoutCallArgument = (referencePath, bindingName) => {
|
|
|
40
40
|
};
|
|
41
41
|
export const renameTimeoutIdsTransform = {
|
|
42
42
|
id: "rename-timeout-ids",
|
|
43
|
-
description: "Renames setTimeout handle variables to timeoutId/timeoutId2/... when usage is only clearTimeout(...)",
|
|
43
|
+
description: "Renames setTimeout handle variables to $timeoutId/$timeoutId2/... or timeoutId/timeoutId2/... when usage is only clearTimeout(...)",
|
|
44
44
|
scope: "file",
|
|
45
45
|
parallelizable: true,
|
|
46
46
|
transform(context) {
|
|
47
47
|
let nodesVisited = 0;
|
|
48
48
|
let transformationsApplied = 0;
|
|
49
49
|
for (const fileInfo of getFilesToProcess(context)) {
|
|
50
|
+
const group = new RenameGroup();
|
|
50
51
|
traverse(fileInfo.ast, {
|
|
51
52
|
VariableDeclarator(path) {
|
|
52
53
|
nodesVisited++;
|
|
53
54
|
const id = path.node.id;
|
|
54
55
|
if (id.type !== "Identifier")
|
|
55
56
|
return;
|
|
56
|
-
|
|
57
|
+
// Skip already-stable names
|
|
58
|
+
if (isStableRenamed(id.name))
|
|
57
59
|
return;
|
|
58
60
|
const init = path.node.init;
|
|
59
61
|
if (init?.type !== "CallExpression")
|
|
@@ -69,17 +71,14 @@ export const renameTimeoutIdsTransform = {
|
|
|
69
71
|
return;
|
|
70
72
|
if (!binding.referencePaths.every((referencePath) => isClearTimeoutCallArgument(referencePath, id.name)))
|
|
71
73
|
return;
|
|
72
|
-
|
|
74
|
+
group.add({
|
|
75
|
+
scope: path.scope,
|
|
76
|
+
currentName: id.name,
|
|
73
77
|
baseName: BASE_NAME,
|
|
74
78
|
});
|
|
75
|
-
if (!targetName)
|
|
76
|
-
return;
|
|
77
|
-
if (id.name === targetName)
|
|
78
|
-
return;
|
|
79
|
-
path.scope.rename(id.name, targetName);
|
|
80
|
-
transformationsApplied++;
|
|
81
79
|
},
|
|
82
80
|
});
|
|
81
|
+
transformationsApplied += group.apply();
|
|
83
82
|
}
|
|
84
83
|
return Promise.resolve({ nodesVisited, transformationsApplied });
|
|
85
84
|
},
|
package/dist/transforms/rename-use-reference-guards/rename-use-reference-guards-transform.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { RenameGroup } from "../../core/stable-naming.js";
|
|
2
3
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
3
4
|
import { getReferenceUsage } from "./get-reference-usage.js";
|
|
4
|
-
import { getTargetName } from "./get-target-name.js";
|
|
5
5
|
import { isUseReferenceFalseInitializer } from "./is-use-reference-false-initializer.js";
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
8
8
|
const traverse = require("@babel/traverse").default;
|
|
9
|
+
const BASE_NAME = "hasRunRef";
|
|
9
10
|
const renameUseReferenceGuardsTransform = {
|
|
10
11
|
id: "rename-use-reference-guards",
|
|
11
|
-
description: "Renames boolean useRef(false) guard variables to hasRunRef/hasRunRef2/...",
|
|
12
|
+
description: "Renames boolean useRef(false) guard variables to $hasRunRef/$hasRunRef2/... or hasRunRef/hasRunRef2/...",
|
|
12
13
|
scope: "file",
|
|
13
14
|
parallelizable: true,
|
|
14
15
|
transform(context) {
|
|
15
16
|
let nodesVisited = 0;
|
|
16
17
|
let transformationsApplied = 0;
|
|
17
18
|
for (const fileInfo of getFilesToProcess(context)) {
|
|
19
|
+
const group = new RenameGroup();
|
|
18
20
|
traverse(fileInfo.ast, {
|
|
19
21
|
VariableDeclarator(path) {
|
|
20
22
|
nodesVisited++;
|
|
21
23
|
const id = path.node.id;
|
|
22
24
|
if (id.type !== "Identifier")
|
|
23
25
|
return;
|
|
24
|
-
if (id.name.length > 2)
|
|
25
|
-
return;
|
|
26
26
|
if (!isUseReferenceFalseInitializer(path.node))
|
|
27
27
|
return;
|
|
28
28
|
const binding = path.scope.getBinding(id.name);
|
|
@@ -36,15 +36,14 @@ const renameUseReferenceGuardsTransform = {
|
|
|
36
36
|
!usage.hasTrueWrite ||
|
|
37
37
|
usage.hasFalseWrite)
|
|
38
38
|
return;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
path.scope.rename(id.name, targetName);
|
|
45
|
-
transformationsApplied++;
|
|
39
|
+
group.add({
|
|
40
|
+
scope: path.scope,
|
|
41
|
+
currentName: id.name,
|
|
42
|
+
baseName: BASE_NAME,
|
|
43
|
+
});
|
|
46
44
|
},
|
|
47
45
|
});
|
|
46
|
+
transformationsApplied += group.apply();
|
|
48
47
|
}
|
|
49
48
|
return Promise.resolve({
|
|
50
49
|
nodesVisited,
|
package/dist/transforms/rename-use-reference-guards-v2/get-member-expression-for-reference.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NodePath } from "@babel/traverse";
|
|
2
|
+
import type { Identifier, MemberExpression, OptionalMemberExpression } from "@babel/types";
|
|
3
|
+
export declare const getMemberExpressionForReference: (referencePath: NodePath<Identifier>) => NodePath<MemberExpression | OptionalMemberExpression> | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const getMemberExpressionForReference = (referencePath) => {
|
|
2
|
+
const parentPath = referencePath.parentPath;
|
|
3
|
+
if (parentPath.isMemberExpression() &&
|
|
4
|
+
parentPath.node.object === referencePath.node)
|
|
5
|
+
return parentPath;
|
|
6
|
+
if (parentPath.isOptionalMemberExpression() &&
|
|
7
|
+
parentPath.node.object === referencePath.node)
|
|
8
|
+
return parentPath;
|
|
9
|
+
return;
|
|
10
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getMemberExpressionForReference } from "./get-member-expression-for-reference.js";
|
|
2
|
+
const getKnownBooleanValue = (expression) => {
|
|
3
|
+
if (expression.type === "BooleanLiteral")
|
|
4
|
+
return expression.value;
|
|
5
|
+
if (expression.type === "UnaryExpression" &&
|
|
6
|
+
expression.operator === "!" &&
|
|
7
|
+
expression.argument.type === "NumericLiteral" &&
|
|
8
|
+
(expression.argument.value === 0 || expression.argument.value === 1)) {
|
|
9
|
+
return !expression.argument.value;
|
|
10
|
+
}
|
|
11
|
+
return;
|
|
12
|
+
};
|
|
13
|
+
export const getReferenceUsage = (binding) => {
|
|
14
|
+
let hasRead = false;
|
|
15
|
+
let hasTrueWrite = false;
|
|
16
|
+
for (const referencePath of binding.referencePaths) {
|
|
17
|
+
if (!referencePath.isIdentifier())
|
|
18
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
19
|
+
const memberPath = getMemberExpressionForReference(referencePath);
|
|
20
|
+
if (!memberPath)
|
|
21
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
22
|
+
const memberNode = memberPath.node;
|
|
23
|
+
if (memberNode.computed)
|
|
24
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
25
|
+
if (memberNode.property.type !== "Identifier" ||
|
|
26
|
+
memberNode.property.name !== "current") {
|
|
27
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
28
|
+
}
|
|
29
|
+
const parentPath = memberPath.parentPath;
|
|
30
|
+
if (parentPath.isAssignmentExpression() &&
|
|
31
|
+
parentPath.node.left === memberNode) {
|
|
32
|
+
if (parentPath.node.operator !== "=")
|
|
33
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
34
|
+
const right = parentPath.node.right;
|
|
35
|
+
const value = getKnownBooleanValue(right);
|
|
36
|
+
if (value === undefined)
|
|
37
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
38
|
+
if (value) {
|
|
39
|
+
hasTrueWrite = true;
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (parentPath.isUpdateExpression() &&
|
|
44
|
+
parentPath.node.argument === memberNode) {
|
|
45
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
46
|
+
}
|
|
47
|
+
if (parentPath.isUnaryExpression() &&
|
|
48
|
+
parentPath.node.operator === "delete" &&
|
|
49
|
+
parentPath.node.argument === memberNode) {
|
|
50
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
51
|
+
}
|
|
52
|
+
if (!memberPath.isReferenced()) {
|
|
53
|
+
return { isSafe: false, hasRead, hasTrueWrite };
|
|
54
|
+
}
|
|
55
|
+
hasRead = true;
|
|
56
|
+
}
|
|
57
|
+
return { isSafe: true, hasRead, hasTrueWrite };
|
|
58
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const isKnownFalseValue = (expression) => {
|
|
2
|
+
if (expression.type === "BooleanLiteral")
|
|
3
|
+
return !expression.value;
|
|
4
|
+
if (expression.type === "UnaryExpression" &&
|
|
5
|
+
expression.operator === "!" &&
|
|
6
|
+
expression.argument.type === "NumericLiteral" &&
|
|
7
|
+
expression.argument.value === 1) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
};
|
|
12
|
+
export const isUseReferenceFalseInitializer = (declarator) => {
|
|
13
|
+
const init = declarator.init;
|
|
14
|
+
if (!init)
|
|
15
|
+
return false;
|
|
16
|
+
if (init.type !== "CallExpression")
|
|
17
|
+
return false;
|
|
18
|
+
if (init.arguments.length !== 1)
|
|
19
|
+
return false;
|
|
20
|
+
const argument = init.arguments[0];
|
|
21
|
+
if (!argument)
|
|
22
|
+
return false;
|
|
23
|
+
if (argument.type === "SpreadElement")
|
|
24
|
+
return false;
|
|
25
|
+
if (argument.type === "ArgumentPlaceholder")
|
|
26
|
+
return false;
|
|
27
|
+
if (!isKnownFalseValue(argument))
|
|
28
|
+
return false;
|
|
29
|
+
const callee = init.callee;
|
|
30
|
+
if (callee.type === "Identifier") {
|
|
31
|
+
return callee.name === "useRef";
|
|
32
|
+
}
|
|
33
|
+
if (callee.type !== "MemberExpression")
|
|
34
|
+
return false;
|
|
35
|
+
if (callee.computed)
|
|
36
|
+
return false;
|
|
37
|
+
if (callee.property.type !== "Identifier")
|
|
38
|
+
return false;
|
|
39
|
+
return callee.property.name === "useRef";
|
|
40
|
+
};
|
package/dist/transforms/rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
|
|
3
|
+
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
|
+
import { getReferenceUsage } from "./get-reference-usage.js";
|
|
5
|
+
import { isUseReferenceFalseInitializer } from "./is-use-reference-false-initializer.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
8
|
+
const traverse = require("@babel/traverse").default;
|
|
9
|
+
const BASE_NAME = "hasRunRef";
|
|
10
|
+
const renameUseReferenceGuardsV2Transform = {
|
|
11
|
+
id: "rename-use-reference-guards-v2",
|
|
12
|
+
description: "Renames boolean useRef(false) guard variables (including reset-to-false guards) to $hasRunRef/$hasRunRef2/... or hasRunRef/hasRunRef2/...",
|
|
13
|
+
scope: "file",
|
|
14
|
+
parallelizable: true,
|
|
15
|
+
transform(context) {
|
|
16
|
+
let nodesVisited = 0;
|
|
17
|
+
let transformationsApplied = 0;
|
|
18
|
+
for (const fileInfo of getFilesToProcess(context)) {
|
|
19
|
+
const group = new RenameGroup();
|
|
20
|
+
traverse(fileInfo.ast, {
|
|
21
|
+
VariableDeclarator(path) {
|
|
22
|
+
nodesVisited++;
|
|
23
|
+
const id = path.node.id;
|
|
24
|
+
if (id.type !== "Identifier")
|
|
25
|
+
return;
|
|
26
|
+
if (isStableRenamed(id.name))
|
|
27
|
+
return;
|
|
28
|
+
if (!isUseReferenceFalseInitializer(path.node))
|
|
29
|
+
return;
|
|
30
|
+
const binding = path.scope.getBinding(id.name);
|
|
31
|
+
if (!binding)
|
|
32
|
+
return;
|
|
33
|
+
if (!binding.constant)
|
|
34
|
+
return;
|
|
35
|
+
const usage = getReferenceUsage(binding);
|
|
36
|
+
// Unlike v1, this version also accepts guards that reset to false
|
|
37
|
+
if (!usage.isSafe || !usage.hasRead || !usage.hasTrueWrite)
|
|
38
|
+
return;
|
|
39
|
+
group.add({
|
|
40
|
+
scope: path.scope,
|
|
41
|
+
currentName: id.name,
|
|
42
|
+
baseName: BASE_NAME,
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
transformationsApplied += group.apply();
|
|
47
|
+
}
|
|
48
|
+
return Promise.resolve({
|
|
49
|
+
nodesVisited,
|
|
50
|
+
transformationsApplied,
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
export { renameUseReferenceGuardsV2Transform };
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { expandBooleanLiteralsTransform } from "./expand-boolean-literals/expand-boolean-literals-transform.js";
|
|
2
|
-
import { expandReturnSequenceTransform } from "./expand-return-sequence/expand-return-sequence-transform.js";
|
|
3
|
-
import { expandSequenceExpressionsTransform } from "./expand-sequence-expressions/expand-sequence-expressions-transform.js";
|
|
4
|
-
import { expandSequenceExpressionsV2Transform } from "./expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.js";
|
|
5
2
|
import { expandSpecialNumberLiteralsTransform } from "./expand-special-number-literals/expand-special-number-literals-transform.js";
|
|
6
|
-
import { expandSequenceExpressionsV3Transform } from "./expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.js";
|
|
7
3
|
import { expandSequenceExpressionsV4Transform } from "./expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.js";
|
|
8
|
-
import { expandThrowSequenceTransform } from "./expand-throw-sequence/expand-throw-sequence-transform.js";
|
|
9
4
|
import { expandUndefinedLiteralsTransform } from "./expand-undefined-literals/expand-undefined-literals-transform.js";
|
|
10
5
|
import { renameCatchParametersTransform } from "./rename-catch-parameters/rename-catch-parameters-transform.js";
|
|
11
6
|
import { renameDestructuredAliasesTransform } from "./rename-destructured-aliases/rename-destructured-aliases-transform.js";
|
|
@@ -14,16 +9,12 @@ import { renameLoopIndexVariablesTransform } from "./rename-loop-index-variables
|
|
|
14
9
|
import { renamePromiseExecutorParametersTransform } from "./rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js";
|
|
15
10
|
import { renameTimeoutIdsTransform } from "./rename-timeout-ids/rename-timeout-ids-transform.js";
|
|
16
11
|
import { renameUseReferenceGuardsTransform } from "./rename-use-reference-guards/rename-use-reference-guards-transform.js";
|
|
12
|
+
import { renameUseReferenceGuardsV2Transform } from "./rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js";
|
|
17
13
|
import { splitVariableDeclarationsTransform } from "./split-variable-declarations/split-variable-declarations-transform.js";
|
|
18
14
|
export const transformRegistry = {
|
|
19
15
|
[expandBooleanLiteralsTransform.id]: expandBooleanLiteralsTransform,
|
|
20
|
-
[expandReturnSequenceTransform.id]: expandReturnSequenceTransform,
|
|
21
|
-
[expandSequenceExpressionsTransform.id]: expandSequenceExpressionsTransform,
|
|
22
|
-
[expandSequenceExpressionsV2Transform.id]: expandSequenceExpressionsV2Transform,
|
|
23
|
-
[expandSequenceExpressionsV3Transform.id]: expandSequenceExpressionsV3Transform,
|
|
24
16
|
[expandSpecialNumberLiteralsTransform.id]: expandSpecialNumberLiteralsTransform,
|
|
25
17
|
[expandSequenceExpressionsV4Transform.id]: expandSequenceExpressionsV4Transform,
|
|
26
|
-
[expandThrowSequenceTransform.id]: expandThrowSequenceTransform,
|
|
27
18
|
[expandUndefinedLiteralsTransform.id]: expandUndefinedLiteralsTransform,
|
|
28
19
|
[renameCatchParametersTransform.id]: renameCatchParametersTransform,
|
|
29
20
|
[renameDestructuredAliasesTransform.id]: renameDestructuredAliasesTransform,
|
|
@@ -32,6 +23,7 @@ export const transformRegistry = {
|
|
|
32
23
|
[renamePromiseExecutorParametersTransform.id]: renamePromiseExecutorParametersTransform,
|
|
33
24
|
[renameTimeoutIdsTransform.id]: renameTimeoutIdsTransform,
|
|
34
25
|
[renameUseReferenceGuardsTransform.id]: renameUseReferenceGuardsTransform,
|
|
26
|
+
[renameUseReferenceGuardsV2Transform.id]: renameUseReferenceGuardsV2Transform,
|
|
35
27
|
[splitVariableDeclarationsTransform.id]: splitVariableDeclarationsTransform,
|
|
36
28
|
};
|
|
37
29
|
export const allTransformIds = Object.keys(transformRegistry);
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "miniread",
|
|
3
3
|
"author": "Łukasz Jerciński",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.7.0",
|
|
6
6
|
"description": "Transform minified JavaScript/TypeScript into a more readable form using deterministic AST-based transforms.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/transform-manifest.json
CHANGED
|
@@ -59,46 +59,6 @@
|
|
|
59
59
|
"evaluatedAt": "2026-01-22T12:49:10.952Z",
|
|
60
60
|
"notes": "Auto-added by evaluation script. Measured with baseline none: 0.09%."
|
|
61
61
|
},
|
|
62
|
-
{
|
|
63
|
-
"id": "expand-return-sequence",
|
|
64
|
-
"description": "Expands return sequences like `return a(), b();`",
|
|
65
|
-
"scope": "file",
|
|
66
|
-
"parallelizable": true,
|
|
67
|
-
"diffReductionImpact": -0.0012834789830316051,
|
|
68
|
-
"recommended": false,
|
|
69
|
-
"evaluatedAt": "2026-01-22T15:19:04.615Z",
|
|
70
|
-
"notes": "Auto-added by evaluation script. Measured with baseline none: -0.13%. Superseded by expand-sequence-expressions-v2 in the recommended preset."
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"id": "expand-sequence-expressions",
|
|
74
|
-
"description": "Expands comma operator sequences in statements and variable initializers",
|
|
75
|
-
"scope": "file",
|
|
76
|
-
"parallelizable": true,
|
|
77
|
-
"diffReductionImpact": -0.01282535248485317,
|
|
78
|
-
"recommended": false,
|
|
79
|
-
"evaluatedAt": "2026-01-22T17:15:48.528Z",
|
|
80
|
-
"notes": "Auto-added by evaluation script. Measured with baseline none: -1.28%. Enabled for readability even when line diffs increase. Kept separate from expand-return-sequence to avoid modifying existing transforms and to allow independent enabling."
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"id": "expand-sequence-expressions-v2",
|
|
84
|
-
"description": "Expands comma operator sequences in returns, statements, and variable initializers",
|
|
85
|
-
"scope": "file",
|
|
86
|
-
"parallelizable": true,
|
|
87
|
-
"diffReductionImpact": -0.014316453068081048,
|
|
88
|
-
"recommended": false,
|
|
89
|
-
"evaluatedAt": "2026-01-22T18:22:48.609Z",
|
|
90
|
-
"notes": "Superseded by expand-sequence-expressions-v3."
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"id": "expand-sequence-expressions-v3",
|
|
94
|
-
"description": "Expands comma operator sequences in returns, throws, statements, and variable initializers",
|
|
95
|
-
"scope": "file",
|
|
96
|
-
"parallelizable": true,
|
|
97
|
-
"diffReductionImpact": -0.014391951831788763,
|
|
98
|
-
"recommended": false,
|
|
99
|
-
"evaluatedAt": "2026-01-23T08:21:23.662Z",
|
|
100
|
-
"notes": "Supersedes expand-sequence-expressions-v2 in the recommended preset. Measured with baseline none: -1.44%. Enabled for readability even when line diffs increase."
|
|
101
|
-
},
|
|
102
62
|
{
|
|
103
63
|
"id": "expand-sequence-expressions-v4",
|
|
104
64
|
"description": "Expands comma operator sequences in returns, throws, statements (including control-flow bodies), and variable initializers",
|
|
@@ -107,7 +67,7 @@
|
|
|
107
67
|
"diffReductionImpact": -0.01730809158000035,
|
|
108
68
|
"recommended": true,
|
|
109
69
|
"evaluatedAt": "2026-01-23T10:57:45.082Z",
|
|
110
|
-
"notes": "Measured with baseline none: -1.73%. Supersedes
|
|
70
|
+
"notes": "Measured with baseline none: -1.73%. Supersedes all prior sequence expression transforms."
|
|
111
71
|
},
|
|
112
72
|
{
|
|
113
73
|
"id": "rename-use-reference-guards",
|
|
@@ -115,9 +75,19 @@
|
|
|
115
75
|
"scope": "file",
|
|
116
76
|
"parallelizable": true,
|
|
117
77
|
"diffReductionImpact": 0,
|
|
118
|
-
"recommended":
|
|
78
|
+
"recommended": false,
|
|
119
79
|
"evaluatedAt": "2026-01-22T17:03:19.826Z",
|
|
120
|
-
"notes": "
|
|
80
|
+
"notes": "Superseded by rename-use-reference-guards-v2.",
|
|
81
|
+
"supersededBy": "rename-use-reference-guards-v2"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "rename-use-reference-guards-v2",
|
|
85
|
+
"description": "Renames boolean useRef(false) guard variables (including reset-to-false guards) to hasRunRef/hasRunRef2/...",
|
|
86
|
+
"scope": "file",
|
|
87
|
+
"parallelizable": true,
|
|
88
|
+
"diffReductionImpact": 0,
|
|
89
|
+
"recommended": true,
|
|
90
|
+
"notes": "Supersedes rename-use-reference-guards and also covers guards that reset to false."
|
|
121
91
|
},
|
|
122
92
|
{
|
|
123
93
|
"id": "rename-timeout-ids",
|
|
@@ -125,9 +95,9 @@
|
|
|
125
95
|
"scope": "file",
|
|
126
96
|
"parallelizable": true,
|
|
127
97
|
"diffReductionImpact": 0.00003774938185385768,
|
|
128
|
-
"recommended":
|
|
98
|
+
"recommended": true,
|
|
129
99
|
"evaluatedAt": "2026-01-23T10:29:23.279Z",
|
|
130
|
-
"notes": "Measured with baseline none: 0.00%.
|
|
100
|
+
"notes": "Measured with baseline none: 0.00%. Added to recommended for readability."
|
|
131
101
|
},
|
|
132
102
|
{
|
|
133
103
|
"id": "split-variable-declarations",
|
|
@@ -139,16 +109,6 @@
|
|
|
139
109
|
"evaluatedAt": "2026-01-23T05:45:27.981Z",
|
|
140
110
|
"notes": "Auto-added by evaluation script. Measured with baseline none: -0.28%. Enabled in the recommended preset for readability and to normalize variable declarations even when line diffs increase."
|
|
141
111
|
},
|
|
142
|
-
{
|
|
143
|
-
"id": "expand-throw-sequence",
|
|
144
|
-
"description": "Expands throw sequences like `throw (a(), b)`",
|
|
145
|
-
"scope": "file",
|
|
146
|
-
"parallelizable": true,
|
|
147
|
-
"diffReductionImpact": -0.00007549876370771536,
|
|
148
|
-
"recommended": false,
|
|
149
|
-
"evaluatedAt": "2026-01-23T07:48:29.356Z",
|
|
150
|
-
"notes": "Largely superseded by expand-sequence-expressions-v3 (which also expands throw sequences), but kept for isolated runs and comparison."
|
|
151
|
-
},
|
|
152
112
|
{
|
|
153
113
|
"id": "rename-promise-executor-parameters",
|
|
154
114
|
"description": "Renames promise-like executor parameters in `new X(executor)` to resolve/reject when usage is high-confidence",
|