This repository has been archived by the owner on Mar 23, 2024. It is now read-only.
/
require-dot-notation.js
166 lines (152 loc) · 4.11 KB
/
require-dot-notation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
* Requires member expressions to use dot notation when possible
*
* Types: `Boolean` or `Object`
*
* Values:
* - `true`
* - `"except_snake_case"` (*deprecated* use `"allExcept": ["snake_case"]`) allow quoted snake cased identifiers
* - `Object`:
* - `'allExcept'` array of exceptions:
* - `'keywords'` allow quoted identifiers made of reserved words
* - `'snake_case'` allow quoted snake cased identifiers
*
* N.B.: keywords are always allowed with es3 enabled (http://jscs.info/overview.html#es3)
*
* JSHint: [`sub`](http://www.jshint.com/docs/options/#sub)
*
* #### Example
*
* ```js
* "requireDotNotation": true
* ```
*
* ##### Valid
*
* ```js
* var a = b[c];
* var a = b.c;
* var a = b[c.d];
* var a = b[1];
* var a = b.while; // reserved words can be property names in ES5
* ```
*
* ##### Invalid
*
* ```js
* var a = b['c'];
* var a = b['snake_cased'];
* var a = b['_camelCased'];
* var a = b['camelCased_'];
* ```
*
* #### Example for allExcept snake_case
*
* ```js
* "requireDotNotation": { "allExcept": [ "snake_case" ] }
* ```
*
* ##### Valid
* ```js
* var a = b[c];
* var a = b.c;
* var a = b['snake_cased'];
* var a = b['camelCased_butWithSnakes'];
* ```
*
* #### Example for allExcept keywords
*
* ```js
* "requireDotNotation": { "allExcept": [ "keywords" ] }
* ```
*
* ##### Valid
*
* ```js
* var a = b['await']; // reserved word in ES6
* var a = b['yield']; // reserved word in ES5
* var a = b['let'];
* ```
*
* ##### Invalid
*
* ```js
* var a = b['c'];
* ```
*
* #### Example for `"es3": true`
*
* ```js
* "requireDotNotation": true,
* "es3": true
* ```
*
* ##### Valid
*
* ```js
* var a = b[c];
* var a = b.c;
* var a = b[c.d];
* var a = b[1];
* var a = b['while']; // reserved word in ES3
* ```
*
* ##### Invalid
*
* ```js
* var a = b['c'];
* ```
*/
var assert = require('assert');
var utils = require('../utils');
var reservedWords = require('reserved-words');
module.exports = function() {};
module.exports.prototype = {
configure: function(options) {
if (typeof options !== 'object') {
assert(
options === true || options === 'except_snake_case',
this.getOptionName() + ' option requires either a true value or an object'
);
var _options = {};
if (options === 'except_snake_case') {
_options.allExcept = ['snake_case'];
}
return this.configure(_options);
}
assert(
!options.allExcept || Array.isArray(options.allExcept),
'allExcept value of ' + this.getOptionName() + ' option requires an array with exceptions'
);
if (Array.isArray(options.allExcept)) {
this._exceptSnakeCase = options.allExcept.indexOf('snake_case') > -1;
this._exceptKeywords = options.allExcept.indexOf('keywords') > -1;
}
},
getOptionName: function() {
return 'requireDotNotation';
},
check: function(file, errors) {
var exceptSnakeCase = this._exceptSnakeCase;
var exceptKeywords = this._exceptKeywords;
var dialect = file.getDialect();
file.iterateNodesByType('MemberExpression', function(node) {
if (!node.computed || node.property.type !== 'StringLiteral') {
return;
}
var value = node.property.value;
if (// allow numbers, nulls, and anything else
typeof value !== 'string' ||
// allow invalid identifiers
!utils.isValidIdentifierName(value, file.getDialect()) ||
// allow quoted snake cased identifiers if allExcept: ['snake_case']
(exceptSnakeCase && utils.isSnakeCased(utils.trimUnderscores(value))) ||
// allow quoted reserved words if allExcept: ['keywords']
((dialect === 'es3' || exceptKeywords) && reservedWords.check(value, dialect, true))
) {
return;
}
errors.add('Use dot notation instead of brackets for member expressions', node.property);
});
}
};