eslint 6.5.1 → 6.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README.md +10 -9
  3. package/conf/config-schema.js +1 -0
  4. package/conf/default-cli-options.js +1 -1
  5. package/lib/cli-engine/cascading-config-array-factory.js +40 -14
  6. package/lib/cli-engine/cli-engine.js +49 -21
  7. package/lib/cli-engine/config-array/config-array.js +13 -4
  8. package/lib/cli-engine/config-array/config-dependency.js +2 -0
  9. package/lib/cli-engine/config-array/extracted-config.js +27 -0
  10. package/lib/cli-engine/config-array/ignore-pattern.js +231 -0
  11. package/lib/cli-engine/config-array/index.js +2 -0
  12. package/lib/cli-engine/config-array/override-tester.js +2 -0
  13. package/lib/cli-engine/config-array-factory.js +120 -2
  14. package/lib/cli-engine/file-enumerator.js +65 -34
  15. package/lib/cli-engine/formatters/html.js +1 -0
  16. package/lib/init/autoconfig.js +1 -11
  17. package/lib/init/config-file.js +0 -1
  18. package/lib/init/config-initializer.js +4 -4
  19. package/lib/init/config-rule.js +1 -5
  20. package/lib/init/npm-utils.js +0 -5
  21. package/lib/linter/code-path-analysis/code-path-analyzer.js +24 -38
  22. package/lib/linter/code-path-analysis/code-path-segment.js +17 -25
  23. package/lib/linter/code-path-analysis/code-path-state.js +40 -81
  24. package/lib/linter/code-path-analysis/code-path.js +10 -11
  25. package/lib/linter/code-path-analysis/debug-helpers.js +8 -12
  26. package/lib/linter/code-path-analysis/fork-context.js +23 -34
  27. package/lib/linter/code-path-analysis/id-generator.js +2 -2
  28. package/lib/linter/linter.js +121 -95
  29. package/lib/linter/node-event-generator.js +3 -2
  30. package/lib/linter/report-translator.js +73 -7
  31. package/lib/rule-tester/rule-tester.js +46 -14
  32. package/lib/rules/accessor-pairs.js +8 -8
  33. package/lib/rules/array-bracket-newline.js +12 -15
  34. package/lib/rules/array-bracket-spacing.js +12 -12
  35. package/lib/rules/array-callback-return.js +6 -11
  36. package/lib/rules/array-element-newline.js +5 -8
  37. package/lib/rules/arrow-parens.js +0 -1
  38. package/lib/rules/block-scoped-var.js +3 -3
  39. package/lib/rules/block-spacing.js +4 -4
  40. package/lib/rules/camelcase.js +19 -6
  41. package/lib/rules/capitalized-comments.js +0 -7
  42. package/lib/rules/class-methods-use-this.js +3 -3
  43. package/lib/rules/comma-dangle.js +20 -25
  44. package/lib/rules/comma-spacing.js +1 -1
  45. package/lib/rules/computed-property-spacing.js +14 -14
  46. package/lib/rules/consistent-return.js +4 -5
  47. package/lib/rules/consistent-this.js +5 -5
  48. package/lib/rules/constructor-super.js +14 -16
  49. package/lib/rules/curly.js +12 -9
  50. package/lib/rules/default-param-last.js +1 -0
  51. package/lib/rules/dot-location.js +11 -12
  52. package/lib/rules/func-names.js +6 -6
  53. package/lib/rules/function-call-argument-newline.js +8 -6
  54. package/lib/rules/generator-star-spacing.js +4 -9
  55. package/lib/rules/getter-return.js +4 -7
  56. package/lib/rules/grouped-accessor-pairs.js +224 -0
  57. package/lib/rules/indent.js +13 -2
  58. package/lib/rules/index.js +5 -0
  59. package/lib/rules/init-declarations.js +2 -2
  60. package/lib/rules/jsx-quotes.js +1 -1
  61. package/lib/rules/keyword-spacing.js +32 -56
  62. package/lib/rules/lines-around-directive.js +1 -1
  63. package/lib/rules/max-len.js +0 -5
  64. package/lib/rules/max-statements-per-line.js +3 -7
  65. package/lib/rules/multiline-comment-style.js +237 -106
  66. package/lib/rules/multiline-ternary.js +3 -3
  67. package/lib/rules/newline-after-var.js +6 -7
  68. package/lib/rules/newline-before-return.js +8 -9
  69. package/lib/rules/newline-per-chained-call.js +2 -4
  70. package/lib/rules/no-class-assign.js +2 -2
  71. package/lib/rules/no-compare-neg-zero.js +1 -2
  72. package/lib/rules/no-cond-assign.js +14 -4
  73. package/lib/rules/no-confusing-arrow.js +2 -2
  74. package/lib/rules/no-console.js +4 -8
  75. package/lib/rules/no-const-assign.js +1 -1
  76. package/lib/rules/no-constructor-return.js +62 -0
  77. package/lib/rules/no-dupe-args.js +1 -1
  78. package/lib/rules/no-dupe-class-members.js +3 -4
  79. package/lib/rules/no-dupe-else-if.js +122 -0
  80. package/lib/rules/no-dupe-keys.js +6 -5
  81. package/lib/rules/no-duplicate-imports.js +14 -18
  82. package/lib/rules/no-else-return.js +0 -8
  83. package/lib/rules/no-empty-function.js +2 -4
  84. package/lib/rules/no-eval.js +10 -18
  85. package/lib/rules/no-ex-assign.js +1 -1
  86. package/lib/rules/no-extra-bind.js +5 -12
  87. package/lib/rules/no-extra-boolean-cast.js +0 -2
  88. package/lib/rules/no-extra-label.js +4 -9
  89. package/lib/rules/no-extra-parens.js +17 -15
  90. package/lib/rules/no-extra-semi.js +5 -6
  91. package/lib/rules/no-fallthrough.js +6 -6
  92. package/lib/rules/no-func-assign.js +3 -3
  93. package/lib/rules/no-global-assign.js +4 -4
  94. package/lib/rules/no-implicit-coercion.js +10 -10
  95. package/lib/rules/no-implicit-globals.js +90 -8
  96. package/lib/rules/no-implied-eval.js +0 -1
  97. package/lib/rules/no-inline-comments.js +25 -11
  98. package/lib/rules/no-invalid-this.js +17 -5
  99. package/lib/rules/no-labels.js +3 -6
  100. package/lib/rules/no-lone-blocks.js +1 -1
  101. package/lib/rules/no-loop-func.js +6 -11
  102. package/lib/rules/no-magic-numbers.js +6 -6
  103. package/lib/rules/no-misleading-character-class.js +14 -7
  104. package/lib/rules/no-mixed-operators.js +13 -22
  105. package/lib/rules/no-mixed-requires.js +0 -1
  106. package/lib/rules/no-multi-spaces.js +1 -1
  107. package/lib/rules/no-native-reassign.js +4 -4
  108. package/lib/rules/no-octal-escape.js +1 -1
  109. package/lib/rules/no-param-reassign.js +28 -7
  110. package/lib/rules/no-redeclare.js +1 -1
  111. package/lib/rules/no-regex-spaces.js +0 -1
  112. package/lib/rules/no-restricted-imports.js +11 -11
  113. package/lib/rules/no-self-assign.js +12 -13
  114. package/lib/rules/no-sequences.js +3 -3
  115. package/lib/rules/no-setter-return.js +227 -0
  116. package/lib/rules/no-shadow.js +1 -4
  117. package/lib/rules/no-tabs.js +8 -2
  118. package/lib/rules/no-this-before-super.js +12 -13
  119. package/lib/rules/no-trailing-spaces.js +19 -7
  120. package/lib/rules/no-underscore-dangle.js +23 -4
  121. package/lib/rules/no-unexpected-multiline.js +8 -0
  122. package/lib/rules/no-unmodified-loop-condition.js +16 -29
  123. package/lib/rules/no-unneeded-ternary.js +3 -3
  124. package/lib/rules/no-unreachable.js +7 -7
  125. package/lib/rules/no-unsafe-finally.js +4 -7
  126. package/lib/rules/no-unsafe-negation.js +32 -9
  127. package/lib/rules/no-unused-expressions.js +11 -7
  128. package/lib/rules/no-unused-labels.js +3 -6
  129. package/lib/rules/no-unused-vars.js +22 -29
  130. package/lib/rules/no-use-before-define.js +10 -15
  131. package/lib/rules/no-useless-call.js +4 -4
  132. package/lib/rules/no-useless-computed-key.js +60 -33
  133. package/lib/rules/no-useless-concat.js +4 -4
  134. package/lib/rules/no-useless-constructor.js +14 -22
  135. package/lib/rules/no-useless-escape.js +29 -8
  136. package/lib/rules/no-useless-rename.js +7 -7
  137. package/lib/rules/no-useless-return.js +8 -15
  138. package/lib/rules/no-var.js +12 -25
  139. package/lib/rules/no-warning-comments.js +0 -1
  140. package/lib/rules/no-whitespace-before-property.js +3 -3
  141. package/lib/rules/object-curly-newline.js +7 -10
  142. package/lib/rules/object-curly-spacing.js +21 -22
  143. package/lib/rules/object-shorthand.js +1 -1
  144. package/lib/rules/one-var-declaration-per-line.js +2 -2
  145. package/lib/rules/operator-assignment.js +33 -3
  146. package/lib/rules/padded-blocks.js +1 -1
  147. package/lib/rules/padding-line-between-statements.js +0 -16
  148. package/lib/rules/prefer-arrow-callback.js +6 -6
  149. package/lib/rules/prefer-const.js +27 -28
  150. package/lib/rules/prefer-destructuring.js +1 -7
  151. package/lib/rules/prefer-exponentiation-operator.js +189 -0
  152. package/lib/rules/prefer-named-capture-group.js +0 -1
  153. package/lib/rules/prefer-numeric-literals.js +32 -4
  154. package/lib/rules/prefer-object-spread.js +7 -7
  155. package/lib/rules/prefer-rest-params.js +3 -6
  156. package/lib/rules/prefer-spread.js +4 -4
  157. package/lib/rules/prefer-template.js +5 -6
  158. package/lib/rules/quote-props.js +1 -1
  159. package/lib/rules/quotes.js +5 -6
  160. package/lib/rules/radix.js +5 -10
  161. package/lib/rules/require-await.js +10 -5
  162. package/lib/rules/require-yield.js +2 -2
  163. package/lib/rules/rest-spread-spacing.js +1 -1
  164. package/lib/rules/semi.js +6 -3
  165. package/lib/rules/sort-imports.js +3 -4
  166. package/lib/rules/sort-keys.js +1 -3
  167. package/lib/rules/space-before-blocks.js +1 -2
  168. package/lib/rules/space-in-parens.js +4 -4
  169. package/lib/rules/space-infix-ops.js +6 -6
  170. package/lib/rules/spaced-comment.js +20 -22
  171. package/lib/rules/strict.js +2 -4
  172. package/lib/rules/symbol-description.js +1 -2
  173. package/lib/rules/template-curly-spacing.js +2 -2
  174. package/lib/rules/use-isnan.js +40 -3
  175. package/lib/rules/utils/ast-utils.js +84 -85
  176. package/lib/rules/utils/fix-tracker.js +0 -6
  177. package/lib/rules/utils/lazy-loading-rule-map.js +0 -1
  178. package/lib/rules/vars-on-top.js +11 -11
  179. package/lib/shared/config-ops.js +2 -2
  180. package/lib/shared/runtime-info.js +8 -8
  181. package/lib/shared/traverser.js +2 -0
  182. package/lib/shared/types.js +9 -0
  183. package/lib/source-code/source-code.js +94 -17
  184. package/lib/source-code/token-store/backward-token-comment-cursor.js +5 -5
  185. package/lib/source-code/token-store/backward-token-cursor.js +5 -5
  186. package/lib/source-code/token-store/cursors.js +17 -19
  187. package/lib/source-code/token-store/decorative-cursor.js +1 -1
  188. package/lib/source-code/token-store/filter-cursor.js +2 -2
  189. package/lib/source-code/token-store/forward-token-comment-cursor.js +5 -5
  190. package/lib/source-code/token-store/forward-token-cursor.js +5 -5
  191. package/lib/source-code/token-store/index.js +86 -92
  192. package/lib/source-code/token-store/limit-cursor.js +2 -2
  193. package/lib/source-code/token-store/padded-token-cursor.js +7 -7
  194. package/lib/source-code/token-store/skip-cursor.js +2 -2
  195. package/lib/source-code/token-store/utils.js +9 -13
  196. package/package.json +9 -7
  197. package/lib/cli-engine/ignored-paths.js +0 -362
@@ -47,7 +47,6 @@ module.exports = {
47
47
  * Checks if a node is free of side effects.
48
48
  *
49
49
  * This check is stricter than it needs to be, in order to keep the implementation simple.
50
- *
51
50
  * @param {ASTNode} node A node to check.
52
51
  * @returns {boolean} True if the node is known to be side-effect free, false otherwise.
53
52
  */
@@ -57,8 +56,7 @@ module.exports = {
57
56
 
58
57
  /**
59
58
  * Reports a given function node.
60
- *
61
- * @param {ASTNode} node - A node to report. This is a FunctionExpression or
59
+ * @param {ASTNode} node A node to report. This is a FunctionExpression or
62
60
  * an ArrowFunctionExpression.
63
61
  * @returns {void}
64
62
  */
@@ -90,8 +88,7 @@ module.exports = {
90
88
  * method.
91
89
  *
92
90
  * e.g. `(function() {}.bind(foo))`
93
- *
94
- * @param {ASTNode} node - A node to report. This is a FunctionExpression or
91
+ * @param {ASTNode} node A node to report. This is a FunctionExpression or
95
92
  * an ArrowFunctionExpression.
96
93
  * @returns {boolean} `true` if the node is the callee of `.bind()` method.
97
94
  */
@@ -113,8 +110,7 @@ module.exports = {
113
110
 
114
111
  /**
115
112
  * Adds a scope information object to the stack.
116
- *
117
- * @param {ASTNode} node - A node to add. This node is a FunctionExpression
113
+ * @param {ASTNode} node A node to add. This node is a FunctionExpression
118
114
  * or a FunctionDeclaration node.
119
115
  * @returns {void}
120
116
  */
@@ -130,8 +126,7 @@ module.exports = {
130
126
  * Removes the scope information object from the top of the stack.
131
127
  * At the same time, this reports the function node if the function has
132
128
  * `.bind()` and the `this` keywords found.
133
- *
134
- * @param {ASTNode} node - A node to remove. This node is a
129
+ * @param {ASTNode} node A node to remove. This node is a
135
130
  * FunctionExpression or a FunctionDeclaration node.
136
131
  * @returns {void}
137
132
  */
@@ -146,8 +141,7 @@ module.exports = {
146
141
  /**
147
142
  * Reports a given arrow function if the function is callee of `.bind()`
148
143
  * method.
149
- *
150
- * @param {ASTNode} node - A node to report. This node is an
144
+ * @param {ASTNode} node A node to report. This node is an
151
145
  * ArrowFunctionExpression.
152
146
  * @returns {void}
153
147
  */
@@ -159,7 +153,6 @@ module.exports = {
159
153
 
160
154
  /**
161
155
  * Set the mark as the `this` keyword was found in this scope.
162
- *
163
156
  * @returns {void}
164
157
  */
165
158
  function markAsThisFound() {
@@ -49,7 +49,6 @@ module.exports = {
49
49
 
50
50
  /**
51
51
  * Check if a node is in a context where its value would be coerced to a boolean at runtime.
52
- *
53
52
  * @param {ASTNode} node The node
54
53
  * @param {ASTNode} parent Its parent
55
54
  * @returns {boolean} If it is in a boolean context
@@ -67,7 +66,6 @@ module.exports = {
67
66
 
68
67
  /**
69
68
  * Check if a node has comments inside.
70
- *
71
69
  * @param {ASTNode} node The node to check.
72
70
  * @returns {boolean} `true` if it has comments inside.
73
71
  */
@@ -40,8 +40,7 @@ module.exports = {
40
40
 
41
41
  /**
42
42
  * Creates a new scope with a breakable statement.
43
- *
44
- * @param {ASTNode} node - A node to create. This is a BreakableStatement.
43
+ * @param {ASTNode} node A node to create. This is a BreakableStatement.
45
44
  * @returns {void}
46
45
  */
47
46
  function enterBreakableStatement(node) {
@@ -54,7 +53,6 @@ module.exports = {
54
53
 
55
54
  /**
56
55
  * Removes the top scope of the stack.
57
- *
58
56
  * @returns {void}
59
57
  */
60
58
  function exitBreakableStatement() {
@@ -66,8 +64,7 @@ module.exports = {
66
64
  *
67
65
  * This ignores it if the body is a breakable statement.
68
66
  * In this case it's handled in the `enterBreakableStatement` function.
69
- *
70
- * @param {ASTNode} node - A node to create. This is a LabeledStatement.
67
+ * @param {ASTNode} node A node to create. This is a LabeledStatement.
71
68
  * @returns {void}
72
69
  */
73
70
  function enterLabeledStatement(node) {
@@ -85,8 +82,7 @@ module.exports = {
85
82
  *
86
83
  * This ignores it if the body is a breakable statement.
87
84
  * In this case it's handled in the `exitBreakableStatement` function.
88
- *
89
- * @param {ASTNode} node - A node. This is a LabeledStatement.
85
+ * @param {ASTNode} node A node. This is a LabeledStatement.
90
86
  * @returns {void}
91
87
  */
92
88
  function exitLabeledStatement(node) {
@@ -97,8 +93,7 @@ module.exports = {
97
93
 
98
94
  /**
99
95
  * Reports a given control node if it's unnecessary.
100
- *
101
- * @param {ASTNode} node - A node. This is a BreakStatement or a
96
+ * @param {ASTNode} node A node. This is a BreakStatement or a
102
97
  * ContinueStatement.
103
98
  * @returns {void}
104
99
  */
@@ -50,7 +50,8 @@ module.exports = {
50
50
  returnAssign: { type: "boolean" },
51
51
  ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
52
52
  enforceForArrowConditionals: { type: "boolean" },
53
- enforceForSequenceExpressions: { type: "boolean" }
53
+ enforceForSequenceExpressions: { type: "boolean" },
54
+ enforceForNewInMemberExpressions: { type: "boolean" }
54
55
  },
55
56
  additionalProperties: false
56
57
  }
@@ -80,6 +81,8 @@ module.exports = {
80
81
  context.options[1].enforceForArrowConditionals === false;
81
82
  const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] &&
82
83
  context.options[1].enforceForSequenceExpressions === false;
84
+ const IGNORE_NEW_IN_MEMBER_EXPR = ALL_NODES && context.options[1] &&
85
+ context.options[1].enforceForNewInMemberExpressions === false;
83
86
 
84
87
  const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" });
85
88
  const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" });
@@ -88,7 +91,7 @@ module.exports = {
88
91
 
89
92
  /**
90
93
  * Determines if this rule should be enforced for a node given the current configuration.
91
- * @param {ASTNode} node - The node to be checked.
94
+ * @param {ASTNode} node The node to be checked.
92
95
  * @returns {boolean} True if the rule should be enforced for this node.
93
96
  * @private
94
97
  */
@@ -127,7 +130,7 @@ module.exports = {
127
130
 
128
131
  /**
129
132
  * Determines if a node is surrounded by parentheses.
130
- * @param {ASTNode} node - The node to be checked.
133
+ * @param {ASTNode} node The node to be checked.
131
134
  * @returns {boolean} True if the node is parenthesised.
132
135
  * @private
133
136
  */
@@ -137,7 +140,7 @@ module.exports = {
137
140
 
138
141
  /**
139
142
  * Determines if a node is surrounded by parentheses twice.
140
- * @param {ASTNode} node - The node to be checked.
143
+ * @param {ASTNode} node The node to be checked.
141
144
  * @returns {boolean} True if the node is doubly parenthesised.
142
145
  * @private
143
146
  */
@@ -147,7 +150,7 @@ module.exports = {
147
150
 
148
151
  /**
149
152
  * Determines if a node is surrounded by (potentially) invalid parentheses.
150
- * @param {ASTNode} node - The node to be checked.
153
+ * @param {ASTNode} node The node to be checked.
151
154
  * @returns {boolean} True if the node is incorrectly parenthesised.
152
155
  * @private
153
156
  */
@@ -158,7 +161,7 @@ module.exports = {
158
161
  /**
159
162
  * Determines if a node that is expected to be parenthesised is surrounded by
160
163
  * (potentially) invalid extra parentheses.
161
- * @param {ASTNode} node - The node to be checked.
164
+ * @param {ASTNode} node The node to be checked.
162
165
  * @returns {boolean} True if the node is has an unexpected extra pair of parentheses.
163
166
  * @private
164
167
  */
@@ -168,7 +171,7 @@ module.exports = {
168
171
 
169
172
  /**
170
173
  * Determines if a node test expression is allowed to have a parenthesised assignment
171
- * @param {ASTNode} node - The node to be checked.
174
+ * @param {ASTNode} node The node to be checked.
172
175
  * @returns {boolean} True if the assignment can be parenthesised.
173
176
  * @private
174
177
  */
@@ -178,7 +181,7 @@ module.exports = {
178
181
 
179
182
  /**
180
183
  * Determines if a node is in a return statement
181
- * @param {ASTNode} node - The node to be checked.
184
+ * @param {ASTNode} node The node to be checked.
182
185
  * @returns {boolean} True if the node is in a return statement.
183
186
  * @private
184
187
  */
@@ -197,7 +200,7 @@ module.exports = {
197
200
 
198
201
  /**
199
202
  * Determines if a constructor function is newed-up with parens
200
- * @param {ASTNode} newExpression - The NewExpression node to be checked.
203
+ * @param {ASTNode} newExpression The NewExpression node to be checked.
201
204
  * @returns {boolean} True if the constructor is called with parens.
202
205
  * @private
203
206
  */
@@ -217,7 +220,7 @@ module.exports = {
217
220
 
218
221
  /**
219
222
  * Determines if a node is or contains an assignment expression
220
- * @param {ASTNode} node - The node to be checked.
223
+ * @param {ASTNode} node The node to be checked.
221
224
  * @returns {boolean} True if the node is or contains an assignment expression.
222
225
  * @private
223
226
  */
@@ -239,7 +242,7 @@ module.exports = {
239
242
 
240
243
  /**
241
244
  * Determines if a node is contained by or is itself a return statement and is allowed to have a parenthesised assignment
242
- * @param {ASTNode} node - The node to be checked.
245
+ * @param {ASTNode} node The node to be checked.
243
246
  * @returns {boolean} True if the assignment can be parenthesised.
244
247
  * @private
245
248
  */
@@ -261,8 +264,8 @@ module.exports = {
261
264
  /**
262
265
  * Determines if a node following a [no LineTerminator here] restriction is
263
266
  * surrounded by (potentially) invalid extra parentheses.
264
- * @param {Token} token - The token preceding the [no LineTerminator here] restriction.
265
- * @param {ASTNode} node - The node to be checked.
267
+ * @param {Token} token The token preceding the [no LineTerminator here] restriction.
268
+ * @param {ASTNode} node The node to be checked.
266
269
  * @returns {boolean} True if the node is incorrectly parenthesised.
267
270
  * @private
268
271
  */
@@ -567,7 +570,6 @@ module.exports = {
567
570
  /**
568
571
  * Checks whether the syntax of the given ancestor of an 'in' expression inside a for-loop initializer
569
572
  * is preventing the 'in' keyword from being interpreted as a part of an ill-formed for-in loop.
570
- *
571
573
  * @param {ASTNode} node Ancestor of an 'in' expression.
572
574
  * @param {ASTNode} child Child of the node, ancestor of the same 'in' expression or the 'in' expression itself.
573
575
  * @returns {boolean} True if the keyword 'in' would be interpreted as the 'in' operator, without any parenthesis.
@@ -599,7 +601,6 @@ module.exports = {
599
601
  /**
600
602
  * Starts a new reports buffering. Warnings will be stored in a buffer instead of being reported immediately.
601
603
  * An additional logic that requires multiple nodes (e.g. a whole subtree) may dismiss some of the stored warnings.
602
- *
603
604
  * @returns {void}
604
605
  */
605
606
  function startNewReportsBuffering() {
@@ -895,6 +896,7 @@ module.exports = {
895
896
  }
896
897
 
897
898
  if (nodeObjHasExcessParens &&
899
+ !IGNORE_NEW_IN_MEMBER_EXPR &&
898
900
  node.object.type === "NewExpression" &&
899
901
  isNewExpressionWithParens(node.object)) {
900
902
  report(node.object);
@@ -40,7 +40,7 @@ module.exports = {
40
40
 
41
41
  /**
42
42
  * Reports an unnecessary semicolon error.
43
- * @param {Node|Token} nodeOrToken - A node or a token to be reported.
43
+ * @param {Node|Token} nodeOrToken A node or a token to be reported.
44
44
  * @returns {void}
45
45
  */
46
46
  function report(nodeOrToken) {
@@ -64,8 +64,7 @@ module.exports = {
64
64
  /**
65
65
  * Checks for a part of a class body.
66
66
  * This checks tokens from a specified token to a next MethodDefinition or the end of class body.
67
- *
68
- * @param {Token} firstToken - The first token to check.
67
+ * @param {Token} firstToken The first token to check.
69
68
  * @returns {void}
70
69
  */
71
70
  function checkForPartOfClassBody(firstToken) {
@@ -83,7 +82,7 @@ module.exports = {
83
82
 
84
83
  /**
85
84
  * Reports this empty statement, except if the parent node is a loop.
86
- * @param {Node} node - A EmptyStatement node to be reported.
85
+ * @param {Node} node A EmptyStatement node to be reported.
87
86
  * @returns {void}
88
87
  */
89
88
  EmptyStatement(node) {
@@ -106,7 +105,7 @@ module.exports = {
106
105
 
107
106
  /**
108
107
  * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.
109
- * @param {Node} node - A ClassBody node to check.
108
+ * @param {Node} node A ClassBody node to check.
110
109
  * @returns {void}
111
110
  */
112
111
  ClassBody(node) {
@@ -115,7 +114,7 @@ module.exports = {
115
114
 
116
115
  /**
117
116
  * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.
118
- * @param {Node} node - A MethodDefinition node of the start point.
117
+ * @param {Node} node A MethodDefinition node of the start point.
119
118
  * @returns {void}
120
119
  */
121
120
  MethodDefinition(node) {
@@ -18,9 +18,9 @@ const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu;
18
18
 
19
19
  /**
20
20
  * Checks whether or not a given node has a fallthrough comment.
21
- * @param {ASTNode} node - A SwitchCase node to get comments.
22
- * @param {RuleContext} context - A rule context which stores comments.
23
- * @param {RegExp} fallthroughCommentPattern - A pattern to match comment to.
21
+ * @param {ASTNode} node A SwitchCase node to get comments.
22
+ * @param {RuleContext} context A rule context which stores comments.
23
+ * @param {RegExp} fallthroughCommentPattern A pattern to match comment to.
24
24
  * @returns {boolean} `true` if the node has a valid fallthrough comment.
25
25
  */
26
26
  function hasFallthroughComment(node, context, fallthroughCommentPattern) {
@@ -32,7 +32,7 @@ function hasFallthroughComment(node, context, fallthroughCommentPattern) {
32
32
 
33
33
  /**
34
34
  * Checks whether or not a given code path segment is reachable.
35
- * @param {CodePathSegment} segment - A CodePathSegment to check.
35
+ * @param {CodePathSegment} segment A CodePathSegment to check.
36
36
  * @returns {boolean} `true` if the segment is reachable.
37
37
  */
38
38
  function isReachable(segment) {
@@ -41,8 +41,8 @@ function isReachable(segment) {
41
41
 
42
42
  /**
43
43
  * Checks whether a node and a token are separated by blank lines
44
- * @param {ASTNode} node - The node to check
45
- * @param {Token} token - The token to compare against
44
+ * @param {ASTNode} node The node to check
45
+ * @param {Token} token The token to compare against
46
46
  * @returns {boolean} `true` if there are blank lines between node and token
47
47
  */
48
48
  function hasBlankLinesBetween(node, token) {
@@ -29,7 +29,7 @@ module.exports = {
29
29
 
30
30
  /**
31
31
  * Reports a reference if is non initializer and writable.
32
- * @param {References} references - Collection of reference to check.
32
+ * @param {References} references Collection of reference to check.
33
33
  * @returns {void}
34
34
  */
35
35
  function checkReference(references) {
@@ -40,7 +40,7 @@ module.exports = {
40
40
 
41
41
  /**
42
42
  * Finds and reports references that are non initializer and writable.
43
- * @param {Variable} variable - A variable to check.
43
+ * @param {Variable} variable A variable to check.
44
44
  * @returns {void}
45
45
  */
46
46
  function checkVariable(variable) {
@@ -51,7 +51,7 @@ module.exports = {
51
51
 
52
52
  /**
53
53
  * Checks parameters of a given function node.
54
- * @param {ASTNode} node - A function node to check.
54
+ * @param {ASTNode} node A function node to check.
55
55
  * @returns {void}
56
56
  */
57
57
  function checkForFunction(node) {
@@ -41,9 +41,9 @@ module.exports = {
41
41
 
42
42
  /**
43
43
  * Reports write references.
44
- * @param {Reference} reference - A reference to check.
45
- * @param {int} index - The index of the reference in the references.
46
- * @param {Reference[]} references - The array that the reference belongs to.
44
+ * @param {Reference} reference A reference to check.
45
+ * @param {int} index The index of the reference in the references.
46
+ * @param {Reference[]} references The array that the reference belongs to.
47
47
  * @returns {void}
48
48
  */
49
49
  function checkReference(reference, index, references) {
@@ -68,7 +68,7 @@ module.exports = {
68
68
 
69
69
  /**
70
70
  * Reports write references if a given variable is read-only builtin.
71
- * @param {Variable} variable - A variable to check.
71
+ * @param {Variable} variable A variable to check.
72
72
  * @returns {void}
73
73
  */
74
74
  function checkVariable(variable) {
@@ -16,7 +16,7 @@ const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"];
16
16
 
17
17
  /**
18
18
  * Parses and normalizes an option object.
19
- * @param {Object} options - An option object to parse.
19
+ * @param {Object} options An option object to parse.
20
20
  * @returns {Object} The parsed and normalized option object.
21
21
  */
22
22
  function parseOptions(options) {
@@ -30,7 +30,7 @@ function parseOptions(options) {
30
30
 
31
31
  /**
32
32
  * Checks whether or not a node is a double logical nigating.
33
- * @param {ASTNode} node - An UnaryExpression node to check.
33
+ * @param {ASTNode} node An UnaryExpression node to check.
34
34
  * @returns {boolean} Whether or not the node is a double logical nigating.
35
35
  */
36
36
  function isDoubleLogicalNegating(node) {
@@ -43,7 +43,7 @@ function isDoubleLogicalNegating(node) {
43
43
 
44
44
  /**
45
45
  * Checks whether or not a node is a binary negating of `.indexOf()` method calling.
46
- * @param {ASTNode} node - An UnaryExpression node to check.
46
+ * @param {ASTNode} node An UnaryExpression node to check.
47
47
  * @returns {boolean} Whether or not the node is a binary negating of `.indexOf()` method calling.
48
48
  */
49
49
  function isBinaryNegatingOfIndexOf(node) {
@@ -58,7 +58,7 @@ function isBinaryNegatingOfIndexOf(node) {
58
58
 
59
59
  /**
60
60
  * Checks whether or not a node is a multiplying by one.
61
- * @param {BinaryExpression} node - A BinaryExpression node to check.
61
+ * @param {BinaryExpression} node A BinaryExpression node to check.
62
62
  * @returns {boolean} Whether or not the node is a multiplying by one.
63
63
  */
64
64
  function isMultiplyByOne(node) {
@@ -118,7 +118,7 @@ function isEmptyString(node) {
118
118
 
119
119
  /**
120
120
  * Checks whether or not a node is a concatenating with an empty string.
121
- * @param {ASTNode} node - A BinaryExpression node to check.
121
+ * @param {ASTNode} node A BinaryExpression node to check.
122
122
  * @returns {boolean} Whether or not the node is a concatenating with an empty string.
123
123
  */
124
124
  function isConcatWithEmptyString(node) {
@@ -130,7 +130,7 @@ function isConcatWithEmptyString(node) {
130
130
 
131
131
  /**
132
132
  * Checks whether or not a node is appended with an empty string.
133
- * @param {ASTNode} node - An AssignmentExpression node to check.
133
+ * @param {ASTNode} node An AssignmentExpression node to check.
134
134
  * @returns {boolean} Whether or not the node is appended with an empty string.
135
135
  */
136
136
  function isAppendEmptyString(node) {
@@ -139,7 +139,7 @@ function isAppendEmptyString(node) {
139
139
 
140
140
  /**
141
141
  * Returns the operand that is not an empty string from a flagged BinaryExpression.
142
- * @param {ASTNode} node - The flagged BinaryExpression node to check.
142
+ * @param {ASTNode} node The flagged BinaryExpression node to check.
143
143
  * @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression.
144
144
  */
145
145
  function getNonEmptyOperand(node) {
@@ -196,9 +196,9 @@ module.exports = {
196
196
 
197
197
  /**
198
198
  * Reports an error and autofixes the node
199
- * @param {ASTNode} node - An ast node to report the error on.
200
- * @param {string} recommendation - The recommended code for the issue
201
- * @param {bool} shouldFix - Whether this report should fix the node
199
+ * @param {ASTNode} node An ast node to report the error on.
200
+ * @param {string} recommendation The recommended code for the issue
201
+ * @param {bool} shouldFix Whether this report should fix the node
202
202
  * @returns {void}
203
203
  */
204
204
  function report(node, recommendation, shouldFix) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Rule to check for implicit global variables and functions.
2
+ * @fileoverview Rule to check for implicit global variables, functions and classes.
3
3
  * @author Joshua Peek
4
4
  */
5
5
 
@@ -14,41 +14,123 @@ module.exports = {
14
14
  type: "suggestion",
15
15
 
16
16
  docs: {
17
- description: "disallow variable and `function` declarations in the global scope",
17
+ description: "disallow declarations in the global scope",
18
18
  category: "Best Practices",
19
19
  recommended: false,
20
20
  url: "https://eslint.org/docs/rules/no-implicit-globals"
21
21
  },
22
22
 
23
- schema: []
23
+ schema: [{
24
+ type: "object",
25
+ properties: {
26
+ lexicalBindings: {
27
+ type: "boolean",
28
+ default: false
29
+ }
30
+ },
31
+ additionalProperties: false
32
+ }],
33
+
34
+ messages: {
35
+ globalNonLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable.",
36
+ globalLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in a block or in an IIFE.",
37
+ globalVariableLeak: "Global variable leak, declare the variable if it is intended to be local.",
38
+ assignmentToReadonlyGlobal: "Unexpected assignment to read-only global variable.",
39
+ redeclarationOfReadonlyGlobal: "Unexpected redeclaration of read-only global variable."
40
+ }
24
41
  },
25
42
 
26
43
  create(context) {
44
+
45
+ const checkLexicalBindings = context.options[0] && context.options[0].lexicalBindings === true;
46
+
47
+ /**
48
+ * Reports the node.
49
+ * @param {ASTNode} node Node to report.
50
+ * @param {string} messageId Id of the message to report.
51
+ * @param {string|undefined} kind Declaration kind, can be 'var', 'const', 'let', function or class.
52
+ * @returns {void}
53
+ */
54
+ function report(node, messageId, kind) {
55
+ context.report({
56
+ node,
57
+ messageId,
58
+ data: {
59
+ kind
60
+ }
61
+ });
62
+ }
63
+
27
64
  return {
28
65
  Program() {
29
66
  const scope = context.getScope();
30
67
 
31
68
  scope.variables.forEach(variable => {
32
- if (variable.writeable) {
69
+
70
+ // Only ESLint global variables have the `writable` key.
71
+ const isReadonlyEslintGlobalVariable = variable.writeable === false;
72
+ const isWritableEslintGlobalVariable = variable.writeable === true;
73
+
74
+ if (isWritableEslintGlobalVariable) {
75
+
76
+ // Everything is allowed with writable ESLint global variables.
33
77
  return;
34
78
  }
35
79
 
36
80
  variable.defs.forEach(def => {
81
+ const defNode = def.node;
82
+
37
83
  if (def.type === "FunctionName" || (def.type === "Variable" && def.parent.kind === "var")) {
38
- context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." });
84
+ if (isReadonlyEslintGlobalVariable) {
85
+ report(defNode, "redeclarationOfReadonlyGlobal");
86
+ } else {
87
+ report(
88
+ defNode,
89
+ "globalNonLexicalBinding",
90
+ def.type === "FunctionName" ? "function" : `'${def.parent.kind}'`
91
+ );
92
+ }
93
+ }
94
+
95
+ if (checkLexicalBindings) {
96
+ if (def.type === "ClassName" ||
97
+ (def.type === "Variable" && (def.parent.kind === "let" || def.parent.kind === "const"))) {
98
+ if (isReadonlyEslintGlobalVariable) {
99
+ report(defNode, "redeclarationOfReadonlyGlobal");
100
+ } else {
101
+ report(
102
+ defNode,
103
+ "globalLexicalBinding",
104
+ def.type === "ClassName" ? "class" : `'${def.parent.kind}'`
105
+ );
106
+ }
107
+ }
39
108
  }
40
109
  });
41
110
  });
42
111
 
112
+ // Undeclared assigned variables.
43
113
  scope.implicit.variables.forEach(variable => {
44
114
  const scopeVariable = scope.set.get(variable.name);
115
+ let messageId;
45
116
 
46
- if (scopeVariable && scopeVariable.writeable) {
47
- return;
117
+ if (scopeVariable) {
118
+
119
+ // ESLint global variable
120
+ if (scopeVariable.writeable) {
121
+ return;
122
+ }
123
+ messageId = "assignmentToReadonlyGlobal";
124
+
125
+ } else {
126
+
127
+ // Reference to an unknown variable, possible global leak.
128
+ messageId = "globalVariableLeak";
48
129
  }
49
130
 
131
+ // def.node is an AssignmentExpression, ForInStatement or ForOfStatement.
50
132
  variable.defs.forEach(def => {
51
- context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." });
133
+ report(def.node, messageId);
52
134
  });
53
135
  });
54
136
  }
@@ -64,7 +64,6 @@ module.exports = {
64
64
  * Determines if a node represents a call to a potentially implied eval.
65
65
  *
66
66
  * This checks the callee name and that there's an argument, but not the type of the argument.
67
- *
68
67
  * @param {ASTNode} node The CallExpression to check.
69
68
  * @returns {boolean} True if the node matches, false if not.
70
69
  * @private
@@ -35,22 +35,36 @@ module.exports = {
35
35
  */
36
36
  function testCodeAroundComment(node) {
37
37
 
38
- // Get the whole line and cut it off at the start of the comment
39
- const startLine = String(sourceCode.lines[node.loc.start.line - 1]);
40
- const endLine = String(sourceCode.lines[node.loc.end.line - 1]);
38
+ const startLine = String(sourceCode.lines[node.loc.start.line - 1]),
39
+ endLine = String(sourceCode.lines[node.loc.end.line - 1]),
40
+ preamble = startLine.slice(0, node.loc.start.column).trim(),
41
+ postamble = endLine.slice(node.loc.end.column).trim(),
42
+ isPreambleEmpty = !preamble,
43
+ isPostambleEmpty = !postamble;
41
44
 
42
- const preamble = startLine.slice(0, node.loc.start.column).trim();
45
+ // Nothing on both sides
46
+ if (isPreambleEmpty && isPostambleEmpty) {
47
+ return;
48
+ }
43
49
 
44
- // Also check after the comment
45
- const postamble = endLine.slice(node.loc.end.column).trim();
50
+ // JSX Exception
51
+ if (
52
+ (isPreambleEmpty || preamble === "{") &&
53
+ (isPostambleEmpty || postamble === "}")
54
+ ) {
55
+ const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]);
46
56
 
47
- // Check that this comment isn't an ESLint directive
48
- const isDirective = astUtils.isDirectiveComment(node);
57
+ if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") {
58
+ return;
59
+ }
60
+ }
49
61
 
50
- // Should be empty if there was only whitespace around the comment
51
- if (!isDirective && (preamble || postamble)) {
52
- context.report({ node, message: "Unexpected comment inline with code." });
62
+ // Don't report ESLint directive comments
63
+ if (astUtils.isDirectiveComment(node)) {
64
+ return;
53
65
  }
66
+
67
+ context.report({ node, message: "Unexpected comment inline with code." });
54
68
  }
55
69
 
56
70
  //--------------------------------------------------------------------------