Skip to content

Commit 2b04f84

Browse files
authored
Fix crash, false-positive in no-statement-after-end (#316)
1 parent 895d215 commit 2b04f84

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

rules/no-statement-after-end.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,19 @@ const create = context => {
2121

2222
let currentSegmentInfo;
2323

24+
function pathStart() {
25+
if (currentSegmentInfo !== undefined) {
26+
segmentInfoStack.push(currentSegmentInfo);
27+
currentSegmentInfo = undefined;
28+
}
29+
}
30+
31+
function pathEnd() {
32+
currentSegmentInfo = segmentInfoStack.pop();
33+
}
34+
2435
function segmentStart(segment) {
2536
// A new CodePathSegment has started, create an "info" object to track this segments state.
26-
segmentInfoStack.push(currentSegmentInfo);
27-
2837
currentSegmentInfo = {
2938
ended: false,
3039
prev: segment.prevSegments.map(previousSegment => segmentInfoMap.get(previousSegment.id))
@@ -34,12 +43,14 @@ const create = context => {
3443
}
3544

3645
function segmentEnd() {
37-
currentSegmentInfo = segmentInfoStack.pop();
46+
currentSegmentInfo = undefined;
3847
}
3948

4049
function checkForEndExpression(node) {
4150
if (isEndExpression(node)) {
42-
currentSegmentInfo.ended = true;
51+
if (currentSegmentInfo !== undefined) {
52+
currentSegmentInfo.ended = true;
53+
}
4354
}
4455
}
4556

@@ -48,6 +59,12 @@ const create = context => {
4859
return;
4960
}
5061

62+
// If there is no current segment (this occurs in unreachable code), then we
63+
// can't check whether `t.end()` was called
64+
if (currentSegmentInfo === undefined) {
65+
return;
66+
}
67+
5168
const ended = [currentSegmentInfo]
5269
.concat(currentSegmentInfo.prev)
5370
.filter(info => info.ended);
@@ -85,6 +102,8 @@ const create = context => {
85102
checkStatement(node);
86103
}
87104
},
105+
onCodePathStart: pathStart,
106+
onCodePathEnd: pathEnd,
88107
onCodePathSegmentStart: segmentStart,
89108
onCodePathSegmentEnd: segmentEnd,
90109
CallExpression: checkForEndExpression

test/no-statement-after-end.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,22 @@ ruleTester.run('no-statement-after-end', rule, {
3030
cbTest('return t.end();'),
3131
cbTest('t.end(); return;'),
3232
// Valid because it is not a test file (no header)
33-
cbTest('t.end(); t.is(1, 1);', false)
33+
cbTest('t.end(); t.is(1, 1);', false),
34+
`
35+
const test = require('ava');
36+
37+
throw new Error();
38+
39+
1;
40+
`,
41+
cbTest(`
42+
function newCodePath() {
43+
throw new Error('make some unreachable code');
44+
t.end();
45+
}
46+
47+
1;
48+
`)
3449
],
3550
invalid: [
3651
{
@@ -48,6 +63,20 @@ ruleTester.run('no-statement-after-end', rule, {
4863
{
4964
code: cbTest('if (t.context.a === 1) { t.end(); }\nt.is(1, 1); t.end();'),
5065
errors
66+
},
67+
{
68+
code: cbTest(`
69+
function newCodePath() {
70+
// ...
71+
}
72+
t.end();
73+
1;
74+
`),
75+
errors
76+
},
77+
{
78+
code: cbTest('t.end(); function newCodePath() {} 1;'),
79+
errors
5180
}
5281
]
5382
});

0 commit comments

Comments
 (0)