Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow to define eslint-disable-next-line in multiple lines #15436

Merged
merged 8 commits into from Dec 29, 2021
13 changes: 13 additions & 0 deletions docs/user-guide/configuring/rules.md
Expand Up @@ -200,6 +200,13 @@ alert('foo'); /* eslint-disable-line no-alert, quotes, semi */

/* eslint-disable-next-line no-alert, quotes, semi */
alert('foo');

/* eslint-disable-next-line
no-alert,
quotes,
semi
*/
alert('foo');
```

All of the above methods also work for plugin rules. For example, to disable `eslint-plugin-example`'s `rule-name` rule, combine the plugin's name (`example`) and the rule's name (`rule-name`) into `example/rule-name`:
Expand All @@ -214,6 +221,12 @@ Configuration comments can include descriptions to explain why the comment is ne
```js
// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
console.log('hello');

/* eslint-disable-next-line no-console --
* Here's a very long description about why this configuration is necessary
* along with some additional information
**/
console.log('hello');
```

**Note:** Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript.
Expand Down
36 changes: 20 additions & 16 deletions lib/linter/apply-disable-directives.js
Expand Up @@ -43,7 +43,7 @@ function groupByParentComment(directives) {
* Creates removal details for a set of directives within the same comment.
* @param {Directive[]} directives Unused directives to be removed.
* @param {Token} commentToken The backing Comment token.
* @returns {{ description, fix, position }[]} Details for later creation of output Problems.
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
*/
function createIndividualDirectivesRemoval(directives, commentToken) {

Expand Down Expand Up @@ -138,7 +138,7 @@ function createIndividualDirectivesRemoval(directives, commentToken) {
],
text: ""
},
position: directive.unprocessedDirective
unprocessedDirective: directive.unprocessedDirective
};
});
}
Expand All @@ -147,7 +147,7 @@ function createIndividualDirectivesRemoval(directives, commentToken) {
* Creates a description of deleting an entire unused disable comment.
* @param {Directive[]} directives Unused directives to be removed.
* @param {Token} commentToken The backing Comment token.
* @returns {{ description, fix, position }} Details for later creation of an output Problem.
* @returns {{ description, fix, unprocessedDirective }} Details for later creation of an output Problem.
*/
function createCommentRemoval(directives, commentToken) {
const { range } = commentToken;
Expand All @@ -161,14 +161,14 @@ function createCommentRemoval(directives, commentToken) {
range,
text: " "
},
position: directives[0].unprocessedDirective
unprocessedDirective: directives[0].unprocessedDirective
};
}

/**
* Parses details from directives to create output Problems.
* @param {Directive[]} allDirectives Unused directives to be removed.
* @returns {{ description, fix, position }[]} Details for later creation of output Problems.
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
*/
function processUnusedDisableDirectives(allDirectives) {
const directiveGroups = groupByParentComment(allDirectives);
Expand Down Expand Up @@ -261,17 +261,21 @@ function applyDirectives(options) {
const processed = processUnusedDisableDirectives(unusedDisableDirectivesToReport);

const unusedDisableDirectives = processed
.map(({ description, fix, position }) => ({
ruleId: null,
message: description
? `Unused eslint-disable directive (no problems were reported from ${description}).`
: "Unused eslint-disable directive (no problems were reported).",
line: position.line,
column: position.column,
severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
nodeType: null,
...options.disableFixes ? {} : { fix }
}));
.map(({ description, fix, unprocessedDirective }) => {
const { parentComment, type, line, column } = unprocessedDirective;

return {
ruleId: null,
message: description
? `Unused eslint-disable directive (no problems were reported from ${description}).`
: "Unused eslint-disable directive (no problems were reported).",
line: type === "disable-next-line" ? parentComment.commentToken.loc.start.line : line,
column: type === "disable-next-line" ? parentComment.commentToken.loc.start.column + 1 : column,
mdjermanovic marked this conversation as resolved.
Show resolved Hide resolved
severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
nodeType: null,
...options.disableFixes ? {} : { fix }
};
});

return { problems, unusedDisableDirectives };
}
Expand Down
8 changes: 6 additions & 2 deletions lib/linter/linter.js
Expand Up @@ -305,7 +305,11 @@ function createDisableDirectives(options) {

// push to directives, if the rule is defined(including null, e.g. /*eslint enable*/)
if (ruleId === null || !!ruleMapper(ruleId)) {
result.directives.push({ parentComment, type, line: commentToken.loc.start.line, column: commentToken.loc.start.column + 1, ruleId });
if (type === "disable-next-line") {
result.directives.push({ parentComment, type, line: commentToken.loc.end.line, column: commentToken.loc.end.column + 1, ruleId });
snitin315 marked this conversation as resolved.
Show resolved Hide resolved
} else {
result.directives.push({ parentComment, type, line: commentToken.loc.start.line, column: commentToken.loc.start.column + 1, ruleId });
}
} else {
result.directiveProblems.push(createLintingProblem({ ruleId, loc: commentToken.loc }));
}
Expand Down Expand Up @@ -369,7 +373,7 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) {
return;
}

if (lineCommentSupported && comment.loc.start.line !== comment.loc.end.line) {
if (directiveText === "eslint-disable-line" && comment.loc.start.line !== comment.loc.end.line) {
const message = `${directiveText} comment should not span multiple lines.`;

problems.push(createLintingProblem({
Expand Down
19 changes: 16 additions & 3 deletions tests/lib/linter/apply-disable-directives.js
Expand Up @@ -25,7 +25,20 @@ const applyDisableDirectives = require("../../../lib/linter/apply-disable-direct
*/
function createParentComment(range, value, ruleIds = []) {
return {
commentToken: { range, value },
commentToken: {
range,
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: value ? value.length : 10
}
},
value
},
ruleIds
};
}
Expand Down Expand Up @@ -1294,7 +1307,7 @@ describe("apply-disable-directives", () => {
parentComment: createParentComment([0, 27]),
type: "disable-next-line",
line: 1,
column: 1,
column: 2,
ruleId: null
}],
problems: [],
Expand All @@ -1305,7 +1318,7 @@ describe("apply-disable-directives", () => {
ruleId: null,
message: "Unused eslint-disable directive (no problems were reported).",
line: 1,
column: 1,
column: 2,
fix: {
range: [0, 27],
text: " "
Expand Down