Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9d4216d

Browse filesBrowse files
nzakasfasttime
andauthored
chore: Refactor and document CodePathSegment (#17474)
* chore: Refactor and document CodePathSegment * Update lib/linter/code-path-analysis/code-path-segment.js Co-authored-by: Francesco Trotta <github@fasttime.org> * Remove unneeded array --------- Co-authored-by: Francesco Trotta <github@fasttime.org>
1 parent cab21e6 commit 9d4216d
Copy full SHA for 9d4216d

File tree

Expand file treeCollapse file tree

1 file changed

+52
-24
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+52
-24
lines changed
Open diff view settings
Collapse file

‎lib/linter/code-path-analysis/code-path-segment.js‎

Copy file name to clipboardExpand all lines: lib/linter/code-path-analysis/code-path-segment.js
+52-24Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @fileoverview A class of the code path segment.
2+
* @fileoverview The CodePathSegment class.
33
* @author Toru Nagashima
44
*/
55

@@ -30,10 +30,22 @@ function isReachable(segment) {
3030

3131
/**
3232
* A code path segment.
33+
*
34+
* Each segment is arranged in a series of linked lists (implemented by arrays)
35+
* that keep track of the previous and next segments in a code path. In this way,
36+
* you can navigate between all segments in any code path so long as you have a
37+
* reference to any segment in that code path.
38+
*
39+
* When first created, the segment is in a detached state, meaning that it knows the
40+
* segments that came before it but those segments don't know that this new segment
41+
* follows it. Only when `CodePathSegment#markUsed()` is called on a segment does it
42+
* officially become part of the code path by updating the previous segments to know
43+
* that this new segment follows.
3344
*/
3445
class CodePathSegment {
3546

3647
/**
48+
* Creates a new instance.
3749
* @param {string} id An identifier.
3850
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
3951
* This array includes unreachable segments.
@@ -49,27 +61,25 @@ class CodePathSegment {
4961
this.id = id;
5062

5163
/**
52-
* An array of the next segments.
64+
* An array of the next reachable segments.
5365
* @type {CodePathSegment[]}
5466
*/
5567
this.nextSegments = [];
5668

5769
/**
58-
* An array of the previous segments.
70+
* An array of the previous reachable segments.
5971
* @type {CodePathSegment[]}
6072
*/
6173
this.prevSegments = allPrevSegments.filter(isReachable);
6274

6375
/**
64-
* An array of the next segments.
65-
* This array includes unreachable segments.
76+
* An array of all next segments including reachable and unreachable.
6677
* @type {CodePathSegment[]}
6778
*/
6879
this.allNextSegments = [];
6980

7081
/**
71-
* An array of the previous segments.
72-
* This array includes unreachable segments.
82+
* An array of all previous segments including reachable and unreachable.
7383
* @type {CodePathSegment[]}
7484
*/
7585
this.allPrevSegments = allPrevSegments;
@@ -83,7 +93,11 @@ class CodePathSegment {
8393
// Internal data.
8494
Object.defineProperty(this, "internal", {
8595
value: {
96+
97+
// determines if the segment has been attached to the code path
8698
used: false,
99+
100+
// array of previous segments coming from the end of a loop
87101
loopedPrevSegments: []
88102
}
89103
});
@@ -113,9 +127,10 @@ class CodePathSegment {
113127
}
114128

115129
/**
116-
* Creates a segment that follows given segments.
130+
* Creates a new segment and appends it after the given segments.
117131
* @param {string} id An identifier.
118-
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
132+
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments
133+
* to append to.
119134
* @returns {CodePathSegment} The created segment.
120135
*/
121136
static newNext(id, allPrevSegments) {
@@ -127,7 +142,7 @@ class CodePathSegment {
127142
}
128143

129144
/**
130-
* Creates an unreachable segment that follows given segments.
145+
* Creates an unreachable segment and appends it after the given segments.
131146
* @param {string} id An identifier.
132147
* @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
133148
* @returns {CodePathSegment} The created segment.
@@ -137,7 +152,7 @@ class CodePathSegment {
137152

138153
/*
139154
* In `if (a) return a; foo();` case, the unreachable segment preceded by
140-
* the return statement is not used but must not be remove.
155+
* the return statement is not used but must not be removed.
141156
*/
142157
CodePathSegment.markUsed(segment);
143158

@@ -157,7 +172,7 @@ class CodePathSegment {
157172
}
158173

159174
/**
160-
* Makes a given segment being used.
175+
* Marks a given segment as used.
161176
*
162177
* And this function registers the segment into the previous segments as a next.
163178
* @param {CodePathSegment} segment A segment to mark.
@@ -172,13 +187,27 @@ class CodePathSegment {
172187
let i;
173188

174189
if (segment.reachable) {
190+
191+
/*
192+
* If the segment is reachable, then it's officially part of the
193+
* code path. This loops through all previous segments to update
194+
* their list of next segments. Because the segment is reachable,
195+
* it's added to both `nextSegments` and `allNextSegments`.
196+
*/
175197
for (i = 0; i < segment.allPrevSegments.length; ++i) {
176198
const prevSegment = segment.allPrevSegments[i];
177199

178200
prevSegment.allNextSegments.push(segment);
179201
prevSegment.nextSegments.push(segment);
180202
}
181203
} else {
204+
205+
/*
206+
* If the segment is not reachable, then it's not officially part of the
207+
* code path. This loops through all previous segments to update
208+
* their list of next segments. Because the segment is not reachable,
209+
* it's added only to `allNextSegments`.
210+
*/
182211
for (i = 0; i < segment.allPrevSegments.length; ++i) {
183212
segment.allPrevSegments[i].allNextSegments.push(segment);
184213
}
@@ -196,19 +225,20 @@ class CodePathSegment {
196225
}
197226

198227
/**
199-
* Replaces unused segments with the previous segments of each unused segment.
200-
* @param {CodePathSegment[]} segments An array of segments to replace.
201-
* @returns {CodePathSegment[]} The replaced array.
228+
* Creates a new array based on an array of segments. If any segment in the
229+
* array is unused, then it is replaced by all of its previous segments.
230+
* All used segments are returned as-is without replacement.
231+
* @param {CodePathSegment[]} segments The array of segments to flatten.
232+
* @returns {CodePathSegment[]} The flattened array.
202233
*/
203234
static flattenUnusedSegments(segments) {
204-
const done = Object.create(null);
205-
const retv = [];
235+
const done = new Set();
206236

207237
for (let i = 0; i < segments.length; ++i) {
208238
const segment = segments[i];
209239

210240
// Ignores duplicated.
211-
if (done[segment.id]) {
241+
if (done.has(segment)) {
212242
continue;
213243
}
214244

@@ -217,18 +247,16 @@ class CodePathSegment {
217247
for (let j = 0; j < segment.allPrevSegments.length; ++j) {
218248
const prevSegment = segment.allPrevSegments[j];
219249

220-
if (!done[prevSegment.id]) {
221-
done[prevSegment.id] = true;
222-
retv.push(prevSegment);
250+
if (!done.has(prevSegment)) {
251+
done.add(prevSegment);
223252
}
224253
}
225254
} else {
226-
done[segment.id] = true;
227-
retv.push(segment);
255+
done.add(segment);
228256
}
229257
}
230258

231-
return retv;
259+
return [...done];
232260
}
233261
}
234262

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.