1 | /**
|
2 | * Requires space after opening array square bracket and before closing.
|
3 | * Reports only on arrays, not on property accessors.
|
4 | * Use [requireSpacesInsideBrackets](http://jscs.info/rule/requireSpacesInsideBrackets.html)
|
5 | * to report on all brackets.
|
6 | *
|
7 | * Types: `String` or `Object`
|
8 | *
|
9 | * Values:
|
10 | * - `String`
|
11 | * - `"all"`: strict mode
|
12 | * - `"allButNested"`: (*deprecated* use Object version with `"allExcept": [ "[", "]" ]`) ignores nested
|
13 | * closing brackets in a row
|
14 | * - `Object`:
|
15 | * - `"allExcept"`: Array specifying list of tokens that can occur after an opening square bracket or before a
|
16 | * closing square bracket without a space
|
17 | *
|
18 | * #### Example
|
19 | *
|
20 | * ```js
|
21 | * "requireSpacesInsideArrayBrackets": "all"
|
22 | * ```
|
23 | * ```js
|
24 | * "requireSpacesInsideArrayBrackets": {
|
25 | * "allExcept": [ "[", "]", "{", "}" ]
|
26 | * }
|
27 | * ```
|
28 | *
|
29 | * ##### Valid for mode `"all"`
|
30 | *
|
31 | * ```js
|
32 | * var x = [ 1 ];
|
33 | * var x = a[1];
|
34 | * ```
|
35 | *
|
36 | * ##### Valid for mode `{ "allExcept": [ "[", "]" ] }` or `"allButNested"`
|
37 | *
|
38 | * ```js
|
39 | * var x = [[ 1 ], [ 2 ]];
|
40 | * ```
|
41 | *
|
42 | * ##### Valid for mode `{ "allExcept": [ "[", "]", "{", "}" ] }`
|
43 | *
|
44 | * ```js
|
45 | * var x = [[ 1 ], [ 2 ]];
|
46 | * var x = [{ a: 1 }, { b: 2}];
|
47 | * ```
|
48 | *
|
49 | * ##### Invalid
|
50 | *
|
51 | * ```js
|
52 | * var x = [1];
|
53 | * ```
|
54 | */
|
55 |
|
56 | var assert = require('assert');
|
57 |
|
58 | module.exports = function() {};
|
59 |
|
60 | module.exports.prototype = {
|
61 |
|
62 | configure: function(value) {
|
63 | var mode;
|
64 | var modes = {
|
65 | 'all': true,
|
66 | 'allButNested': true
|
67 | };
|
68 | var isObject = typeof value === 'object';
|
69 |
|
70 | var error = this.getOptionName() + ' rule' +
|
71 | ' requires string value "all" or "allButNested" or object';
|
72 |
|
73 | if (typeof value === 'string') {
|
74 | assert(modes[value], error);
|
75 |
|
76 | } else if (isObject) {
|
77 | assert('allExcept' in value, error);
|
78 | } else {
|
79 | assert(false, error);
|
80 | }
|
81 |
|
82 | this._exceptions = {};
|
83 |
|
84 | if (isObject) {
|
85 | (value.allExcept || []).forEach(function(value) {
|
86 | this._exceptions[value] = true;
|
87 | }, this);
|
88 |
|
89 | } else {
|
90 | mode = value;
|
91 | }
|
92 |
|
93 | if (mode === 'allButNested') {
|
94 | this._exceptions['['] = this._exceptions[']'] = true;
|
95 | }
|
96 | },
|
97 |
|
98 | getOptionName: function() {
|
99 | return 'requireSpacesInsideArrayBrackets';
|
100 | },
|
101 |
|
102 | check: function(file, errors) {
|
103 | var exceptions = this._exceptions;
|
104 |
|
105 | file.iterateNodesByType('ArrayExpression', function(node) {
|
106 | var openBracket = node.getFirstToken();
|
107 | var afterOpen = file.getNextToken(openBracket, {includeComments: true});
|
108 | var closeBracket = file.getLastNodeToken(node);
|
109 | var beforeClose = file.getPrevToken(closeBracket, {includeComments: true});
|
110 |
|
111 | // Skip for empty array brackets
|
112 | if (afterOpen.value === ']') {
|
113 | return;
|
114 | }
|
115 |
|
116 | if (!(afterOpen.value in exceptions)) {
|
117 | errors.assert.spacesBetween({
|
118 | token: openBracket,
|
119 | nextToken: afterOpen,
|
120 | exactly: 1,
|
121 | message: 'One space required after opening bracket'
|
122 | });
|
123 | }
|
124 |
|
125 | if (!(beforeClose.value in exceptions)) {
|
126 | errors.assert.spacesBetween({
|
127 | token: beforeClose,
|
128 | nextToken: closeBracket,
|
129 | exactly: 1,
|
130 | message: 'One space required before closing bracket'
|
131 | });
|
132 | }
|
133 | });
|
134 | }
|
135 | };
|