Skip to content

Commit 063d140

Browse files
committed
fix: Add types for "process-exit-as-throw"
1 parent a408ba4 commit 063d140

8 files changed

+1346
-8
lines changed

lib/rules/process-exit-as-throw.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@
55
*/
66
"use strict"
77

8+
/** @type {typeof import('../types-code-path-analysis/code-path-analyzer.js')} */
89
const CodePathAnalyzer = safeRequire(
910
"eslint/lib/linter/code-path-analysis/code-path-analyzer",
1011
"eslint/lib/code-path-analysis/code-path-analyzer"
1112
)
13+
/** @type {typeof import('../types-code-path-analysis/code-path-segment.js')} */
1214
const CodePathSegment = safeRequire(
1315
"eslint/lib/linter/code-path-analysis/code-path-segment",
1416
"eslint/lib/code-path-analysis/code-path-segment"
1517
)
18+
/** @type {typeof import('../types-code-path-analysis/code-path.js')} */
1619
const CodePath = safeRequire(
1720
"eslint/lib/linter/code-path-analysis/code-path",
1821
"eslint/lib/code-path-analysis/code-path"
1922
)
2023

21-
const originalLeaveNode =
22-
CodePathAnalyzer && CodePathAnalyzer.prototype.leaveNode
24+
const originalLeaveNode = CodePathAnalyzer?.prototype?.leaveNode
2325

2426
/**
2527
* Imports a specific module.
2628
* @param {...string} moduleNames - module names to import.
27-
* @returns {object|null} The imported object, or null.
29+
* @returns {*} The imported object, or null.
2830
*/
2931
function safeRequire(...moduleNames) {
3032
for (const moduleName of moduleNames) {
@@ -41,8 +43,8 @@ function safeRequire(...moduleNames) {
4143
/**
4244
* Copied from https://github.com/eslint/eslint/blob/16fad5880bb70e9dddbeab8ed0f425ae51f5841f/lib/code-path-analysis/code-path-analyzer.js#L137
4345
*
44-
* @param {CodePathAnalyzer} analyzer - The instance.
45-
* @param {ASTNode} node - The current AST node.
46+
* @param {import('../types-code-path-analysis/code-path-analyzer.js')} analyzer - The instance.
47+
* @param {import('eslint').Rule.Node} node - The current AST node.
4648
* @returns {void}
4749
*/
4850
function forwardCurrentToHead(analyzer, node) {
@@ -95,7 +97,7 @@ function forwardCurrentToHead(analyzer, node) {
9597
/**
9698
* Checks whether a given node is `process.exit()` or not.
9799
*
98-
* @param {ASTNode} node - A node to check.
100+
* @param {import('eslint').Rule.Node} node - A node to check.
99101
* @returns {boolean} `true` if the node is `process.exit()`.
100102
*/
101103
function isProcessExit(node) {
@@ -114,8 +116,8 @@ function isProcessExit(node) {
114116
* The function to override `CodePathAnalyzer.prototype.leaveNode` in order to
115117
* address `process.exit()` as throw.
116118
*
117-
* @this CodePathAnalyzer
118-
* @param {ASTNode} node - A node to be left.
119+
* @this {import('../types-code-path-analysis/code-path-analyzer.js')}
120+
* @param {import('eslint').Rule.Node} node - A node to be left.
119121
* @returns {void}
120122
*/
121123
function overrideLeaveNode(node) {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export = CodePathAnalyzer;
2+
3+
interface EventGenerator {
4+
emitter: import('node:events').EventEmitter;
5+
enterNode(node: import('eslint').Rule.Node): void;
6+
leaveNode(node: import('eslint').Rule.Node): void;
7+
}
8+
9+
/**
10+
* The class to analyze code paths.
11+
* This class implements the EventGenerator interface.
12+
*/
13+
declare class CodePathAnalyzer {
14+
/**
15+
* @param {EventGenerator} eventGenerator An event generator to wrap.
16+
*/
17+
constructor(eventGenerator: EventGenerator);
18+
original: EventGenerator;
19+
emitter: any;
20+
codePath: any;
21+
idGenerator: IdGenerator;
22+
currentNode: any;
23+
/**
24+
* This is called on a code path looped.
25+
* Then this raises a looped event.
26+
* @param {CodePathSegment} fromSegment A segment of prev.
27+
* @param {CodePathSegment} toSegment A segment of next.
28+
* @returns {void}
29+
*/
30+
onLooped(fromSegment: CodePathSegment, toSegment: CodePathSegment): void;
31+
/**
32+
* Does the process to enter a given AST node.
33+
* This updates state of analysis and calls `enterNode` of the wrapped.
34+
* @param {ASTNode} node A node which is entering.
35+
* @returns {void}
36+
*/
37+
enterNode(node: import('eslint').Rule.Node): void;
38+
/**
39+
* Does the process to leave a given AST node.
40+
* This updates state of analysis and calls `leaveNode` of the wrapped.
41+
* @param {ASTNode} node A node which is leaving.
42+
* @returns {void}
43+
*/
44+
leaveNode(node: import('eslint').Rule.Node): void;
45+
}
46+
import IdGenerator = require("./id-generator");
47+
import CodePathSegment = require("./code-path-segment");
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
export = CodePathSegment;
2+
/**
3+
* A code path segment.
4+
*
5+
* Each segment is arranged in a series of linked lists (implemented by arrays)
6+
* that keep track of the previous and next segments in a code path. In this way,
7+
* you can navigate between all segments in any code path so long as you have a
8+
* reference to any segment in that code path.
9+
*
10+
* When first created, the segment is in a detached state, meaning that it knows the
11+
* segments that came before it but those segments don't know that this new segment
12+
* follows it. Only when `CodePathSegment#markUsed()` is called on a segment does it
13+
* officially become part of the code path by updating the previous segments to know
14+
* that this new segment follows.
15+
*/
16+
declare class CodePathSegment {
17+
/**
18+
* Creates the root segment.
19+
* @param {string} id An identifier.
20+
* @returns {CodePathSegment} The created segment.
21+
*/
22+
static newRoot(id: string): CodePathSegment;
23+
/**
24+
* Creates a new segment and appends it after the given segments.
25+
* @param {string} id An identifier.
26+
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments
27+
* to append to.
28+
* @returns {CodePathSegment} The created segment.
29+
*/
30+
static newNext(id: string, allPrevSegments: CodePathSegment[]): CodePathSegment;
31+
/**
32+
* Creates an unreachable segment and appends it after the given segments.
33+
* @param {string} id An identifier.
34+
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
35+
* @returns {CodePathSegment} The created segment.
36+
*/
37+
static newUnreachable(id: string, allPrevSegments: CodePathSegment[]): CodePathSegment;
38+
/**
39+
* Creates a segment that follows given segments.
40+
* This factory method does not connect with `allPrevSegments`.
41+
* But this inherits `reachable` flag.
42+
* @param {string} id An identifier.
43+
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
44+
* @returns {CodePathSegment} The created segment.
45+
*/
46+
static newDisconnected(id: string, allPrevSegments: CodePathSegment[]): CodePathSegment;
47+
/**
48+
* Marks a given segment as used.
49+
*
50+
* And this function registers the segment into the previous segments as a next.
51+
* @param {CodePathSegment} segment A segment to mark.
52+
* @returns {void}
53+
*/
54+
static markUsed(segment: CodePathSegment): void;
55+
/**
56+
* Marks a previous segment as looped.
57+
* @param {CodePathSegment} segment A segment.
58+
* @param {CodePathSegment} prevSegment A previous segment to mark.
59+
* @returns {void}
60+
*/
61+
static markPrevSegmentAsLooped(segment: CodePathSegment, prevSegment: CodePathSegment): void;
62+
/**
63+
* Creates a new array based on an array of segments. If any segment in the
64+
* array is unused, then it is replaced by all of its previous segments.
65+
* All used segments are returned as-is without replacement.
66+
* @param {CodePathSegment[]} segments The array of segments to flatten.
67+
* @returns {CodePathSegment[]} The flattened array.
68+
*/
69+
static flattenUnusedSegments(segments: CodePathSegment[]): CodePathSegment[];
70+
/**
71+
* Creates a new instance.
72+
* @param {string} id An identifier.
73+
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
74+
* This array includes unreachable segments.
75+
* @param {boolean} reachable A flag which shows this is reachable.
76+
*/
77+
constructor(id: string, allPrevSegments: CodePathSegment[], reachable: boolean);
78+
/**
79+
* The identifier of this code path.
80+
* Rules use it to store additional information of each rule.
81+
* @type {string}
82+
*/
83+
id: string;
84+
/**
85+
* An array of the next reachable segments.
86+
* @type {CodePathSegment[]}
87+
*/
88+
nextSegments: CodePathSegment[];
89+
/**
90+
* An array of the previous reachable segments.
91+
* @type {CodePathSegment[]}
92+
*/
93+
prevSegments: CodePathSegment[];
94+
/**
95+
* An array of all next segments including reachable and unreachable.
96+
* @type {CodePathSegment[]}
97+
*/
98+
allNextSegments: CodePathSegment[];
99+
/**
100+
* An array of all previous segments including reachable and unreachable.
101+
* @type {CodePathSegment[]}
102+
*/
103+
allPrevSegments: CodePathSegment[];
104+
/**
105+
* A flag which shows this is reachable.
106+
* @type {boolean}
107+
*/
108+
reachable: boolean;
109+
/**
110+
* Checks a given previous segment is coming from the end of a loop.
111+
* @param {CodePathSegment} segment A previous segment to check.
112+
* @returns {boolean} `true` if the segment is coming from the end of a loop.
113+
*/
114+
isLoopedPrevSegment(segment: CodePathSegment): boolean;
115+
}

0 commit comments

Comments
 (0)