Skip to content

Commit

Permalink
Refactor to improve types for rule-empty-line-before rule (#5834)
Browse files Browse the repository at this point in the history
  • Loading branch information
ybiquitous committed Jan 17, 2022
1 parent 76fb420 commit 7af4b10
Showing 1 changed file with 35 additions and 24 deletions.
59 changes: 35 additions & 24 deletions lib/rules/rule-empty-line-before/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @ts-nocheck

'use strict';

const addEmptyLineBefore = require('../../utils/addEmptyLineBefore');
Expand All @@ -23,17 +21,18 @@ const messages = ruleMessages(ruleName, {
rejected: 'Unexpected empty line before rule',
});

function rule(expectation, options, context) {
/** @type {import('stylelint').Rule} */
const rule = (primary, secondaryOptions, context) => {
return (root, result) => {
const validOptions = validateOptions(
result,
ruleName,
{
actual: expectation,
actual: primary,
possible: ['always', 'never', 'always-multi-line', 'never-multi-line'],
},
{
actual: options,
actual: secondaryOptions,
possible: {
ignore: ['after-comment', 'first-nested', 'inside-block'],
except: [
Expand All @@ -52,6 +51,8 @@ function rule(expectation, options, context) {
return;
}

const expectation = /** @type {string} */ (primary);

root.walkRules((ruleNode) => {
if (!isStandardSyntaxRule(ruleNode)) {
return;
Expand All @@ -63,23 +64,23 @@ function rule(expectation, options, context) {
}

// Optionally ignore the expectation if a comment precedes this node
if (
optionsMatches(options, 'ignore', 'after-comment') &&
ruleNode.prev() &&
ruleNode.prev().type === 'comment'
) {
return;
if (optionsMatches(secondaryOptions, 'ignore', 'after-comment')) {
const prevNode = ruleNode.prev();

if (prevNode && prevNode.type === 'comment') {
return;
}
}

// Optionally ignore the node if it is the first nested
if (optionsMatches(options, 'ignore', 'first-nested') && isFirstNested(ruleNode)) {
if (optionsMatches(secondaryOptions, 'ignore', 'first-nested') && isFirstNested(ruleNode)) {
return;
}

const isNested = ruleNode.parent.type !== 'root';
const isNested = ruleNode.parent && ruleNode.parent.type !== 'root';

// Optionally ignore the expectation if inside a block
if (optionsMatches(options, 'ignore', 'inside-block') && isNested) {
if (optionsMatches(secondaryOptions, 'ignore', 'inside-block') && isNested) {
return;
}

Expand All @@ -88,18 +89,18 @@ function rule(expectation, options, context) {
return;
}

let expectEmptyLineBefore = Boolean(expectation.includes('always'));
let expectEmptyLineBefore = expectation.includes('always');

// Optionally reverse the expectation if any exceptions apply
if (
(optionsMatches(options, 'except', 'first-nested') && isFirstNested(ruleNode)) ||
(optionsMatches(options, 'except', 'after-rule') && isAfterRule(ruleNode)) ||
(optionsMatches(options, 'except', 'inside-block-and-after-rule') &&
(optionsMatches(secondaryOptions, 'except', 'first-nested') && isFirstNested(ruleNode)) ||
(optionsMatches(secondaryOptions, 'except', 'after-rule') && isAfterRule(ruleNode)) ||
(optionsMatches(secondaryOptions, 'except', 'inside-block-and-after-rule') &&
isNested &&
isAfterRule(ruleNode)) ||
(optionsMatches(options, 'except', 'after-single-line-comment') &&
(optionsMatches(secondaryOptions, 'except', 'after-single-line-comment') &&
isAfterSingleLineComment(ruleNode)) ||
(optionsMatches(options, 'except', 'inside-block') && isNested)
(optionsMatches(secondaryOptions, 'except', 'inside-block') && isNested)
) {
expectEmptyLineBefore = !expectEmptyLineBefore;
}
Expand All @@ -113,10 +114,16 @@ function rule(expectation, options, context) {

// Fix
if (context.fix) {
const newline = context.newline;

if (typeof newline !== 'string') {
throw new Error(`The "newline" property must be a string: ${newline}`);
}

if (expectEmptyLineBefore) {
addEmptyLineBefore(ruleNode, context.newline);
addEmptyLineBefore(ruleNode, newline);
} else {
removeEmptyLinesBefore(ruleNode, context.newline);
removeEmptyLinesBefore(ruleNode, newline);
}

return;
Expand All @@ -132,12 +139,16 @@ function rule(expectation, options, context) {
});
});
};
}
};

/**
* @param {import('postcss').Rule} ruleNode
* @returns {boolean}
*/
function isAfterRule(ruleNode) {
const prevNode = getPreviousNonSharedLineCommentNode(ruleNode);

return prevNode && prevNode.type === 'rule';
return prevNode != null && prevNode.type === 'rule';
}

rule.ruleName = ruleName;
Expand Down

0 comments on commit 7af4b10

Please sign in to comment.