.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / rules / comment-empty-line-before / index.js
1 "use strict";
2
3 const addEmptyLineBefore = require("../../utils/addEmptyLineBefore");
4 const hasEmptyLine = require("../../utils/hasEmptyLine");
5 const isAfterComment = require("../../utils/isAfterComment");
6 const isFirstNested = require("../../utils/isFirstNested");
7 const isFirstNodeOfRoot = require("../../utils/isFirstNodeOfRoot");
8 const isSharedLineComment = require("../../utils/isSharedLineComment");
9 const optionsMatches = require("../../utils/optionsMatches");
10 const removeEmptyLinesBefore = require("../../utils/removeEmptyLinesBefore");
11 const report = require("../../utils/report");
12 const ruleMessages = require("../../utils/ruleMessages");
13 const validateOptions = require("../../utils/validateOptions");
14
15 const ruleName = "comment-empty-line-before";
16
17 const messages = ruleMessages(ruleName, {
18   expected: "Expected empty line before comment",
19   rejected: "Unexpected empty line before comment"
20 });
21
22 const stylelintCommandPrefix = "stylelint-";
23
24 const rule = function(expectation, options, context) {
25   return (root, result) => {
26     const validOptions = validateOptions(
27       result,
28       ruleName,
29       {
30         actual: expectation,
31         possible: ["always", "never"]
32       },
33       {
34         actual: options,
35         possible: {
36           except: ["first-nested"],
37           ignore: ["stylelint-commands", "after-comment"]
38         },
39         optional: true
40       }
41     );
42     if (!validOptions) {
43       return;
44     }
45
46     root.walkComments(comment => {
47       // Ignore the first node
48       if (isFirstNodeOfRoot(comment)) {
49         return;
50       }
51
52       // Optionally ignore stylelint commands
53       if (
54         comment.text.indexOf(stylelintCommandPrefix) === 0 &&
55         optionsMatches(options, "ignore", "stylelint-commands")
56       ) {
57         return;
58       }
59
60       // Optionally ignore newlines between comments
61       if (
62         optionsMatches(options, "ignore", "after-comment") &&
63         isAfterComment(comment)
64       ) {
65         return;
66       }
67
68       // Ignore shared-line comments
69       if (isSharedLineComment(comment)) {
70         return;
71       }
72
73       // Ignore SCSS comments
74       if (comment.raws.inline || comment.inline) {
75         return;
76       }
77
78       const expectEmptyLineBefore = (() => {
79         if (
80           optionsMatches(options, "except", "first-nested") &&
81           isFirstNested(comment)
82         ) {
83           return false;
84         }
85         return expectation === "always";
86       })();
87
88       const before = comment.raws.before || "";
89       const hasEmptyLineBefore = hasEmptyLine(before);
90
91       // Return if the expectation is met
92       if (expectEmptyLineBefore === hasEmptyLineBefore) {
93         return;
94       }
95
96       // Fix
97       if (context.fix) {
98         if (expectEmptyLineBefore) {
99           addEmptyLineBefore(comment, context.newline);
100         } else {
101           removeEmptyLinesBefore(comment, context.newline);
102         }
103
104         return;
105       }
106
107       const message = expectEmptyLineBefore
108         ? messages.expected
109         : messages.rejected;
110
111       report({
112         message,
113         node: comment,
114         result,
115         ruleName
116       });
117     });
118   };
119 };
120
121 rule.ruleName = ruleName;
122 rule.messages = messages;
123 module.exports = rule;