eslint-plugin-runtime-cleanup 1.2.8
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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/dist/_internal/ast-node.d.ts +19 -0
- package/dist/_internal/ast-node.d.ts.map +1 -0
- package/dist/_internal/ast-node.js +42 -0
- package/dist/_internal/ast-node.js.map +1 -0
- package/dist/_internal/bounded-cache.d.ts +37 -0
- package/dist/_internal/bounded-cache.d.ts.map +1 -0
- package/dist/_internal/bounded-cache.js +63 -0
- package/dist/_internal/bounded-cache.js.map +1 -0
- package/dist/_internal/cycle-safe-linked-search.d.ts +48 -0
- package/dist/_internal/cycle-safe-linked-search.d.ts.map +1 -0
- package/dist/_internal/cycle-safe-linked-search.js +70 -0
- package/dist/_internal/cycle-safe-linked-search.js.map +1 -0
- package/dist/_internal/expression-boolean-memoizer.d.ts +17 -0
- package/dist/_internal/expression-boolean-memoizer.d.ts.map +1 -0
- package/dist/_internal/expression-boolean-memoizer.js +22 -0
- package/dist/_internal/expression-boolean-memoizer.js.map +1 -0
- package/dist/_internal/filter-callback.d.ts +52 -0
- package/dist/_internal/filter-callback.d.ts.map +1 -0
- package/dist/_internal/filter-callback.js +108 -0
- package/dist/_internal/filter-callback.js.map +1 -0
- package/dist/_internal/floating-resource.d.ts +29 -0
- package/dist/_internal/floating-resource.d.ts.map +1 -0
- package/dist/_internal/floating-resource.js +114 -0
- package/dist/_internal/floating-resource.js.map +1 -0
- package/dist/_internal/member-call.d.ts +53 -0
- package/dist/_internal/member-call.d.ts.map +1 -0
- package/dist/_internal/member-call.js +61 -0
- package/dist/_internal/member-call.js.map +1 -0
- package/dist/_internal/normalize-expression-text.d.ts +21 -0
- package/dist/_internal/normalize-expression-text.d.ts.map +1 -0
- package/dist/_internal/normalize-expression-text.js +186 -0
- package/dist/_internal/normalize-expression-text.js.map +1 -0
- package/dist/_internal/nullish-comparison.d.ts +44 -0
- package/dist/_internal/nullish-comparison.d.ts.map +1 -0
- package/dist/_internal/nullish-comparison.js +162 -0
- package/dist/_internal/nullish-comparison.js.map +1 -0
- package/dist/_internal/plugin-settings.d.ts +30 -0
- package/dist/_internal/plugin-settings.d.ts.map +1 -0
- package/dist/_internal/plugin-settings.js +90 -0
- package/dist/_internal/plugin-settings.js.map +1 -0
- package/dist/_internal/report-adapter.d.ts +24 -0
- package/dist/_internal/report-adapter.d.ts.map +1 -0
- package/dist/_internal/report-adapter.js +35 -0
- package/dist/_internal/report-adapter.js.map +1 -0
- package/dist/_internal/rule-catalog.d.ts +47 -0
- package/dist/_internal/rule-catalog.d.ts.map +1 -0
- package/dist/_internal/rule-catalog.js +97 -0
- package/dist/_internal/rule-catalog.js.map +1 -0
- package/dist/_internal/rule-docs-metadata.d.ts +35 -0
- package/dist/_internal/rule-docs-metadata.d.ts.map +1 -0
- package/dist/_internal/rule-docs-metadata.js +172 -0
- package/dist/_internal/rule-docs-metadata.js.map +1 -0
- package/dist/_internal/rule-docs-url.d.ts +15 -0
- package/dist/_internal/rule-docs-url.d.ts.map +1 -0
- package/dist/_internal/rule-docs-url.js +15 -0
- package/dist/_internal/rule-docs-url.js.map +1 -0
- package/dist/_internal/rules-registry.d.ts +11 -0
- package/dist/_internal/rules-registry.d.ts.map +1 -0
- package/dist/_internal/rules-registry.js +53 -0
- package/dist/_internal/rules-registry.js.map +1 -0
- package/dist/_internal/runtime-cleanup-config-references.d.ts +38 -0
- package/dist/_internal/runtime-cleanup-config-references.d.ts.map +1 -0
- package/dist/_internal/runtime-cleanup-config-references.js +78 -0
- package/dist/_internal/runtime-cleanup-config-references.js.map +1 -0
- package/dist/_internal/safe-type-operation.d.ts +89 -0
- package/dist/_internal/safe-type-operation.d.ts.map +1 -0
- package/dist/_internal/safe-type-operation.js +147 -0
- package/dist/_internal/safe-type-operation.js.map +1 -0
- package/dist/_internal/scope-variable.d.ts +17 -0
- package/dist/_internal/scope-variable.d.ts.map +1 -0
- package/dist/_internal/scope-variable.js +30 -0
- package/dist/_internal/scope-variable.js.map +1 -0
- package/dist/_internal/type-checker.d.ts +11 -0
- package/dist/_internal/type-checker.d.ts.map +1 -0
- package/dist/_internal/type-checker.js +25 -0
- package/dist/_internal/type-checker.js.map +1 -0
- package/dist/_internal/type-predicate-autofix-safety.d.ts +16 -0
- package/dist/_internal/type-predicate-autofix-safety.d.ts.map +1 -0
- package/dist/_internal/type-predicate-autofix-safety.js +54 -0
- package/dist/_internal/type-predicate-autofix-safety.js.map +1 -0
- package/dist/_internal/type-reference-node.d.ts +23 -0
- package/dist/_internal/type-reference-node.d.ts.map +1 -0
- package/dist/_internal/type-reference-node.js +41 -0
- package/dist/_internal/type-reference-node.js.map +1 -0
- package/dist/_internal/typed-rule.d.ts +91 -0
- package/dist/_internal/typed-rule.d.ts.map +1 -0
- package/dist/_internal/typed-rule.js +121 -0
- package/dist/_internal/typed-rule.js.map +1 -0
- package/dist/_internal/value-rewrite-autofix-safety.d.ts +29 -0
- package/dist/_internal/value-rewrite-autofix-safety.d.ts.map +1 -0
- package/dist/_internal/value-rewrite-autofix-safety.js +108 -0
- package/dist/_internal/value-rewrite-autofix-safety.js.map +1 -0
- package/dist/plugin.cjs +3693 -0
- package/dist/plugin.cjs.map +7 -0
- package/dist/plugin.d.cts +75 -0
- package/dist/plugin.d.ts +75 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +223 -0
- package/dist/plugin.js.map +1 -0
- package/dist/rules/no-floating-abort-controllers.d.ts +9 -0
- package/dist/rules/no-floating-abort-controllers.d.ts.map +1 -0
- package/dist/rules/no-floating-abort-controllers.js +144 -0
- package/dist/rules/no-floating-abort-controllers.js.map +1 -0
- package/dist/rules/no-floating-audio-contexts.d.ts +9 -0
- package/dist/rules/no-floating-audio-contexts.d.ts.map +1 -0
- package/dist/rules/no-floating-audio-contexts.js +95 -0
- package/dist/rules/no-floating-audio-contexts.js.map +1 -0
- package/dist/rules/no-floating-broadcast-channels.d.ts +9 -0
- package/dist/rules/no-floating-broadcast-channels.d.ts.map +1 -0
- package/dist/rules/no-floating-broadcast-channels.js +151 -0
- package/dist/rules/no-floating-broadcast-channels.js.map +1 -0
- package/dist/rules/no-floating-child-processes.d.ts +9 -0
- package/dist/rules/no-floating-child-processes.d.ts.map +1 -0
- package/dist/rules/no-floating-child-processes.js +259 -0
- package/dist/rules/no-floating-child-processes.js.map +1 -0
- package/dist/rules/no-floating-disposable-stacks.d.ts +9 -0
- package/dist/rules/no-floating-disposable-stacks.d.ts.map +1 -0
- package/dist/rules/no-floating-disposable-stacks.js +177 -0
- package/dist/rules/no-floating-disposable-stacks.js.map +1 -0
- package/dist/rules/no-floating-file-watchers.d.ts +9 -0
- package/dist/rules/no-floating-file-watchers.d.ts.map +1 -0
- package/dist/rules/no-floating-file-watchers.js +241 -0
- package/dist/rules/no-floating-file-watchers.js.map +1 -0
- package/dist/rules/no-floating-geolocation-watches.d.ts +9 -0
- package/dist/rules/no-floating-geolocation-watches.d.ts.map +1 -0
- package/dist/rules/no-floating-geolocation-watches.js +156 -0
- package/dist/rules/no-floating-geolocation-watches.js.map +1 -0
- package/dist/rules/no-floating-infinite-animations.d.ts +9 -0
- package/dist/rules/no-floating-infinite-animations.d.ts.map +1 -0
- package/dist/rules/no-floating-infinite-animations.js +131 -0
- package/dist/rules/no-floating-infinite-animations.js.map +1 -0
- package/dist/rules/no-floating-media-streams.d.ts +9 -0
- package/dist/rules/no-floating-media-streams.d.ts.map +1 -0
- package/dist/rules/no-floating-media-streams.js +175 -0
- package/dist/rules/no-floating-media-streams.js.map +1 -0
- package/dist/rules/no-floating-message-channels.d.ts +9 -0
- package/dist/rules/no-floating-message-channels.d.ts.map +1 -0
- package/dist/rules/no-floating-message-channels.js +150 -0
- package/dist/rules/no-floating-message-channels.js.map +1 -0
- package/dist/rules/no-floating-network-connections.d.ts +9 -0
- package/dist/rules/no-floating-network-connections.d.ts.map +1 -0
- package/dist/rules/no-floating-network-connections.js +170 -0
- package/dist/rules/no-floating-network-connections.js.map +1 -0
- package/dist/rules/no-floating-object-urls.d.ts +9 -0
- package/dist/rules/no-floating-object-urls.d.ts.map +1 -0
- package/dist/rules/no-floating-object-urls.js +83 -0
- package/dist/rules/no-floating-object-urls.js.map +1 -0
- package/dist/rules/no-floating-observers.d.ts +9 -0
- package/dist/rules/no-floating-observers.d.ts.map +1 -0
- package/dist/rules/no-floating-observers.js +160 -0
- package/dist/rules/no-floating-observers.js.map +1 -0
- package/dist/rules/no-floating-servers.d.ts +9 -0
- package/dist/rules/no-floating-servers.d.ts.map +1 -0
- package/dist/rules/no-floating-servers.js +282 -0
- package/dist/rules/no-floating-servers.js.map +1 -0
- package/dist/rules/no-floating-streams.d.ts +9 -0
- package/dist/rules/no-floating-streams.d.ts.map +1 -0
- package/dist/rules/no-floating-streams.js +222 -0
- package/dist/rules/no-floating-streams.js.map +1 -0
- package/dist/rules/no-floating-timers.d.ts +9 -0
- package/dist/rules/no-floating-timers.d.ts.map +1 -0
- package/dist/rules/no-floating-timers.js +145 -0
- package/dist/rules/no-floating-timers.js.map +1 -0
- package/dist/rules/no-floating-wake-locks.d.ts +9 -0
- package/dist/rules/no-floating-wake-locks.d.ts.map +1 -0
- package/dist/rules/no-floating-wake-locks.js +159 -0
- package/dist/rules/no-floating-wake-locks.js.map +1 -0
- package/dist/rules/no-floating-web-stream-locks.d.ts +9 -0
- package/dist/rules/no-floating-web-stream-locks.d.ts.map +1 -0
- package/dist/rules/no-floating-web-stream-locks.js +87 -0
- package/dist/rules/no-floating-web-stream-locks.js.map +1 -0
- package/dist/rules/no-floating-workers.d.ts +9 -0
- package/dist/rules/no-floating-workers.d.ts.map +1 -0
- package/dist/rules/no-floating-workers.js +185 -0
- package/dist/rules/no-floating-workers.js.map +1 -0
- package/dist/rules/no-unmanaged-event-listeners.d.ts +9 -0
- package/dist/rules/no-unmanaged-event-listeners.d.ts.map +1 -0
- package/dist/rules/no-unmanaged-event-listeners.js +210 -0
- package/dist/rules/no-unmanaged-event-listeners.js.map +1 -0
- package/docs/rules/getting-started.md +29 -0
- package/docs/rules/guides/adoption-checklist.md +31 -0
- package/docs/rules/guides/preset-selection-strategy.md +24 -0
- package/docs/rules/guides/rollout-and-fix-safety.md +42 -0
- package/docs/rules/guides/snapshot-testing.md +20 -0
- package/docs/rules/guides/type-aware-linting-readiness.md +20 -0
- package/docs/rules/no-floating-abort-controllers.md +126 -0
- package/docs/rules/no-floating-audio-contexts.md +104 -0
- package/docs/rules/no-floating-broadcast-channels.md +105 -0
- package/docs/rules/no-floating-child-processes.md +123 -0
- package/docs/rules/no-floating-disposable-stacks.md +118 -0
- package/docs/rules/no-floating-file-watchers.md +111 -0
- package/docs/rules/no-floating-geolocation-watches.md +95 -0
- package/docs/rules/no-floating-infinite-animations.md +110 -0
- package/docs/rules/no-floating-media-streams.md +113 -0
- package/docs/rules/no-floating-message-channels.md +114 -0
- package/docs/rules/no-floating-network-connections.md +116 -0
- package/docs/rules/no-floating-object-urls.md +102 -0
- package/docs/rules/no-floating-observers.md +108 -0
- package/docs/rules/no-floating-servers.md +127 -0
- package/docs/rules/no-floating-streams.md +120 -0
- package/docs/rules/no-floating-timers.md +120 -0
- package/docs/rules/no-floating-wake-locks.md +109 -0
- package/docs/rules/no-floating-web-stream-locks.md +105 -0
- package/docs/rules/no-floating-workers.md +123 -0
- package/docs/rules/no-unmanaged-event-listeners.md +143 -0
- package/docs/rules/overview.md +44 -0
- package/docs/rules/presets/all.md +35 -0
- package/docs/rules/presets/experimental.md +44 -0
- package/docs/rules/presets/index.md +54 -0
- package/docs/rules/presets/minimal.md +17 -0
- package/docs/rules/presets/recommended-type-checked.md +43 -0
- package/docs/rules/presets/recommended.md +34 -0
- package/docs/rules/presets/strict.md +36 -0
- package/package.json +323 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Utilities for detecting nodes that live inside `.filter(...)` callbacks.
|
|
4
|
+
*/
|
|
5
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
6
|
+
import { getParentNode } from "./ast-node.js";
|
|
7
|
+
/** Target method name used for callback-context detection. */
|
|
8
|
+
const FILTER_METHOD_NAME = "filter";
|
|
9
|
+
/**
|
|
10
|
+
* Narrows nodes to function-like callback expressions.
|
|
11
|
+
*/
|
|
12
|
+
const isFunctionCallbackNode = (node) => node.type === AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
13
|
+
node.type === AST_NODE_TYPES.FunctionExpression;
|
|
14
|
+
/**
|
|
15
|
+
* Narrows call expressions to direct `.filter(...)` calls.
|
|
16
|
+
*/
|
|
17
|
+
export const isFilterCallExpression = (expression) => !expression.optional &&
|
|
18
|
+
expression.callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
19
|
+
!expression.callee.computed &&
|
|
20
|
+
!expression.callee.optional &&
|
|
21
|
+
expression.callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
22
|
+
expression.callee.property.name === FILTER_METHOD_NAME;
|
|
23
|
+
/**
|
|
24
|
+
* Extract the first callback argument from a direct `.filter(...)` call.
|
|
25
|
+
*
|
|
26
|
+
* @param expression - Candidate call expression to inspect.
|
|
27
|
+
*
|
|
28
|
+
* @returns Callback expression when the call is a supported `.filter(...)`
|
|
29
|
+
* invocation and the first argument is an arrow/function expression;
|
|
30
|
+
* otherwise `null`.
|
|
31
|
+
*/
|
|
32
|
+
export const getFilterCallbackFunctionArgument = (expression) => {
|
|
33
|
+
if (!isFilterCallExpression(expression)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const [firstArgument] = expression.arguments;
|
|
37
|
+
if (!firstArgument ||
|
|
38
|
+
(firstArgument.type !== AST_NODE_TYPES.ArrowFunctionExpression &&
|
|
39
|
+
firstArgument.type !== AST_NODE_TYPES.FunctionExpression)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return firstArgument;
|
|
43
|
+
};
|
|
44
|
+
const isSingleParameterExpressionArrowFunction = (callback) => {
|
|
45
|
+
if (callback.params.length !== 1) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (callback.body.type === AST_NODE_TYPES.BlockStatement) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const firstParameter = callback.params.at(0);
|
|
52
|
+
return firstParameter?.type === AST_NODE_TYPES.Identifier;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Extract a strict callback shape from direct `.filter(...)` calls.
|
|
56
|
+
*
|
|
57
|
+
* @param expression - Candidate call expression to inspect.
|
|
58
|
+
*
|
|
59
|
+
* @returns Structured callback match when supported; otherwise `null`.
|
|
60
|
+
*/
|
|
61
|
+
export const getSingleParameterExpressionArrowFilterCallback = (expression) => {
|
|
62
|
+
const callback = getFilterCallbackFunctionArgument(expression);
|
|
63
|
+
if (callback?.type !== AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
if (!isSingleParameterExpressionArrowFunction(callback)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const [parameter] = callback.params;
|
|
70
|
+
return {
|
|
71
|
+
callback,
|
|
72
|
+
parameter,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Checks whether a node appears inside a callback passed as the first argument
|
|
77
|
+
* to a direct `.filter(...)` call.
|
|
78
|
+
*
|
|
79
|
+
* @param node - Node to inspect.
|
|
80
|
+
*
|
|
81
|
+
* @returns `true` when the node is inside a `.filter(...)` callback; otherwise
|
|
82
|
+
* `false`.
|
|
83
|
+
*/
|
|
84
|
+
export const isWithinFilterCallback = (node) => {
|
|
85
|
+
let currentNode = node;
|
|
86
|
+
const visitedNodes = new Set();
|
|
87
|
+
while (currentNode) {
|
|
88
|
+
if (visitedNodes.has(currentNode)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
visitedNodes.add(currentNode);
|
|
92
|
+
if (isFunctionCallbackNode(currentNode)) {
|
|
93
|
+
const callbackParent = getParentNode(currentNode);
|
|
94
|
+
if (callbackParent?.type !== AST_NODE_TYPES.CallExpression) {
|
|
95
|
+
currentNode = getParentNode(currentNode);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const [firstArgument] = callbackParent.arguments;
|
|
99
|
+
if (firstArgument === currentNode &&
|
|
100
|
+
isFilterCallExpression(callbackParent)) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
currentNode = getParentNode(currentNode);
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=filter-callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-callback.js","sourceRoot":"","sources":["../../src/_internal/filter-callback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Shared AST helpers for rules that reject unowned cleanup handles.
|
|
4
|
+
*/
|
|
5
|
+
import { type TSESTree } from "@typescript-eslint/utils";
|
|
6
|
+
/**
|
|
7
|
+
* Unwrap syntax that does not change whether a resource expression is owned.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getTransparentWrappedExpression: (node: Readonly<TSESTree.Node>) => Readonly<TSESTree.Node> | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a static property name from dot or string-literal member access.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getStaticPropertyName: (node: Readonly<TSESTree.MemberExpression["property"]>, computed: boolean) => string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a simple static member path such as `globalThis.URL.createObjectURL`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const collectStaticMemberPath: (node: Readonly<TSESTree.Expression>) => readonly string[] | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Check whether a resource-producing expression is discarded as a standalone
|
|
20
|
+
* expression or explicitly voided.
|
|
21
|
+
*/
|
|
22
|
+
export declare const isDiscardedResourceExpression: (node: Readonly<TSESTree.Node>) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check whether a resource handle is immediately used as a member receiver
|
|
25
|
+
* instead of being retained. Cleanup members are excluded so immediate cleanup
|
|
26
|
+
* calls such as `new AudioContext().close()` are not reported here.
|
|
27
|
+
*/
|
|
28
|
+
export declare const isImmediateUnownedMemberReceiver: (node: Readonly<TSESTree.Node>, cleanupMemberNames: ReadonlySet<string>) => boolean;
|
|
29
|
+
//# sourceMappingURL=floating-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-resource.d.ts","sourceRoot":"","sources":["../../src/_internal/floating-resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIzE;;GAEG;AACH,eAAO,MAAM,+BAA+B,GACxC,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAC9B,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,SA0B5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAC9B,MAAM,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,EACrD,UAAU,OAAO,KAClB,MAAM,GAAG,SAcX,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAChC,MAAM,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,KACpC,SAAS,MAAM,EAAE,GAAG,SAetB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,GACtC,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAC9B,OAkCF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,GACzC,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC7B,oBAAoB,WAAW,CAAC,MAAM,CAAC,KACxC,OAgCF,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Shared AST helpers for rules that reject unowned cleanup handles.
|
|
4
|
+
*/
|
|
5
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
6
|
+
import { getParentNode } from "./ast-node.js";
|
|
7
|
+
/**
|
|
8
|
+
* Unwrap syntax that does not change whether a resource expression is owned.
|
|
9
|
+
*/
|
|
10
|
+
export const getTransparentWrappedExpression = (node) => {
|
|
11
|
+
if (node.type === AST_NODE_TYPES.AwaitExpression) {
|
|
12
|
+
return node.argument;
|
|
13
|
+
}
|
|
14
|
+
if (node.type === AST_NODE_TYPES.ChainExpression) {
|
|
15
|
+
return node.expression;
|
|
16
|
+
}
|
|
17
|
+
if (node.type === AST_NODE_TYPES.TSAsExpression) {
|
|
18
|
+
return node.expression;
|
|
19
|
+
}
|
|
20
|
+
if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
21
|
+
return node.expression;
|
|
22
|
+
}
|
|
23
|
+
if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
24
|
+
return node.expression;
|
|
25
|
+
}
|
|
26
|
+
if (node.type === AST_NODE_TYPES.TSTypeAssertion) {
|
|
27
|
+
return node.expression;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a static property name from dot or string-literal member access.
|
|
33
|
+
*/
|
|
34
|
+
export const getStaticPropertyName = (node, computed) => {
|
|
35
|
+
if (!computed && node.type === AST_NODE_TYPES.Identifier) {
|
|
36
|
+
return node.name;
|
|
37
|
+
}
|
|
38
|
+
if (computed &&
|
|
39
|
+
node.type === AST_NODE_TYPES.Literal &&
|
|
40
|
+
typeof node.value === "string") {
|
|
41
|
+
return node.value;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a simple static member path such as `globalThis.URL.createObjectURL`.
|
|
47
|
+
*/
|
|
48
|
+
export const collectStaticMemberPath = (node) => {
|
|
49
|
+
if (node.type === AST_NODE_TYPES.Identifier) {
|
|
50
|
+
return [node.name];
|
|
51
|
+
}
|
|
52
|
+
if (node.type !== AST_NODE_TYPES.MemberExpression || node.optional) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const objectPath = collectStaticMemberPath(node.object);
|
|
56
|
+
const propertyName = getStaticPropertyName(node.property, node.computed);
|
|
57
|
+
return objectPath === undefined || propertyName === undefined
|
|
58
|
+
? undefined
|
|
59
|
+
: [...objectPath, propertyName];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Check whether a resource-producing expression is discarded as a standalone
|
|
63
|
+
* expression or explicitly voided.
|
|
64
|
+
*/
|
|
65
|
+
export const isDiscardedResourceExpression = (node) => {
|
|
66
|
+
let current = node;
|
|
67
|
+
let parent = getParentNode(current);
|
|
68
|
+
while (parent !== undefined) {
|
|
69
|
+
const wrappedExpression = getTransparentWrappedExpression(parent);
|
|
70
|
+
if (wrappedExpression === current) {
|
|
71
|
+
current = parent;
|
|
72
|
+
parent = getParentNode(current);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (parent.type === AST_NODE_TYPES.ExpressionStatement &&
|
|
76
|
+
parent.expression === current) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (parent.type === AST_NODE_TYPES.UnaryExpression &&
|
|
80
|
+
parent.operator === "void" &&
|
|
81
|
+
parent.argument === current) {
|
|
82
|
+
const unaryParent = getParentNode(parent);
|
|
83
|
+
return unaryParent?.type === AST_NODE_TYPES.ExpressionStatement;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Check whether a resource handle is immediately used as a member receiver
|
|
91
|
+
* instead of being retained. Cleanup members are excluded so immediate cleanup
|
|
92
|
+
* calls such as `new AudioContext().close()` are not reported here.
|
|
93
|
+
*/
|
|
94
|
+
export const isImmediateUnownedMemberReceiver = (node, cleanupMemberNames) => {
|
|
95
|
+
let current = node;
|
|
96
|
+
let parent = getParentNode(current);
|
|
97
|
+
while (parent !== undefined) {
|
|
98
|
+
const wrappedExpression = getTransparentWrappedExpression(parent);
|
|
99
|
+
if (wrappedExpression === current) {
|
|
100
|
+
current = parent;
|
|
101
|
+
parent = getParentNode(current);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (parent.type !== AST_NODE_TYPES.MemberExpression ||
|
|
105
|
+
parent.object !== current ||
|
|
106
|
+
parent.optional) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const propertyName = getStaticPropertyName(parent.property, parent.computed);
|
|
110
|
+
return (propertyName === undefined || !cleanupMemberNames.has(propertyName));
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=floating-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-resource.js","sourceRoot":"","sources":["../../src/_internal/floating-resource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Shared call-expression helpers for matching method calls safely.
|
|
4
|
+
*/
|
|
5
|
+
import { type TSESTree } from "@typescript-eslint/utils";
|
|
6
|
+
/**
|
|
7
|
+
* Strongly-typed shape for non-computed member calls with identifier receiver
|
|
8
|
+
* and property (e.g. `Object.keys`).
|
|
9
|
+
*/
|
|
10
|
+
export type IdentifierMemberCallExpression = TSESTree.CallExpression & {
|
|
11
|
+
callee: TSESTree.MemberExpression & {
|
|
12
|
+
computed: false;
|
|
13
|
+
object: TSESTree.Identifier;
|
|
14
|
+
property: TSESTree.Identifier;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Strongly-typed shape for non-computed member calls with identifier property
|
|
19
|
+
* (e.g. `value.includes`).
|
|
20
|
+
*/
|
|
21
|
+
export type IdentifierPropertyMemberCallExpression = TSESTree.CallExpression & {
|
|
22
|
+
callee: TSESTree.MemberExpression & {
|
|
23
|
+
computed: false;
|
|
24
|
+
object: Exclude<TSESTree.MemberExpression["object"], TSESTree.Super>;
|
|
25
|
+
property: TSESTree.Identifier;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Match `ObjectName.methodName(...)` style calls.
|
|
30
|
+
*
|
|
31
|
+
* @param options - Candidate call expression and expected receiver/member
|
|
32
|
+
* names.
|
|
33
|
+
*
|
|
34
|
+
* @returns Narrowed call expression when the shape matches; otherwise `null`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getIdentifierMemberCall: (options: Readonly<{
|
|
37
|
+
memberName: string;
|
|
38
|
+
node: Readonly<TSESTree.CallExpression>;
|
|
39
|
+
objectName: string;
|
|
40
|
+
}>) => IdentifierMemberCallExpression | null;
|
|
41
|
+
/**
|
|
42
|
+
* Match `<expression>.memberName(...)` style calls where the property is a
|
|
43
|
+
* non-computed identifier.
|
|
44
|
+
*
|
|
45
|
+
* @param options - Candidate call expression and expected member name.
|
|
46
|
+
*
|
|
47
|
+
* @returns Narrowed call expression when matched; otherwise `null`.
|
|
48
|
+
*/
|
|
49
|
+
export declare const getIdentifierPropertyMemberCall: (options: Readonly<{
|
|
50
|
+
memberName: string;
|
|
51
|
+
node: Readonly<TSESTree.CallExpression>;
|
|
52
|
+
}>) => IdentifierPropertyMemberCallExpression | null;
|
|
53
|
+
//# sourceMappingURL=member-call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"member-call.d.ts","sourceRoot":"","sources":["../../src/_internal/member-call.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzE;;;GAGG;AACH,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC,cAAc,GAAG;IACnE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,GAAG;QAChC,QAAQ,EAAE,KAAK,CAAC;QAChB,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC;KACjC,CAAC;CACL,CAAC;AACF;;;GAGG;AACH,MAAM,MAAM,sCAAsC,GAAG,QAAQ,CAAC,cAAc,GAAG;IAC3E,MAAM,EAAE,QAAQ,CAAC,gBAAgB,GAAG;QAChC,QAAQ,EAAE,KAAK,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrE,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC;KACjC,CAAC;CACL,CAAC;AAkDF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAChC,SAAS,QAAQ,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC,KACH,8BAA8B,GAAG,IAKnC,CAAC;AACF;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,GACxC,SAAS,QAAQ,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;CAC3C,CAAC,KACH,sCAAsC,GAAG,IAK3C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Shared call-expression helpers for matching method calls safely.
|
|
4
|
+
*/
|
|
5
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
6
|
+
const isIdentifierMemberCallExpression = (options) => {
|
|
7
|
+
const { memberName, node, objectName } = options;
|
|
8
|
+
if (node.optional) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const { callee } = node;
|
|
12
|
+
return (callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
13
|
+
!callee.computed &&
|
|
14
|
+
!callee.optional &&
|
|
15
|
+
callee.object.type === AST_NODE_TYPES.Identifier &&
|
|
16
|
+
callee.object.name === objectName &&
|
|
17
|
+
callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
18
|
+
callee.property.name === memberName);
|
|
19
|
+
};
|
|
20
|
+
const isIdentifierPropertyMemberCallExpression = (options) => {
|
|
21
|
+
const { memberName, node } = options;
|
|
22
|
+
if (node.optional) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const { callee } = node;
|
|
26
|
+
return (callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
27
|
+
!callee.computed &&
|
|
28
|
+
!callee.optional &&
|
|
29
|
+
callee.object.type !== AST_NODE_TYPES.Super &&
|
|
30
|
+
callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
31
|
+
callee.property.name === memberName);
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Match `ObjectName.methodName(...)` style calls.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Candidate call expression and expected receiver/member
|
|
37
|
+
* names.
|
|
38
|
+
*
|
|
39
|
+
* @returns Narrowed call expression when the shape matches; otherwise `null`.
|
|
40
|
+
*/
|
|
41
|
+
export const getIdentifierMemberCall = (options) => {
|
|
42
|
+
if (!isIdentifierMemberCallExpression(options)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return options.node;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Match `<expression>.memberName(...)` style calls where the property is a
|
|
49
|
+
* non-computed identifier.
|
|
50
|
+
*
|
|
51
|
+
* @param options - Candidate call expression and expected member name.
|
|
52
|
+
*
|
|
53
|
+
* @returns Narrowed call expression when matched; otherwise `null`.
|
|
54
|
+
*/
|
|
55
|
+
export const getIdentifierPropertyMemberCall = (options) => {
|
|
56
|
+
if (!isIdentifierPropertyMemberCallExpression(options)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return options.node;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=member-call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"member-call.js","sourceRoot":"","sources":["../../src/_internal/member-call.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAiB,MAAM,0BAA0B,CAAC;AAuBzE,MAAM,gCAAgC,GAAG,CACrC,OAIE,EAKH,EAAE;IACD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACjD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,OAAO,CACH,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB;QAC/C,CAAC,MAAM,CAAC,QAAQ;QAChB,CAAC,MAAM,CAAC,QAAQ;QAChB,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;QAChD,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU;QACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;QAClD,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CACtC,CAAC;AACN,CAAC,CAAC;AACF,MAAM,wCAAwC,GAAG,CAC7C,OAGE,EAIH,EAAE;IACD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,OAAO,CACH,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB;QAC/C,CAAC,MAAM,CAAC,QAAQ;QAChB,CAAC,MAAM,CAAC,QAAQ;QAChB,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,KAAK;QAC3C,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;QAClD,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CACtC,CAAC;AACN,CAAC,CAAC;AACF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACnC,OAIE,EACmC,EAAE;IACvC,IAAI,CAAC,gCAAgC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC;AACF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC3C,OAGE,EAC2C,EAAE;IAC/C,IAAI,CAAC,wCAAwC,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
/**
|
|
3
|
+
* Compare two expressions for structural equivalence after unwrapping
|
|
4
|
+
* transparent TypeScript wrappers.
|
|
5
|
+
*
|
|
6
|
+
* @param left - Left-hand expression.
|
|
7
|
+
* @param right - Right-hand expression.
|
|
8
|
+
*
|
|
9
|
+
* @returns `true` when both expressions are structurally equivalent.
|
|
10
|
+
*/
|
|
11
|
+
export declare const areEquivalentExpressions: (left: Readonly<TSESTree.Expression>, right: Readonly<TSESTree.Expression>) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Compare two type nodes for structural equivalence.
|
|
14
|
+
*
|
|
15
|
+
* @param left - Left-hand type node.
|
|
16
|
+
* @param right - Right-hand type node.
|
|
17
|
+
*
|
|
18
|
+
* @returns `true` when both type nodes are structurally equivalent.
|
|
19
|
+
*/
|
|
20
|
+
export declare const areEquivalentTypeNodes: (left: Readonly<TSESTree.TypeNode>, right: Readonly<TSESTree.TypeNode>) => boolean;
|
|
21
|
+
//# sourceMappingURL=normalize-expression-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-expression-text.d.ts","sourceRoot":"","sources":["../../src/_internal/normalize-expression-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAgPzD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GACjC,MAAM,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EACnC,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,KACrC,OAIE,CAAC;AAEN;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAC/B,MAAM,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACjC,OAAO,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,KACnC,OAA+C,CAAC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Structural normalization and equivalence checks for expressions and type
|
|
4
|
+
* nodes used by safe-fix heuristics.
|
|
5
|
+
*/
|
|
6
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
7
|
+
/**
|
|
8
|
+
* ESTree metadata keys ignored during structural-equivalence checks.
|
|
9
|
+
*/
|
|
10
|
+
const ignoredPropertyKeys = new Set([
|
|
11
|
+
"end",
|
|
12
|
+
"loc",
|
|
13
|
+
"parent",
|
|
14
|
+
"range",
|
|
15
|
+
"start",
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Maximum recursive depth allowed during structural node-value comparisons.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* This guard avoids stack-overflow crashes on pathological, adversarially deep
|
|
22
|
+
* AST/type structures. Returning `false` in that case preserves lint-process
|
|
23
|
+
* stability by failing closed for autofix-equivalence checks.
|
|
24
|
+
*/
|
|
25
|
+
const MAX_NODE_VALUE_COMPARISON_DEPTH = 256;
|
|
26
|
+
/**
|
|
27
|
+
* Check whether a value is object-like for structural comparisons.
|
|
28
|
+
*/
|
|
29
|
+
const isComparableRecord = (value) => typeof value === "object" && value !== null;
|
|
30
|
+
/**
|
|
31
|
+
* Return stable comparable keys after stripping metadata properties.
|
|
32
|
+
*/
|
|
33
|
+
const getComparableKeys = (value) => Object.keys(value).filter((key) => !ignoredPropertyKeys.has(key));
|
|
34
|
+
/**
|
|
35
|
+
* Read comparable keys with per-comparison caching to reduce repeated
|
|
36
|
+
* key-filter allocations during deep traversals.
|
|
37
|
+
*
|
|
38
|
+
* @param value - Object candidate being compared.
|
|
39
|
+
* @param comparableKeysByObject - Per-comparison key cache.
|
|
40
|
+
*
|
|
41
|
+
* @returns Comparable key list with ESTree metadata keys removed.
|
|
42
|
+
*/
|
|
43
|
+
const getCachedComparableKeys = (value, comparableKeysByObject) => {
|
|
44
|
+
const existingComparableKeys = comparableKeysByObject.get(value);
|
|
45
|
+
if (existingComparableKeys !== undefined) {
|
|
46
|
+
return existingComparableKeys;
|
|
47
|
+
}
|
|
48
|
+
const comparableKeys = getComparableKeys(value);
|
|
49
|
+
comparableKeysByObject.set(value, comparableKeys);
|
|
50
|
+
return comparableKeys;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Unwrap transparent TypeScript expression wrappers.
|
|
54
|
+
*
|
|
55
|
+
* @param expression - Expression to normalize.
|
|
56
|
+
*
|
|
57
|
+
* @returns The innermost wrapped expression.
|
|
58
|
+
*/
|
|
59
|
+
const unwrapTransparentExpression = (expression) => {
|
|
60
|
+
let currentExpression = expression;
|
|
61
|
+
const visitedExpressions = new Set();
|
|
62
|
+
while (true) {
|
|
63
|
+
if (visitedExpressions.has(currentExpression)) {
|
|
64
|
+
return currentExpression;
|
|
65
|
+
}
|
|
66
|
+
visitedExpressions.add(currentExpression);
|
|
67
|
+
if (currentExpression.type === AST_NODE_TYPES.TSAsExpression) {
|
|
68
|
+
currentExpression = currentExpression.expression;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (currentExpression.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
72
|
+
currentExpression = currentExpression.expression;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (currentExpression.type === AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
76
|
+
currentExpression = currentExpression.expression;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (currentExpression.type === AST_NODE_TYPES.TSTypeAssertion) {
|
|
80
|
+
currentExpression = currentExpression.expression;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
return currentExpression;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Records a compared object pair and reports whether that pair was already
|
|
88
|
+
* visited.
|
|
89
|
+
*
|
|
90
|
+
* @param left - Left-side object in the comparison pair.
|
|
91
|
+
* @param right - Right-side object in the comparison pair.
|
|
92
|
+
* @param seenPairs - Weakly-held pair-tracking cache for cycle-safe traversal.
|
|
93
|
+
*
|
|
94
|
+
* @returns `true` when this exact pair has already been processed.
|
|
95
|
+
*/
|
|
96
|
+
const markAndCheckSeenPair = (left, right, seenPairs) => {
|
|
97
|
+
const seenRightNodes = seenPairs.get(left);
|
|
98
|
+
if (seenRightNodes?.has(right) === true) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
if (seenRightNodes === undefined) {
|
|
102
|
+
seenPairs.set(left, new WeakSet([right]));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
seenRightNodes.add(right);
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Deep structural comparison that is resilient to cycles and ESTree metadata
|
|
111
|
+
* fields.
|
|
112
|
+
*
|
|
113
|
+
* @param left - Left-side value.
|
|
114
|
+
* @param right - Right-side value.
|
|
115
|
+
* @param seenPairs - Pair cache used to break recursive cycles.
|
|
116
|
+
*
|
|
117
|
+
* @returns `true` when the values are structurally equivalent after metadata
|
|
118
|
+
* normalization.
|
|
119
|
+
*/
|
|
120
|
+
const areEquivalentNodeValues = (left, right, seenPairs = new WeakMap(), comparableKeysByObject = new WeakMap(), depth = 0) => {
|
|
121
|
+
if (depth >= MAX_NODE_VALUE_COMPARISON_DEPTH) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
if (Object.is(left, right)) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (typeof left !== typeof right) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (left === null || right === null) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
134
|
+
if (!Array.isArray(left) || !Array.isArray(right)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (markAndCheckSeenPair(left, right, seenPairs)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (left.length !== right.length) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return left.every((value, index) => areEquivalentNodeValues(value, right[index], seenPairs, comparableKeysByObject, depth + 1));
|
|
144
|
+
}
|
|
145
|
+
if (!isComparableRecord(left) || !isComparableRecord(right)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
if (markAndCheckSeenPair(left, right, seenPairs)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
const leftKeys = getCachedComparableKeys(left, comparableKeysByObject);
|
|
152
|
+
const rightKeys = getCachedComparableKeys(right, comparableKeysByObject);
|
|
153
|
+
const rightKeySet = new Set(rightKeys);
|
|
154
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
if (leftKeys.some((key) => !rightKeySet.has(key))) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return leftKeys.every((key) => {
|
|
161
|
+
if (!Object.hasOwn(left, key) || !Object.hasOwn(right, key)) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return areEquivalentNodeValues(left[key], right[key], seenPairs, comparableKeysByObject, depth + 1);
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Compare two expressions for structural equivalence after unwrapping
|
|
169
|
+
* transparent TypeScript wrappers.
|
|
170
|
+
*
|
|
171
|
+
* @param left - Left-hand expression.
|
|
172
|
+
* @param right - Right-hand expression.
|
|
173
|
+
*
|
|
174
|
+
* @returns `true` when both expressions are structurally equivalent.
|
|
175
|
+
*/
|
|
176
|
+
export const areEquivalentExpressions = (left, right) => areEquivalentNodeValues(unwrapTransparentExpression(left), unwrapTransparentExpression(right));
|
|
177
|
+
/**
|
|
178
|
+
* Compare two type nodes for structural equivalence.
|
|
179
|
+
*
|
|
180
|
+
* @param left - Left-hand type node.
|
|
181
|
+
* @param right - Right-hand type node.
|
|
182
|
+
*
|
|
183
|
+
* @returns `true` when both type nodes are structurally equivalent.
|
|
184
|
+
*/
|
|
185
|
+
export const areEquivalentTypeNodes = (left, right) => areEquivalentNodeValues(left, right);
|
|
186
|
+
//# sourceMappingURL=normalize-expression-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-expression-text.js","sourceRoot":"","sources":["../../src/_internal/normalize-expression-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Shared helpers for parsing and flattening nullish comparison expressions.
|
|
4
|
+
*/
|
|
5
|
+
import type { TSESTree } from "@typescript-eslint/utils";
|
|
6
|
+
/**
|
|
7
|
+
* Normalized representation of one binary comparison against null/undefined.
|
|
8
|
+
*/
|
|
9
|
+
type NullishComparison = Readonly<{
|
|
10
|
+
comparedExpression: TSESTree.Expression;
|
|
11
|
+
kind: NullishComparisonKind;
|
|
12
|
+
operator: NullishComparisonOperator;
|
|
13
|
+
}>;
|
|
14
|
+
/** Nullish literal kinds supported by comparison extraction. */
|
|
15
|
+
type NullishComparisonKind = "null" | "undefined";
|
|
16
|
+
/** Operators supported by nullish comparison extraction. */
|
|
17
|
+
type NullishComparisonOperator = "!=" | "!==" | "==" | "===";
|
|
18
|
+
/**
|
|
19
|
+
* Flatten a logical-expression tree for one specific operator.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Expression and logical operator to flatten.
|
|
22
|
+
*
|
|
23
|
+
* @returns Left-to-right list of terms participating in that operator chain.
|
|
24
|
+
*/
|
|
25
|
+
export declare const flattenLogicalTerms: ({ expression, operator, }: Readonly<{
|
|
26
|
+
expression: Readonly<TSESTree.Expression>;
|
|
27
|
+
operator: "&&" | "||";
|
|
28
|
+
}>) => readonly TSESTree.Expression[];
|
|
29
|
+
/**
|
|
30
|
+
* Narrow a list of expressions to an exact two-term tuple.
|
|
31
|
+
*/
|
|
32
|
+
export declare const isExpressionPair: (terms: readonly Readonly<TSESTree.Expression>[]) => terms is readonly [TSESTree.Expression, TSESTree.Expression];
|
|
33
|
+
/**
|
|
34
|
+
* Extract a normalized nullish comparison from an expression.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getNullishComparison: ({ allowedOperators, allowTypeofComparedIdentifierForUndefined, comparedIdentifierName, expression, isGlobalUndefinedIdentifier, }: Readonly<{
|
|
37
|
+
allowedOperators?: readonly NullishComparisonOperator[];
|
|
38
|
+
allowTypeofComparedIdentifierForUndefined?: boolean;
|
|
39
|
+
comparedIdentifierName?: string;
|
|
40
|
+
expression: Readonly<TSESTree.Expression>;
|
|
41
|
+
isGlobalUndefinedIdentifier: (expression: Readonly<TSESTree.Expression>) => boolean;
|
|
42
|
+
}>) => null | NullishComparison;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=nullish-comparison.d.ts.map
|