UNPKG

2.39 kBJavaScriptView Raw
1'use strict';
2
3const blockString = require('../../utils/blockString');
4const nextNonCommentNode = require('../../utils/nextNonCommentNode');
5const rawNodeString = require('../../utils/rawNodeString');
6const report = require('../../utils/report');
7const ruleMessages = require('../../utils/ruleMessages');
8const validateOptions = require('../../utils/validateOptions');
9const whitespaceChecker = require('../../utils/whitespaceChecker');
10
11const ruleName = 'declaration-block-semicolon-newline-after';
12
13const messages = ruleMessages(ruleName, {
14 expectedAfter: () => 'Expected newline after ";"',
15 expectedAfterMultiLine: () => 'Expected newline after ";" in a multi-line declaration block',
16 rejectedAfterMultiLine: () => 'Unexpected newline after ";" in a multi-line declaration block',
17});
18
19function rule(expectation, options, context) {
20 const checker = whitespaceChecker('newline', expectation, messages);
21
22 return (root, result) => {
23 const validOptions = validateOptions(result, ruleName, {
24 actual: expectation,
25 possible: ['always', 'always-multi-line', 'never-multi-line'],
26 });
27
28 if (!validOptions) {
29 return;
30 }
31
32 root.walkDecls((decl) => {
33 // Ignore last declaration if there's no trailing semicolon
34 const parentRule = decl.parent;
35
36 if (!parentRule.raws.semicolon && parentRule.last === decl) {
37 return;
38 }
39
40 const nextNode = decl.next();
41
42 if (!nextNode) {
43 return;
44 }
45
46 // Allow end-of-line comment
47 const nodeToCheck = nextNonCommentNode(nextNode);
48
49 if (!nodeToCheck) {
50 return;
51 }
52
53 checker.afterOneOnly({
54 source: rawNodeString(nodeToCheck),
55 index: -1,
56 lineCheckStr: blockString(parentRule),
57 err: (m) => {
58 if (context.fix) {
59 if (expectation.startsWith('always')) {
60 const index = nodeToCheck.raws.before.search(/\r?\n/);
61
62 if (index >= 0) {
63 nodeToCheck.raws.before = nodeToCheck.raws.before.slice(index);
64 } else {
65 nodeToCheck.raws.before = context.newline + nodeToCheck.raws.before;
66 }
67
68 return;
69 }
70
71 if (expectation === 'never-multi-line') {
72 nodeToCheck.raws.before = '';
73
74 return;
75 }
76 }
77
78 report({
79 message: m,
80 node: decl,
81 index: decl.toString().length + 1,
82 result,
83 ruleName,
84 });
85 },
86 });
87 });
88 };
89}
90
91rule.ruleName = ruleName;
92rule.messages = messages;
93module.exports = rule;