UNPKG

3.49 kBJavaScriptView Raw
1/**
2 * Disallows space after opening and before closing grouping parentheses.
3 *
4 * Types: `Boolean` or `Object`
5 *
6 * Values:
7 * - `true`: always disallow spaces inside grouping parentheses
8 * - `Object`:
9 * - `"allExcept"`: `[ "{", "}", "function" ]` Ignore parenthesized objects and functions
10 *
11 * #### Example
12 *
13 * ```js
14 * "disallowSpacesInsideParenthesizedExpression": true
15 *
16 * // or
17 *
18 * "disallowSpacesInsideParenthesizedExpression": {
19 * "allExcept": [ "{", "}" ]
20 * }
21 * ```
22 *
23 * ##### Valid for mode `true`
24 *
25 * ```js
26 * var x = (1 + obj.size) * (2);
27 * ```
28 *
29 * ##### Valid for mode `{ allExcept": [ "{", "}", "function" ] }`
30 *
31 * ```js
32 * var x = (options || { x: true } ).x;
33 * var global = ( function() { return this; } )();
34 * ```
35 *
36 * ##### Invalid
37 *
38 * ```js
39 * var x = ( 1 + obj.size ) * ( 2 );
40 * ```
41 */
42
43var assert = require('assert');
44var TokenCategorizer = require('../token-categorizer');
45
46module.exports = function() {};
47
48module.exports.prototype = {
49 configure: function(value) {
50 var isObject = typeof value === 'object';
51
52 var error = this.getOptionName() + ' rule requires string value true or object';
53
54 if (isObject) {
55 assert('allExcept' in value, error);
56 } else {
57 assert(value === true, error);
58 }
59
60 this._exceptions = {};
61
62 if (isObject) {
63 (value.allExcept || []).forEach(function(value) {
64 this._exceptions[value] = true;
65 }, this);
66 }
67 },
68
69 getOptionName: function() {
70 return 'disallowSpacesInsideParenthesizedExpression';
71 },
72
73 check: function(file, errors) {
74 var exceptions = this._exceptions;
75
76 file.iterateTokensByTypeAndValue('Punctuator', '(', function(token) {
77 var nextToken = file.getNextToken(token, {includeComments: true});
78 var value = nextToken.isComment ?
79 nextToken.type === 'CommentBlock' ? '/*' : '//' :
80 nextToken.value;
81
82 // Skip empty parentheses and explicit exceptions
83 if (value === ')' || value in exceptions) {
84 return;
85 }
86
87 // Skip non-expression parentheses
88 var type = TokenCategorizer.categorizeOpenParen(token);
89 if (type !== 'ParenthesizedExpression') {
90 return;
91 }
92
93 errors.assert.noWhitespaceBetween({
94 token: token,
95 nextToken: nextToken,
96 message: 'Illegal space after opening grouping parenthesis'
97 });
98 });
99
100 file.iterateTokensByTypeAndValue('Punctuator', ')', function(token) {
101 var prevToken = file.getPrevToken(token, {includeComments: true});
102 var value = prevToken.isComment ?
103 prevToken.type === 'CommentBlock' ? '*/' : '' :
104 prevToken.value;
105
106 // Skip empty parentheses and explicit exceptions
107 if (value === '(' || value in exceptions) {
108 return;
109 }
110
111 // Skip non-expression parentheses
112 var type = TokenCategorizer.categorizeCloseParen(token);
113 if (type !== 'ParenthesizedExpression') {
114 return;
115 }
116
117 errors.assert.noWhitespaceBetween({
118 token: prevToken,
119 nextToken: token,
120 message: 'Illegal space before closing grouping parenthesis'
121 });
122 });
123 }
124};