+++ /dev/null
-"use strict";
-
-const addEmptyLineBefore = require("../../utils/addEmptyLineBefore");
-const getPreviousNonSharedLineCommentNode = require("../../utils/getPreviousNonSharedLineCommentNode");
-const hasEmptyLine = require("../../utils/hasEmptyLine");
-const isAfterSingleLineComment = require("../../utils/isAfterSingleLineComment");
-const isFirstNested = require("../../utils/isFirstNested");
-const isFirstNodeOfRoot = require("../../utils/isFirstNodeOfRoot");
-const isSingleLineString = require("../../utils/isSingleLineString");
-const isStandardSyntaxRule = require("../../utils/isStandardSyntaxRule");
-const optionsMatches = require("../../utils/optionsMatches");
-const removeEmptyLinesBefore = require("../../utils/removeEmptyLinesBefore");
-const report = require("../../utils/report");
-const ruleMessages = require("../../utils/ruleMessages");
-const validateOptions = require("../../utils/validateOptions");
-
-const ruleName = "rule-empty-line-before";
-
-const messages = ruleMessages(ruleName, {
- expected: "Expected empty line before rule",
- rejected: "Unexpected empty line before rule"
-});
-
-const rule = function(expectation, options, context) {
- return (root, result) => {
- const validOptions = validateOptions(
- result,
- ruleName,
- {
- actual: expectation,
- possible: ["always", "never", "always-multi-line", "never-multi-line"]
- },
- {
- actual: options,
- possible: {
- ignore: ["after-comment", "inside-block"],
- except: [
- "after-rule",
- "after-single-line-comment",
- "first-nested",
- "inside-block-and-after-rule",
- "inside-block"
- ]
- },
- optional: true
- }
- );
-
- if (!validOptions) {
- return;
- }
-
- root.walkRules(rule => {
- if (!isStandardSyntaxRule(rule)) {
- return;
- }
-
- // Ignore the first node
- if (isFirstNodeOfRoot(rule)) {
- return;
- }
-
- // Optionally ignore the expectation if a comment precedes this node
- if (
- optionsMatches(options, "ignore", "after-comment") &&
- rule.prev() &&
- rule.prev().type === "comment"
- ) {
- return;
- }
-
- const isNested = rule.parent.type !== "root";
-
- // Optionally ignore the expectation if inside a block
- if (optionsMatches(options, "ignore", "inside-block") && isNested) {
- return;
- }
-
- // Ignore if the expectation is for multiple and the rule is single-line
- if (
- expectation.indexOf("multi-line") !== -1 &&
- isSingleLineString(rule.toString())
- ) {
- return;
- }
-
- let expectEmptyLineBefore =
- expectation.indexOf("always") !== -1 ? true : false;
-
- // Optionally reverse the expectation if any exceptions apply
- if (
- (optionsMatches(options, "except", "first-nested") &&
- isFirstNested(rule)) ||
- (optionsMatches(options, "except", "after-rule") &&
- isAfterRule(rule)) ||
- (optionsMatches(options, "except", "inside-block-and-after-rule") &&
- isNested &&
- isAfterRule(rule)) ||
- (optionsMatches(options, "except", "after-single-line-comment") &&
- isAfterSingleLineComment(rule)) ||
- (optionsMatches(options, "except", "inside-block") && isNested)
- ) {
- expectEmptyLineBefore = !expectEmptyLineBefore;
- }
-
- const hasEmptyLineBefore = hasEmptyLine(rule.raws.before);
-
- // Return if the expectation is met
- if (expectEmptyLineBefore === hasEmptyLineBefore) {
- return;
- }
-
- // Fix
- if (context.fix) {
- if (expectEmptyLineBefore) {
- addEmptyLineBefore(rule, context.newline);
- } else {
- removeEmptyLinesBefore(rule, context.newline);
- }
-
- return;
- }
-
- const message = expectEmptyLineBefore
- ? messages.expected
- : messages.rejected;
-
- report({
- message,
- node: rule,
- result,
- ruleName
- });
- });
- };
-};
-
-function isAfterRule(rule) {
- const prevNode = getPreviousNonSharedLineCommentNode(rule);
- return prevNode && prevNode.type === "rule";
-}
-
-rule.ruleName = ruleName;
-rule.messages = messages;
-module.exports = rule;