Skip to content

Commit c6cb40b

Browse files
committed
Fix: no-unused-disable crashes if a code has parse error
1 parent 7f4ffbb commit c6cb40b

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

lib/patch.js

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,33 @@ function getSeverity(config, ruleId) {
3434
}
3535
}
3636

37+
/**
38+
* Get the comment which is at a given message location.
39+
* @param {Message} message The message to get.
40+
* @param {SourceCode|undefined} sourceCode The source code object to get.
41+
* @returns {Comment|undefined} The gotten comment.
42+
*/
43+
function getCommentAt(message, sourceCode) {
44+
if (sourceCode == null) {
45+
return undefined
46+
}
47+
48+
const index = sourceCode.getIndexFromLoc(message) - 1
49+
return sourceCode.getTokenByRangeStart(index, { includeComments: true })
50+
}
51+
3752
/**
3853
* Check whether a given message is a `reportUnusedDisableDirectives` error.
3954
* @param {Message} message The message.
40-
* @param {Comment} comment The comment which existed at the message location.
55+
* @param {Comment|undefined} comment The comment which existed at the message location.
4156
* @returns {boolean} `true` if the message is a `reportUnusedDisableDirectives` error.
4257
*/
4358
function isUnusedDisableDirectiveError(message, comment) {
4459
return (
4560
!message.fatal &&
4661
!message.ruleId &&
4762
message.message.includes("eslint-disable") &&
48-
comment != null &&
49-
(comment.type === "Block" || comment.type === "Line")
63+
(comment == null || comment.type === "Block" || comment.type === "Line")
5064
)
5165
}
5266

@@ -55,7 +69,7 @@ function isUnusedDisableDirectiveError(message, comment) {
5569
* @param {string} ruleId The ruleId.
5670
* @param {number} severity The severity of the rule.
5771
* @param {Message} message The original message.
58-
* @param {Comment} comment The directive comment.
72+
* @param {Comment|undefined} comment The directive comment.
5973
* @returns {Message} The created error.
6074
*/
6175
function createNoUnusedDisableError(ruleId, severity, message, comment) {
@@ -69,15 +83,17 @@ function createNoUnusedDisableError(ruleId, severity, message, comment) {
6983
? `'${targetRuleId}' rule is disabled but never reported.`
7084
: "ESLint rules are disabled but never reported."
7185

72-
if (targetRuleId) {
73-
const loc = toRuleIdLocation(comment, targetRuleId)
74-
clone.line = loc.start.line
75-
clone.column = loc.start.column + 1
76-
clone.endLine = loc.end.line
77-
clone.endColumn = loc.end.column + 1
78-
} else {
79-
clone.endLine = comment.loc.end.line
80-
clone.endColumn = comment.loc.end.column + 1
86+
if (comment != null) {
87+
if (targetRuleId) {
88+
const loc = toRuleIdLocation(comment, targetRuleId)
89+
clone.line = loc.start.line
90+
clone.column = loc.start.column + 1
91+
clone.endLine = loc.end.line
92+
clone.endColumn = loc.end.column + 1
93+
} else {
94+
clone.endLine = comment.loc.end.line
95+
clone.endColumn = comment.loc.end.column + 1
96+
}
8197
}
8298

8399
return clone
@@ -86,7 +102,7 @@ function createNoUnusedDisableError(ruleId, severity, message, comment) {
86102
/**
87103
* Convert `reportUnusedDisableDirectives` errors to `eslint-comments/no-unused-disable` errors.
88104
* @param {Message[]} messages The original messages.
89-
* @param {SourceCode} sourceCode The source code object.
105+
* @param {SourceCode|undefined} sourceCode The source code object.
90106
* @param {string} ruleId The rule ID to convert.
91107
* @param {number} severity The severity of the rule.
92108
* @param {boolean} keepAsIs The flag to keep original errors as is.
@@ -95,10 +111,8 @@ function createNoUnusedDisableError(ruleId, severity, message, comment) {
95111
function convert(messages, sourceCode, ruleId, severity, keepAsIs) {
96112
for (let i = messages.length - 1; i >= 0; --i) {
97113
const message = messages[i]
98-
const rangeStart = sourceCode.getIndexFromLoc(message) - 1
99-
const comment = sourceCode.getTokenByRangeStart(rangeStart, {
100-
includeComments: true,
101-
})
114+
const comment = getCommentAt(message, sourceCode)
115+
102116
if (!isUnusedDisableDirectiveError(message, comment)) {
103117
continue
104118
}

tests/lib/rules/no-unused-disable.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,17 @@ var a = b //eslint-disable-line no-undef`,
475475
],
476476
reportUnusedDisableDirectives: true,
477477
},
478+
479+
// Don't crash even if the source code has a parse error.
480+
{
481+
code:
482+
"/*eslint no-undef:error*/\nvar a = b c //eslint-disable-line no-undef",
483+
errors: [
484+
{
485+
message: "Parsing error: Unexpected token c",
486+
},
487+
],
488+
},
478489
]) {
479490
it(code, () =>
480491
runESLint(code, reportUnusedDisableDirectives).then(

0 commit comments

Comments
 (0)