Skip to content

Commit

Permalink
Support multi-line disable descriptions (#4895)
Browse files Browse the repository at this point in the history
  • Loading branch information
jathak committed Aug 17, 2020
1 parent 03f494d commit 40e60ce
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,8 @@ All notable changes to this project are documented in this file.
- Fixed: inconsistent trailing newlines in CLI error output ([#4876](https://github.com/stylelint/stylelint/pull/4876)).
- Fixed: `selector-max-*` (except `selector-max-type`) false negatives for `where`, `is`, `nth-child` and `nth-last-child` ([#4842](https://github.com/stylelint/stylelint/pull/4842)).
- Fixed: `length-zero-no-unit` TypeError for custom properties fallback ([#4860](https://github.com/stylelint/stylelint/pull/4860)).
- Fixed: false negatives for `where`, `is`, `nth-child` and `nth-last-child` in `selector-max-*` rules (except selector-max-type) ([#4842](https://github.com/stylelint/stylelint/pull/4842)).
- Fixed: support for multi-line disable descriptions ([#4895](https://github.com/stylelint/stylelint/pull/4895)).

## 13.6.1

Expand Down
52 changes: 52 additions & 0 deletions lib/__tests__/disableRanges.test.js
Expand Up @@ -747,6 +747,32 @@ it('SCSS // line-disabling comment (with description)', () => {
});
});

it('SCSS // disable next-line comment (with multi-line description)', () => {
const scssSource = `a {
// stylelint-disable-next-line declaration-no-important
// --
// Long-winded description
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 5,
end: 5,
strictStart: true,
strictEnd: true,
},
],
});
});
});

it('Less // line-disabling comment (with description)', () => {
const lessSource = `a {
color: pink !important; // stylelint-disable-line declaration-no-important -- Description
Expand All @@ -770,6 +796,32 @@ it('Less // line-disabling comment (with description)', () => {
});
});

it('Less // disable next-line comment (with multi-line description)', () => {
const lessSource = `a {
// stylelint-disable-next-line declaration-no-important
// --
// Long-winded description
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(lessSource, { syntax: less, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 5,
end: 5,
strictStart: true,
strictEnd: true,
},
],
});
});
});

function testDisableRanges(source, cb) {
return postcss().use(assignDisabledRanges).process(source, { from: undefined }).then(cb);
}
51 changes: 47 additions & 4 deletions lib/assignDisabledRanges.js
Expand Up @@ -9,7 +9,7 @@ const disableLineCommand = `${COMMAND_PREFIX}disable-line`;
const disableNextLineCommand = `${COMMAND_PREFIX}disable-next-line`;
const ALL_RULES = 'all';

/** @typedef {import('postcss').Comment} PostcssComment */
/** @typedef {import('postcss/lib/comment')} PostcssComment */
/** @typedef {import('postcss').Root} PostcssRoot */
/** @typedef {import('stylelint').PostcssResult} PostcssResult */
/** @typedef {import('stylelint').DisabledRangeObject} DisabledRangeObject */
Expand Down Expand Up @@ -53,10 +53,53 @@ module.exports = function (root, result) {
};

result.stylelint.disabledRanges = disabledRanges;
root.walkComments(checkComment);

// Work around postcss/postcss-scss#109 by merging adjacent `//` comments
// into a single node before passing to `checkComment`.

/** @type {PostcssComment?} */
let inlineEnd;

root.walkComments((/** @type {PostcssComment} */ comment) => {
if (inlineEnd) {
// Ignore comments already processed by grouping with a previous one.
if (inlineEnd === comment) inlineEnd = null;
} else if (isInlineComment(comment)) {
const fullComment = comment.clone();
let next = comment.next();

while (next && next.type === 'comment') {
/** @type {PostcssComment} */
const current = next;

if (!isInlineComment(current)) break;

fullComment.text += `\n${current.text}`;

if (fullComment.source && current.source) {
fullComment.source.end = current.source.end;
}

inlineEnd = current;
next = current.next();
}
checkComment(fullComment);
} else {
checkComment(comment);
}
});

return result;

/**
* @param {PostcssComment} comment
*/
function isInlineComment(comment) {
// We check both here because the Sass parser uses `raws.inline` to indicate
// inline comments, while the Less parser uses `inline`.
return comment.inline || comment.raws.inline;
}

/**
* @param {PostcssComment} comment
*/
Expand All @@ -74,8 +117,8 @@ module.exports = function (root, result) {
* @param {PostcssComment} comment
*/
function processDisableNextLineCommand(comment) {
if (comment.source && comment.source.start) {
const line = comment.source.start.line;
if (comment.source && comment.source.end) {
const line = comment.source.end.line;

getCommandRules(disableNextLineCommand, comment.text).forEach((ruleName) => {
disableLine(line + 1, ruleName, comment);
Expand Down
17 changes: 17 additions & 0 deletions types/postcss/index.d.ts
@@ -1,3 +1,20 @@
declare module 'postcss/lib/comment' {
import { Comment, NodeRaws } from 'postcss';

interface NodeRawsExt extends NodeRaws {
// Used by the SCSS parser to indicate `//` comments.
inline?: boolean;
}

interface CommentExt extends Comment {
// Used by the Less parser to indicate `//` comments.
inline?: boolean;
raws: NodeRawsExt;
}

export = CommentExt;
}

declare module 'postcss/lib/lazy-result' {
import {
LazyResult,
Expand Down

0 comments on commit 40e60ce

Please sign in to comment.