UNPKG

2.97 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash');
4
5const isWhitespace = require('../../utils/isWhitespace');
6const report = require('../../utils/report');
7const ruleMessages = require('../../utils/ruleMessages');
8const validateOptions = require('../../utils/validateOptions');
9
10const ruleName = 'comment-whitespace-inside';
11
12const messages = ruleMessages(ruleName, {
13 expectedOpening: 'Expected whitespace after "/*"',
14 rejectedOpening: 'Unexpected whitespace after "/*"',
15 expectedClosing: 'Expected whitespace before "*/"',
16 rejectedClosing: 'Unexpected whitespace before "*/"',
17});
18
19function rule(expectation, options, context) {
20 return function (root, result) {
21 const validOptions = validateOptions(result, ruleName, {
22 actual: expectation,
23 possible: ['always', 'never'],
24 });
25
26 if (!validOptions) {
27 return;
28 }
29
30 root.walkComments((comment) => {
31 if (comment.raws.inline || comment.inline) {
32 return;
33 }
34
35 const rawComment = comment.toString();
36 const firstFourChars = rawComment.substr(0, 4);
37
38 // Return early if sourcemap or copyright comment
39 if (/^\/\*[#!]\s/.test(firstFourChars)) {
40 return;
41 }
42
43 const leftMatches = rawComment.match(/(^\/\*+)(\s)?/);
44 const rightMatches = rawComment.match(/(\s)?(\*+\/)$/);
45 const opener = leftMatches[1];
46 const leftSpace = leftMatches[2] || '';
47 const rightSpace = rightMatches[1] || '';
48 const closer = rightMatches[2];
49
50 if (expectation === 'never' && leftSpace !== '') {
51 complain(messages.rejectedOpening, opener.length);
52 }
53
54 if (expectation === 'always' && !isWhitespace(leftSpace)) {
55 complain(messages.expectedOpening, opener.length);
56 }
57
58 if (expectation === 'never' && rightSpace !== '') {
59 complain(messages.rejectedClosing, comment.toString().length - closer.length - 1);
60 }
61
62 if (expectation === 'always' && !isWhitespace(rightSpace)) {
63 complain(messages.expectedClosing, comment.toString().length - closer.length - 1);
64 }
65
66 function addWhitespaceBefore(comment) {
67 if (comment.text.startsWith('*')) {
68 comment.text = comment.text.replace(/^(\*+)/, `$1 `);
69 } else {
70 comment.raws.left = ' ';
71 }
72 }
73
74 function addWhitespaceAfter(comment) {
75 if (_.last(comment.text) === '*') {
76 comment.text = comment.text.replace(/(\*+)$/, ` $1`);
77 } else {
78 comment.raws.right = ' ';
79 }
80 }
81
82 function complain(message, index) {
83 if (context.fix) {
84 if (expectation === 'never') {
85 comment.raws.left = '';
86 comment.raws.right = '';
87 comment.text = comment.text.replace(/^(\*+)(\s+)?/, '$1').replace(/(\s+)?(\*+)$/, '$2');
88 } else {
89 if (!leftSpace) {
90 addWhitespaceBefore(comment);
91 }
92
93 if (!rightSpace) {
94 addWhitespaceAfter(comment);
95 }
96 }
97
98 return;
99 }
100
101 report({
102 message,
103 index,
104 result,
105 ruleName,
106 node: comment,
107 });
108 }
109 });
110 };
111}
112
113rule.ruleName = ruleName;
114rule.messages = messages;
115module.exports = rule;