UNPKG

5.52 kBJavaScriptView Raw
1'use strict'
2
3/**
4 * @fileoverview Disallows or enforces spaces inside computed properties.
5 * @author Jamund Ferguson
6 * @copyright 2015 Jamund Ferguson. All rights reserved.
7 */
8// ------------------------------------------------------------------------------
9// Rule Definition
10// ------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 docs: {
15 url: 'https://github.com/standard/eslint-plugin-standard#rules-explanations'
16 }
17 },
18
19 create: function (context) {
20 var propertyNameMustBeSpaced = context.options[0] === 'always' // default is "never"
21 var propertyNameMustBeEven = context.options[0] === 'even' // default is "never"
22
23 // --------------------------------------------------------------------------
24 // Helpers
25 // --------------------------------------------------------------------------
26
27 /**
28 * Determines whether two adjacent tokens are have whitespace between them.
29 * @param {Object} left - The left token object.
30 * @param {Object} right - The right token object.
31 * @returns {boolean} Whether or not there is space between the tokens.
32 */
33 function isSpaced (left, right) {
34 return left.range[1] < right.range[0]
35 }
36
37 /**
38 * Determines whether two adjacent tokens are on the same line.
39 * @param {Object} left - The left token object.
40 * @param {Object} right - The right token object.
41 * @returns {boolean} Whether or not the tokens are on the same line.
42 */
43 function isSameLine (left, right) {
44 return left.loc.start.line === right.loc.start.line
45 }
46
47 /**
48 * Reports that there shouldn't be a space after the first token
49 * @param {ASTNode} node - The node to report in the event of an error.
50 * @param {Token} token - The token to use for the report.
51 * @returns {void}
52 */
53 function reportNoBeginningSpace (node, token) {
54 context.report(node, token.loc.start,
55 "There should be no space after '" + token.value + "'")
56 }
57
58 /**
59 * Reports that there shouldn't be a space before the last token
60 * @param {ASTNode} node - The node to report in the event of an error.
61 * @param {Token} token - The token to use for the report.
62 * @returns {void}
63 */
64 function reportNoEndingSpace (node, token) {
65 context.report(node, token.loc.start,
66 "There should be no space before '" + token.value + "'")
67 }
68
69 /**
70 * Reports that there should be a space after the first token
71 * @param {ASTNode} node - The node to report in the event of an error.
72 * @param {Token} token - The token to use for the report.
73 * @returns {void}
74 */
75 function reportRequiredBeginningSpace (node, token) {
76 context.report(node, token.loc.start,
77 "A space is required after '" + token.value + "'")
78 }
79
80 /**
81 * Reports that there should be a space before the last token
82 * @param {ASTNode} node - The node to report in the event of an error.
83 * @param {Token} token - The token to use for the report.
84 * @returns {void}
85 */
86 function reportRequiredEndingSpace (node, token) {
87 context.report(node, token.loc.start,
88 "A space is required before '" + token.value + "'")
89 }
90
91 /**
92 * Returns a function that checks the spacing of a node on the property name
93 * that was passed in.
94 * @param {String} propertyName The property on the node to check for spacing
95 * @returns {Function} A function that will check spacing on a node
96 */
97 function checkSpacing (propertyName) {
98 return function (node) {
99 if (!node.computed) {
100 return
101 }
102
103 var property = node[propertyName]
104
105 var before = context.getTokenBefore(property)
106 var first = context.getFirstToken(property)
107 var last = context.getLastToken(property)
108 var after = context.getTokenAfter(property)
109 var startSpace, endSpace
110
111 if (propertyNameMustBeEven) {
112 if (!isSameLine(before, after)) {
113 context.report(node, 'Expected "[" and "]" to be on the same line')
114 return
115 }
116 startSpace = first.loc.start.column - before.loc.end.column
117 endSpace = after.loc.start.column - last.loc.end.column
118
119 if (startSpace !== endSpace || startSpace > 1) {
120 context.report(node, 'Expected 1 or 0 spaces around "[" and "]"')
121 }
122
123 return
124 }
125
126 if (isSameLine(before, first)) {
127 if (propertyNameMustBeSpaced) {
128 if (!isSpaced(before, first) && isSameLine(before, first)) {
129 reportRequiredBeginningSpace(node, before)
130 }
131 } else {
132 if (isSpaced(before, first)) {
133 reportNoBeginningSpace(node, before)
134 }
135 }
136 }
137
138 if (isSameLine(last, after)) {
139 if (propertyNameMustBeSpaced) {
140 if (!isSpaced(last, after) && isSameLine(last, after)) {
141 reportRequiredEndingSpace(node, after)
142 }
143 } else {
144 if (isSpaced(last, after)) {
145 reportNoEndingSpace(node, after)
146 }
147 }
148 }
149 }
150 }
151
152 // --------------------------------------------------------------------------
153 // Public
154 // --------------------------------------------------------------------------
155
156 return {
157 Property: checkSpacing('key'),
158 MemberExpression: checkSpacing('property')
159 }
160 }
161}