eslint 4.12.1 → 4.15.0

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 (269) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +3 -3
  3. package/lib/cli-engine.js +4 -0
  4. package/lib/linter.js +78 -35
  5. package/lib/options.js +47 -41
  6. package/lib/report-translator.js +34 -13
  7. package/lib/rules/.eslintrc.yml +1 -0
  8. package/lib/rules/accessor-pairs.js +2 -1
  9. package/lib/rules/array-bracket-newline.js +2 -1
  10. package/lib/rules/array-bracket-spacing.js +2 -1
  11. package/lib/rules/array-callback-return.js +18 -3
  12. package/lib/rules/array-element-newline.js +2 -1
  13. package/lib/rules/arrow-body-style.js +15 -2
  14. package/lib/rules/arrow-parens.js +2 -1
  15. package/lib/rules/arrow-spacing.js +2 -1
  16. package/lib/rules/block-scoped-var.js +2 -1
  17. package/lib/rules/block-spacing.js +2 -1
  18. package/lib/rules/brace-style.js +2 -1
  19. package/lib/rules/callback-return.js +2 -1
  20. package/lib/rules/camelcase.js +29 -17
  21. package/lib/rules/capitalized-comments.js +2 -1
  22. package/lib/rules/class-methods-use-this.js +2 -1
  23. package/lib/rules/comma-dangle.js +2 -1
  24. package/lib/rules/comma-spacing.js +2 -1
  25. package/lib/rules/comma-style.js +2 -1
  26. package/lib/rules/complexity.js +3 -16
  27. package/lib/rules/computed-property-spacing.js +2 -1
  28. package/lib/rules/consistent-return.js +2 -1
  29. package/lib/rules/consistent-this.js +2 -1
  30. package/lib/rules/constructor-super.js +2 -1
  31. package/lib/rules/curly.js +2 -1
  32. package/lib/rules/default-case.js +2 -1
  33. package/lib/rules/dot-location.js +2 -1
  34. package/lib/rules/dot-notation.js +2 -1
  35. package/lib/rules/eol-last.js +10 -1
  36. package/lib/rules/eqeqeq.js +2 -1
  37. package/lib/rules/for-direction.js +2 -1
  38. package/lib/rules/func-call-spacing.js +2 -1
  39. package/lib/rules/func-name-matching.js +2 -1
  40. package/lib/rules/func-names.js +2 -1
  41. package/lib/rules/func-style.js +2 -1
  42. package/lib/rules/function-paren-newline.js +2 -1
  43. package/lib/rules/generator-star-spacing.js +2 -1
  44. package/lib/rules/getter-return.js +2 -1
  45. package/lib/rules/global-require.js +2 -1
  46. package/lib/rules/guard-for-in.js +2 -1
  47. package/lib/rules/handle-callback-err.js +2 -1
  48. package/lib/rules/id-blacklist.js +2 -1
  49. package/lib/rules/id-length.js +2 -1
  50. package/lib/rules/id-match.js +2 -1
  51. package/lib/rules/implicit-arrow-linebreak.js +2 -1
  52. package/lib/rules/indent-legacy.js +2 -1
  53. package/lib/rules/indent.js +13 -2
  54. package/lib/rules/init-declarations.js +2 -1
  55. package/lib/rules/jsx-quotes.js +2 -1
  56. package/lib/rules/key-spacing.js +2 -1
  57. package/lib/rules/keyword-spacing.js +2 -1
  58. package/lib/rules/line-comment-position.js +2 -1
  59. package/lib/rules/linebreak-style.js +2 -1
  60. package/lib/rules/lines-around-comment.js +2 -1
  61. package/lib/rules/lines-around-directive.js +2 -1
  62. package/lib/rules/lines-between-class-members.js +53 -4
  63. package/lib/rules/max-depth.js +2 -1
  64. package/lib/rules/max-len.js +2 -1
  65. package/lib/rules/max-lines.js +2 -1
  66. package/lib/rules/max-nested-callbacks.js +2 -1
  67. package/lib/rules/max-params.js +2 -1
  68. package/lib/rules/max-statements-per-line.js +2 -1
  69. package/lib/rules/max-statements.js +2 -1
  70. package/lib/rules/multiline-comment-style.js +2 -1
  71. package/lib/rules/multiline-ternary.js +2 -1
  72. package/lib/rules/new-cap.js +2 -1
  73. package/lib/rules/new-parens.js +2 -1
  74. package/lib/rules/newline-after-var.js +2 -1
  75. package/lib/rules/newline-before-return.js +2 -1
  76. package/lib/rules/newline-per-chained-call.js +2 -1
  77. package/lib/rules/no-alert.js +2 -1
  78. package/lib/rules/no-array-constructor.js +2 -1
  79. package/lib/rules/no-await-in-loop.js +2 -1
  80. package/lib/rules/no-bitwise.js +2 -1
  81. package/lib/rules/no-buffer-constructor.js +2 -1
  82. package/lib/rules/no-caller.js +2 -1
  83. package/lib/rules/no-case-declarations.js +2 -1
  84. package/lib/rules/no-catch-shadow.js +2 -1
  85. package/lib/rules/no-class-assign.js +2 -1
  86. package/lib/rules/no-compare-neg-zero.js +2 -1
  87. package/lib/rules/no-cond-assign.js +2 -1
  88. package/lib/rules/no-confusing-arrow.js +2 -1
  89. package/lib/rules/no-console.js +2 -1
  90. package/lib/rules/no-const-assign.js +2 -1
  91. package/lib/rules/no-constant-condition.js +2 -1
  92. package/lib/rules/no-continue.js +2 -1
  93. package/lib/rules/no-control-regex.js +2 -1
  94. package/lib/rules/no-debugger.js +2 -1
  95. package/lib/rules/no-delete-var.js +2 -1
  96. package/lib/rules/no-div-regex.js +2 -1
  97. package/lib/rules/no-dupe-args.js +2 -1
  98. package/lib/rules/no-dupe-class-members.js +2 -1
  99. package/lib/rules/no-dupe-keys.js +2 -1
  100. package/lib/rules/no-duplicate-case.js +2 -1
  101. package/lib/rules/no-duplicate-imports.js +2 -1
  102. package/lib/rules/no-else-return.js +2 -1
  103. package/lib/rules/no-empty-character-class.js +2 -1
  104. package/lib/rules/no-empty-function.js +2 -1
  105. package/lib/rules/no-empty-pattern.js +2 -1
  106. package/lib/rules/no-empty.js +2 -1
  107. package/lib/rules/no-eq-null.js +2 -1
  108. package/lib/rules/no-eval.js +2 -1
  109. package/lib/rules/no-ex-assign.js +2 -1
  110. package/lib/rules/no-extend-native.js +2 -1
  111. package/lib/rules/no-extra-bind.js +2 -1
  112. package/lib/rules/no-extra-boolean-cast.js +2 -1
  113. package/lib/rules/no-extra-label.js +2 -1
  114. package/lib/rules/no-extra-parens.js +3 -2
  115. package/lib/rules/no-extra-semi.js +2 -1
  116. package/lib/rules/no-fallthrough.js +2 -1
  117. package/lib/rules/no-floating-decimal.js +2 -1
  118. package/lib/rules/no-func-assign.js +2 -1
  119. package/lib/rules/no-global-assign.js +2 -1
  120. package/lib/rules/no-implicit-coercion.js +2 -1
  121. package/lib/rules/no-implicit-globals.js +2 -1
  122. package/lib/rules/no-implied-eval.js +2 -1
  123. package/lib/rules/no-inline-comments.js +2 -1
  124. package/lib/rules/no-inner-declarations.js +2 -1
  125. package/lib/rules/no-invalid-regexp.js +2 -1
  126. package/lib/rules/no-invalid-this.js +2 -1
  127. package/lib/rules/no-irregular-whitespace.js +2 -1
  128. package/lib/rules/no-iterator.js +2 -1
  129. package/lib/rules/no-label-var.js +2 -1
  130. package/lib/rules/no-labels.js +2 -1
  131. package/lib/rules/no-lone-blocks.js +2 -1
  132. package/lib/rules/no-lonely-if.js +2 -1
  133. package/lib/rules/no-loop-func.js +2 -1
  134. package/lib/rules/no-magic-numbers.js +2 -1
  135. package/lib/rules/no-mixed-operators.js +2 -1
  136. package/lib/rules/no-mixed-requires.js +2 -1
  137. package/lib/rules/no-mixed-spaces-and-tabs.js +2 -1
  138. package/lib/rules/no-multi-assign.js +2 -1
  139. package/lib/rules/no-multi-spaces.js +2 -1
  140. package/lib/rules/no-multi-str.js +2 -1
  141. package/lib/rules/no-multiple-empty-lines.js +2 -1
  142. package/lib/rules/no-native-reassign.js +2 -1
  143. package/lib/rules/no-negated-condition.js +2 -1
  144. package/lib/rules/no-negated-in-lhs.js +2 -1
  145. package/lib/rules/no-nested-ternary.js +2 -1
  146. package/lib/rules/no-new-func.js +2 -1
  147. package/lib/rules/no-new-object.js +2 -1
  148. package/lib/rules/no-new-require.js +2 -1
  149. package/lib/rules/no-new-symbol.js +2 -1
  150. package/lib/rules/no-new-wrappers.js +2 -1
  151. package/lib/rules/no-new.js +2 -1
  152. package/lib/rules/no-obj-calls.js +2 -1
  153. package/lib/rules/no-octal-escape.js +2 -1
  154. package/lib/rules/no-octal.js +2 -1
  155. package/lib/rules/no-param-reassign.js +2 -1
  156. package/lib/rules/no-path-concat.js +2 -1
  157. package/lib/rules/no-plusplus.js +2 -1
  158. package/lib/rules/no-process-env.js +2 -1
  159. package/lib/rules/no-process-exit.js +2 -1
  160. package/lib/rules/no-proto.js +2 -1
  161. package/lib/rules/no-prototype-builtins.js +2 -1
  162. package/lib/rules/no-redeclare.js +2 -1
  163. package/lib/rules/no-regex-spaces.js +2 -1
  164. package/lib/rules/no-restricted-globals.js +2 -1
  165. package/lib/rules/no-restricted-imports.js +2 -1
  166. package/lib/rules/no-restricted-modules.js +2 -1
  167. package/lib/rules/no-restricted-properties.js +2 -1
  168. package/lib/rules/no-restricted-syntax.js +2 -1
  169. package/lib/rules/no-return-assign.js +2 -1
  170. package/lib/rules/no-return-await.js +5 -1
  171. package/lib/rules/no-script-url.js +2 -1
  172. package/lib/rules/no-self-assign.js +2 -1
  173. package/lib/rules/no-self-compare.js +2 -1
  174. package/lib/rules/no-sequences.js +2 -1
  175. package/lib/rules/no-shadow-restricted-names.js +2 -1
  176. package/lib/rules/no-shadow.js +2 -1
  177. package/lib/rules/no-spaced-func.js +2 -1
  178. package/lib/rules/no-sparse-arrays.js +2 -1
  179. package/lib/rules/no-sync.js +2 -1
  180. package/lib/rules/no-tabs.js +2 -1
  181. package/lib/rules/no-template-curly-in-string.js +2 -1
  182. package/lib/rules/no-ternary.js +2 -1
  183. package/lib/rules/no-this-before-super.js +2 -1
  184. package/lib/rules/no-throw-literal.js +2 -1
  185. package/lib/rules/no-trailing-spaces.js +2 -1
  186. package/lib/rules/no-undef-init.js +2 -1
  187. package/lib/rules/no-undef.js +2 -1
  188. package/lib/rules/no-undefined.js +2 -1
  189. package/lib/rules/no-underscore-dangle.js +2 -1
  190. package/lib/rules/no-unexpected-multiline.js +2 -1
  191. package/lib/rules/no-unmodified-loop-condition.js +81 -79
  192. package/lib/rules/no-unneeded-ternary.js +2 -1
  193. package/lib/rules/no-unreachable.js +2 -1
  194. package/lib/rules/no-unsafe-finally.js +2 -1
  195. package/lib/rules/no-unsafe-negation.js +2 -1
  196. package/lib/rules/no-unused-expressions.js +2 -1
  197. package/lib/rules/no-unused-labels.js +2 -1
  198. package/lib/rules/no-unused-vars.js +10 -14
  199. package/lib/rules/no-use-before-define.js +2 -1
  200. package/lib/rules/no-useless-call.js +2 -1
  201. package/lib/rules/no-useless-computed-key.js +2 -1
  202. package/lib/rules/no-useless-concat.js +2 -1
  203. package/lib/rules/no-useless-constructor.js +2 -1
  204. package/lib/rules/no-useless-escape.js +2 -1
  205. package/lib/rules/no-useless-rename.js +2 -1
  206. package/lib/rules/no-useless-return.js +2 -1
  207. package/lib/rules/no-var.js +2 -1
  208. package/lib/rules/no-void.js +2 -1
  209. package/lib/rules/no-warning-comments.js +2 -1
  210. package/lib/rules/no-whitespace-before-property.js +2 -1
  211. package/lib/rules/no-with.js +2 -1
  212. package/lib/rules/nonblock-statement-body-position.js +2 -1
  213. package/lib/rules/object-curly-newline.js +2 -1
  214. package/lib/rules/object-curly-spacing.js +2 -1
  215. package/lib/rules/object-property-newline.js +2 -1
  216. package/lib/rules/object-shorthand.js +2 -1
  217. package/lib/rules/one-var-declaration-per-line.js +2 -1
  218. package/lib/rules/one-var.js +42 -8
  219. package/lib/rules/operator-assignment.js +2 -1
  220. package/lib/rules/operator-linebreak.js +2 -1
  221. package/lib/rules/padded-blocks.js +2 -1
  222. package/lib/rules/padding-line-between-statements.js +2 -1
  223. package/lib/rules/prefer-arrow-callback.js +2 -1
  224. package/lib/rules/prefer-const.js +2 -1
  225. package/lib/rules/prefer-destructuring.js +2 -1
  226. package/lib/rules/prefer-numeric-literals.js +2 -1
  227. package/lib/rules/prefer-promise-reject-errors.js +2 -1
  228. package/lib/rules/prefer-reflect.js +2 -1
  229. package/lib/rules/prefer-rest-params.js +2 -1
  230. package/lib/rules/prefer-spread.js +2 -1
  231. package/lib/rules/prefer-template.js +2 -1
  232. package/lib/rules/quote-props.js +2 -1
  233. package/lib/rules/quotes.js +2 -1
  234. package/lib/rules/radix.js +2 -1
  235. package/lib/rules/require-await.js +2 -1
  236. package/lib/rules/require-jsdoc.js +2 -1
  237. package/lib/rules/require-yield.js +2 -1
  238. package/lib/rules/rest-spread-spacing.js +2 -1
  239. package/lib/rules/semi-spacing.js +2 -1
  240. package/lib/rules/semi-style.js +2 -1
  241. package/lib/rules/semi.js +2 -1
  242. package/lib/rules/sort-imports.js +2 -1
  243. package/lib/rules/sort-keys.js +2 -1
  244. package/lib/rules/sort-vars.js +2 -1
  245. package/lib/rules/space-before-blocks.js +2 -1
  246. package/lib/rules/space-before-function-paren.js +2 -1
  247. package/lib/rules/space-in-parens.js +2 -1
  248. package/lib/rules/space-infix-ops.js +2 -1
  249. package/lib/rules/space-unary-ops.js +2 -1
  250. package/lib/rules/spaced-comment.js +2 -1
  251. package/lib/rules/strict.js +2 -1
  252. package/lib/rules/switch-colon-spacing.js +2 -1
  253. package/lib/rules/symbol-description.js +2 -1
  254. package/lib/rules/template-curly-spacing.js +2 -1
  255. package/lib/rules/template-tag-spacing.js +2 -1
  256. package/lib/rules/unicode-bom.js +2 -1
  257. package/lib/rules/use-isnan.js +2 -1
  258. package/lib/rules/valid-jsdoc.js +2 -1
  259. package/lib/rules/valid-typeof.js +2 -1
  260. package/lib/rules/vars-on-top.js +2 -1
  261. package/lib/rules/wrap-iife.js +2 -1
  262. package/lib/rules/wrap-regex.js +2 -1
  263. package/lib/rules/yield-star-spacing.js +2 -1
  264. package/lib/rules/yoda.js +2 -1
  265. package/lib/testers/rule-tester.js +63 -30
  266. package/lib/util/interpolate.js +24 -0
  267. package/lib/util/source-code.js +41 -6
  268. package/lib/util/traverser.js +163 -15
  269. package/package.json +3 -3
@@ -27,7 +27,8 @@ module.exports = {
27
27
  docs: {
28
28
  description: "require or disallow spacing around embedded expressions of template strings",
29
29
  category: "ECMAScript 6",
30
- recommended: false
30
+ recommended: false,
31
+ url: "https://eslint.org/docs/rules/template-curly-spacing"
31
32
  },
32
33
 
33
34
  fixable: "whitespace",
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require or disallow spacing between template tags and their literals",
16
16
  category: "Stylistic Issues",
17
- recommended: false
17
+ recommended: false,
18
+ url: "https://eslint.org/docs/rules/template-tag-spacing"
18
19
  },
19
20
 
20
21
  fixable: "whitespace",
@@ -13,7 +13,8 @@ module.exports = {
13
13
  docs: {
14
14
  description: "require or disallow Unicode byte order mark (BOM)",
15
15
  category: "Stylistic Issues",
16
- recommended: false
16
+ recommended: false,
17
+ url: "https://eslint.org/docs/rules/unicode-bom"
17
18
  },
18
19
 
19
20
  fixable: "whitespace",
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require calls to `isNaN()` when checking for `NaN`",
16
16
  category: "Possible Errors",
17
- recommended: true
17
+ recommended: true,
18
+ url: "https://eslint.org/docs/rules/use-isnan"
18
19
  },
19
20
 
20
21
  schema: []
@@ -19,7 +19,8 @@ module.exports = {
19
19
  docs: {
20
20
  description: "enforce valid JSDoc comments",
21
21
  category: "Possible Errors",
22
- recommended: false
22
+ recommended: false,
23
+ url: "https://eslint.org/docs/rules/valid-jsdoc"
23
24
  },
24
25
 
25
26
  schema: [
@@ -13,7 +13,8 @@ module.exports = {
13
13
  docs: {
14
14
  description: "enforce comparing `typeof` expressions against valid strings",
15
15
  category: "Possible Errors",
16
- recommended: true
16
+ recommended: true,
17
+ url: "https://eslint.org/docs/rules/valid-typeof"
17
18
  },
18
19
 
19
20
  schema: [
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require `var` declarations be placed at the top of their containing scope",
16
16
  category: "Best Practices",
17
- recommended: false
17
+ recommended: false,
18
+ url: "https://eslint.org/docs/rules/vars-on-top"
18
19
  },
19
20
 
20
21
  schema: []
@@ -20,7 +20,8 @@ module.exports = {
20
20
  docs: {
21
21
  description: "require parentheses around immediate `function` invocations",
22
22
  category: "Best Practices",
23
- recommended: false
23
+ recommended: false,
24
+ url: "https://eslint.org/docs/rules/wrap-iife"
24
25
  },
25
26
 
26
27
  schema: [
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require parenthesis around regex literals",
16
16
  category: "Stylistic Issues",
17
- recommended: false
17
+ recommended: false,
18
+ url: "https://eslint.org/docs/rules/wrap-regex"
18
19
  },
19
20
 
20
21
  schema: [],
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require or disallow spacing around the `*` in `yield*` expressions",
16
16
  category: "ECMAScript 6",
17
- recommended: false
17
+ recommended: false,
18
+ url: "https://eslint.org/docs/rules/yield-star-spacing"
18
19
  },
19
20
 
20
21
  fixable: "whitespace",
package/lib/rules/yoda.js CHANGED
@@ -155,7 +155,8 @@ module.exports = {
155
155
  docs: {
156
156
  description: "require or disallow \"Yoda\" conditions",
157
157
  category: "Best Practices",
158
- recommended: false
158
+ recommended: false,
159
+ url: "https://eslint.org/docs/rules/yoda"
159
160
  },
160
161
 
161
162
  schema: [
@@ -47,7 +47,8 @@ const lodash = require("lodash"),
47
47
  ajv = require("../util/ajv"),
48
48
  Linter = require("../linter"),
49
49
  Environments = require("../config/environments"),
50
- SourceCodeFixer = require("../util/source-code-fixer");
50
+ SourceCodeFixer = require("../util/source-code-fixer"),
51
+ interpolate = require("../util/interpolate");
51
52
 
52
53
  //------------------------------------------------------------------------------
53
54
  // Private Members
@@ -131,13 +132,31 @@ const DESCRIBE = Symbol("describe");
131
132
  const IT = Symbol("it");
132
133
 
133
134
  /**
134
- * This is `it` or `describe` if those don't exist.
135
+ * This is `it` default handler if `it` don't exist.
135
136
  * @this {Mocha}
136
137
  * @param {string} text - The description of the test case.
137
138
  * @param {Function} method - The logic of the test case.
138
139
  * @returns {any} Returned value of `method`.
139
140
  */
140
- function defaultHandler(text, method) {
141
+ function itDefaultHandler(text, method) {
142
+ try {
143
+ return method.apply(this);
144
+ } catch (err) {
145
+ if (err instanceof assert.AssertionError) {
146
+ err.message += ` (${util.inspect(err.actual)} ${err.operator} ${util.inspect(err.expected)})`;
147
+ }
148
+ throw err;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * This is `describe` default handler if `describe` don't exist.
154
+ * @this {Mocha}
155
+ * @param {string} text - The description of the test case.
156
+ * @param {Function} method - The logic of the test case.
157
+ * @returns {any} Returned value of `method`.
158
+ */
159
+ function describeDefaultHandler(text, method) {
141
160
  return method.apply(this);
142
161
  }
143
162
 
@@ -212,7 +231,7 @@ class RuleTester {
212
231
  static get describe() {
213
232
  return (
214
233
  this[DESCRIBE] ||
215
- (typeof describe === "function" ? describe : defaultHandler)
234
+ (typeof describe === "function" ? describe : describeDefaultHandler)
216
235
  );
217
236
  }
218
237
 
@@ -223,7 +242,7 @@ class RuleTester {
223
242
  static get it() {
224
243
  return (
225
244
  this[IT] ||
226
- (typeof it === "function" ? it : defaultHandler)
245
+ (typeof it === "function" ? it : itDefaultHandler)
227
246
  );
228
247
  }
229
248
 
@@ -454,59 +473,73 @@ class RuleTester {
454
473
  const hasMessageOfThisRule = messages.some(m => m.ruleId === ruleName);
455
474
 
456
475
  for (let i = 0, l = item.errors.length; i < l; i++) {
457
- assert(!messages[i].fatal, `A fatal parsing error occurred: ${messages[i].message}`);
476
+ const error = item.errors[i];
477
+ const message = messages[i];
478
+
479
+ assert(!message.fatal, `A fatal parsing error occurred: ${message.message}`);
458
480
  assert(hasMessageOfThisRule, "Error rule name should be the same as the name of the rule being tested");
459
481
 
460
- if (typeof item.errors[i] === "string" || item.errors[i] instanceof RegExp) {
482
+ if (typeof error === "string" || error instanceof RegExp) {
461
483
 
462
484
  // Just an error message.
463
- assertMessageMatches(messages[i].message, item.errors[i]);
464
- } else if (typeof item.errors[i] === "object") {
485
+ assertMessageMatches(message.message, error);
486
+ } else if (typeof error === "object") {
465
487
 
466
488
  /*
467
489
  * Error object.
468
490
  * This may have a message, node type, line, and/or
469
491
  * column.
470
492
  */
471
- if (item.errors[i].message) {
472
- assertMessageMatches(messages[i].message, item.errors[i].message);
493
+ if (error.message) {
494
+ assertMessageMatches(message.message, error.message);
473
495
  }
474
496
 
475
- // The following checks use loose equality assertions for backwards compatibility.
497
+ if (error.messageId) {
498
+ const hOP = Object.hasOwnProperty.call.bind(Object.hasOwnProperty);
476
499
 
477
- if (item.errors[i].type) {
500
+ // verify that `error.message` is `undefined`
501
+ assert.strictEqual(error.message, void 0, "Error should not specify both a message and a messageId.");
502
+ if (!hOP(rule, "meta") || !hOP(rule.meta, "messages")) {
503
+ assert.fail("Rule must specify a messages hash in `meta`");
504
+ }
505
+ if (!hOP(rule.meta.messages, error.messageId)) {
506
+ const friendlyIDList = `[${Object.keys(rule.meta.messages).map(key => `'${key}'`).join(", ")}]`;
478
507
 
479
- // eslint-disable-next-line no-restricted-properties
480
- assert.equal(messages[i].nodeType, item.errors[i].type, `Error type should be ${item.errors[i].type}, found ${messages[i].nodeType}`);
481
- }
508
+ assert.fail(`Invalid messageId '${error.messageId}'. Expected one of ${friendlyIDList}.`);
509
+ }
482
510
 
483
- if (item.errors[i].hasOwnProperty("line")) {
511
+ let expectedMessage = rule.meta.messages[error.messageId];
484
512
 
485
- // eslint-disable-next-line no-restricted-properties
486
- assert.equal(messages[i].line, item.errors[i].line, `Error line should be ${item.errors[i].line}`);
487
- }
513
+ if (error.data) {
514
+ expectedMessage = interpolate(expectedMessage, error.data);
515
+ }
488
516
 
489
- if (item.errors[i].hasOwnProperty("column")) {
517
+ assertMessageMatches(message.message, expectedMessage);
518
+ }
490
519
 
491
- // eslint-disable-next-line no-restricted-properties
492
- assert.equal(messages[i].column, item.errors[i].column, `Error column should be ${item.errors[i].column}`);
520
+ if (error.type) {
521
+ assert.strictEqual(message.nodeType, error.type, `Error type should be ${error.type}, found ${message.nodeType}`);
493
522
  }
494
523
 
495
- if (item.errors[i].hasOwnProperty("endLine")) {
524
+ if (error.hasOwnProperty("line")) {
525
+ assert.strictEqual(message.line, error.line, `Error line should be ${error.line}`);
526
+ }
496
527
 
497
- // eslint-disable-next-line no-restricted-properties
498
- assert.equal(messages[i].endLine, item.errors[i].endLine, `Error endLine should be ${item.errors[i].endLine}`);
528
+ if (error.hasOwnProperty("column")) {
529
+ assert.strictEqual(message.column, error.column, `Error column should be ${error.column}`);
499
530
  }
500
531
 
501
- if (item.errors[i].hasOwnProperty("endColumn")) {
532
+ if (error.hasOwnProperty("endLine")) {
533
+ assert.strictEqual(message.endLine, error.endLine, `Error endLine should be ${error.endLine}`);
534
+ }
502
535
 
503
- // eslint-disable-next-line no-restricted-properties
504
- assert.equal(messages[i].endColumn, item.errors[i].endColumn, `Error endColumn should be ${item.errors[i].endColumn}`);
536
+ if (error.hasOwnProperty("endColumn")) {
537
+ assert.strictEqual(message.endColumn, error.endColumn, `Error endColumn should be ${error.endColumn}`);
505
538
  }
506
539
  } else {
507
540
 
508
541
  // Message was an unexpected type
509
- assert.fail(messages[i], null, "Error should be a string, object, or RegExp.");
542
+ assert.fail(message, null, "Error should be a string, object, or RegExp.");
510
543
  }
511
544
  }
512
545
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Interpolate keys from an object into a string with {{ }} markers.
3
+ * @author Jed Fox
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Public Interface
10
+ //------------------------------------------------------------------------------
11
+
12
+ module.exports = (text, data) => {
13
+ if (!data) {
14
+ return text;
15
+ }
16
+ return text.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (fullMatch, term) => {
17
+ if (term in data) {
18
+ return data[term];
19
+ }
20
+
21
+ // Preserve old behavior: If parameter name not provided, don't replace it.
22
+ return fullMatch;
23
+ });
24
+ };
@@ -84,13 +84,30 @@ class SourceCode extends TokenStore {
84
84
 
85
85
  /**
86
86
  * Represents parsed source code.
87
- * @param {string} text - The source code text.
88
- * @param {ASTNode} ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
87
+ * @param {string|Object} textOrConfig - The source code text or config object.
88
+ * @param {string} textOrConfig.text - The source code text.
89
+ * @param {ASTNode} textOrConfig.ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
90
+ * @param {Object|null} textOrConfig.parserServices - The parser srevices.
91
+ * @param {ScopeManager|null} textOrConfig.scopeManager - The scope of this source code.
92
+ * @param {Object|null} textOrConfig.visitorKeys - The visitor keys to traverse AST.
93
+ * @param {ASTNode} [ast] - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
89
94
  * @constructor
90
95
  */
91
- constructor(text, ast) {
92
- validate(ast);
96
+ constructor(textOrConfig, ast) {
97
+ let text, parserServices, scopeManager, visitorKeys;
98
+
99
+ // Process overloading.
100
+ if (typeof textOrConfig === "string") {
101
+ text = textOrConfig;
102
+ } else if (typeof textOrConfig === "object" && textOrConfig !== null) {
103
+ text = textOrConfig.text;
104
+ ast = textOrConfig.ast;
105
+ parserServices = textOrConfig.parserServices;
106
+ scopeManager = textOrConfig.scopeManager;
107
+ visitorKeys = textOrConfig.visitorKeys;
108
+ }
93
109
 
110
+ validate(ast);
94
111
  super(ast.tokens, ast.comments);
95
112
 
96
113
  /**
@@ -112,6 +129,24 @@ class SourceCode extends TokenStore {
112
129
  */
113
130
  this.ast = ast;
114
131
 
132
+ /**
133
+ * The parser services of this source code.
134
+ * @type {Object}
135
+ */
136
+ this.parserServices = parserServices || {};
137
+
138
+ /**
139
+ * The scope of this source code.
140
+ * @type {ScopeManager|null}
141
+ */
142
+ this.scopeManager = scopeManager || null;
143
+
144
+ /**
145
+ * The visitor keys to traverse AST.
146
+ * @type {Object}
147
+ */
148
+ this.visitorKeys = visitorKeys || Traverser.DEFAULT_VISITOR_KEYS;
149
+
115
150
  // Check the source text for the presence of a shebang since it is parsed as a standard line comment.
116
151
  const shebangMatched = this.text.match(astUtils.SHEBANG_MATCHER);
117
152
  const hasShebang = shebangMatched && ast.comments.length && ast.comments[0].value === shebangMatched[1];
@@ -353,9 +388,9 @@ class SourceCode extends TokenStore {
353
388
  getNodeByRangeIndex(index) {
354
389
  let result = null,
355
390
  resultParent = null;
356
- const traverser = new Traverser();
357
391
 
358
- traverser.traverse(this.ast, {
392
+ Traverser.traverse(this.ast, {
393
+ visitorKeys: this.visitorKeys,
359
394
  enter(node, parent) {
360
395
  if (node.range[0] <= index && index < node.range[1]) {
361
396
  result = node;
@@ -1,6 +1,7 @@
1
1
  /**
2
- * @fileoverview Wrapper around estraverse
2
+ * @fileoverview Traverser to traverse AST trees.
3
3
  * @author Nicholas C. Zakas
4
+ * @author Toru Nagashima
4
5
  */
5
6
  "use strict";
6
7
 
@@ -8,27 +9,153 @@
8
9
  // Requirements
9
10
  //------------------------------------------------------------------------------
10
11
 
11
- const estraverse = require("estraverse");
12
+ const vk = require("eslint-visitor-keys");
13
+ const debug = require("debug")("eslint:traverser");
12
14
 
13
15
  //------------------------------------------------------------------------------
14
16
  // Helpers
15
17
  //------------------------------------------------------------------------------
16
18
 
17
- const KEY_BLACKLIST = new Set([
18
- "parent",
19
- "leadingComments",
20
- "trailingComments"
21
- ]);
19
+ /**
20
+ * Do nothing.
21
+ * @returns {void}
22
+ */
23
+ function noop() {
24
+
25
+ // do nothing.
26
+ }
27
+
28
+ /**
29
+ * Check whether the given value is an ASTNode or not.
30
+ * @param {any} x The value to check.
31
+ * @returns {boolean} `true` if the value is an ASTNode.
32
+ */
33
+ function isNode(x) {
34
+ return x !== null && typeof x === "object" && typeof x.type === "string";
35
+ }
22
36
 
23
37
  /**
24
- * Wrapper around an estraverse controller that ensures the correct keys
25
- * are visited.
26
- * @constructor
38
+ * Get the visitor keys of a given node.
39
+ * @param {Object} visitorKeys The map of visitor keys.
40
+ * @param {ASTNode} node The node to get their visitor keys.
41
+ * @returns {string[]} The visitor keys of the node.
27
42
  */
28
- class Traverser extends estraverse.Controller {
29
- traverse(node, visitor) {
30
- visitor.fallback = Traverser.getKeys;
31
- return super.traverse(node, visitor);
43
+ function getVisitorKeys(visitorKeys, node) {
44
+ let keys = visitorKeys[node.type];
45
+
46
+ if (!keys) {
47
+ keys = vk.getKeys(node);
48
+ debug("Unknown node type \"%s\": Estimated visitor keys %j", node.type, keys);
49
+ }
50
+
51
+ return keys;
52
+ }
53
+
54
+ /**
55
+ * The traverser class to traverse AST trees.
56
+ */
57
+ class Traverser {
58
+ constructor() {
59
+ this._current = null;
60
+ this._parents = [];
61
+ this._skipped = false;
62
+ this._broken = false;
63
+ this._visitorKeys = null;
64
+ this._enter = null;
65
+ this._leave = null;
66
+ }
67
+
68
+ /**
69
+ * @returns {ASTNode} The current node.
70
+ */
71
+ current() {
72
+ return this._current;
73
+ }
74
+
75
+ /**
76
+ * @returns {ASTNode[]} The ancestor nodes.
77
+ */
78
+ parents() {
79
+ return this._parents.slice(0);
80
+ }
81
+
82
+ /**
83
+ * Break the current traversal.
84
+ * @returns {void}
85
+ */
86
+ break() {
87
+ this._broken = true;
88
+ }
89
+
90
+ /**
91
+ * Skip child nodes for the current traversal.
92
+ * @returns {void}
93
+ */
94
+ skip() {
95
+ this._skipped = true;
96
+ }
97
+
98
+ /**
99
+ * Traverse the given AST tree.
100
+ * @param {ASTNode} node The root node to traverse.
101
+ * @param {Object} options The option object.
102
+ * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`.
103
+ * @param {Function} [options.enter=noop] The callback function which is called on entering each node.
104
+ * @param {Function} [options.leave=noop] The callback function which is called on leaving each node.
105
+ * @returns {void}
106
+ */
107
+ traverse(node, options) {
108
+ this._current = null;
109
+ this._parents = [];
110
+ this._skipped = false;
111
+ this._broken = false;
112
+ this._visitorKeys = options.visitorKeys || vk.KEYS;
113
+ this._enter = options.enter || noop;
114
+ this._leave = options.leave || noop;
115
+ this._traverse(node, null);
116
+ }
117
+
118
+ /**
119
+ * Traverse the given AST tree recursively.
120
+ * @param {ASTNode} node The current node.
121
+ * @param {ASTNode|null} parent The parent node.
122
+ * @returns {void}
123
+ * @private
124
+ */
125
+ _traverse(node, parent) {
126
+ if (!isNode(node)) {
127
+ return;
128
+ }
129
+
130
+ this._current = node;
131
+ this._skipped = false;
132
+ this._enter(node, parent);
133
+
134
+ if (!this._skipped && !this._broken) {
135
+ const keys = getVisitorKeys(this._visitorKeys, node);
136
+
137
+ if (keys.length >= 1) {
138
+ this._parents.push(node);
139
+ for (let i = 0; i < keys.length && !this._broken; ++i) {
140
+ const child = node[keys[i]];
141
+
142
+ if (Array.isArray(child)) {
143
+ for (let j = 0; j < child.length && !this._broken; ++j) {
144
+ this._traverse(child[j], node);
145
+ }
146
+ } else {
147
+ this._traverse(child, node);
148
+ }
149
+ }
150
+ this._parents.pop();
151
+ }
152
+ }
153
+
154
+ if (!this._broken) {
155
+ this._leave(node, parent);
156
+ }
157
+
158
+ this._current = parent;
32
159
  }
33
160
 
34
161
  /**
@@ -38,7 +165,28 @@ class Traverser extends estraverse.Controller {
38
165
  * @private
39
166
  */
40
167
  static getKeys(node) {
41
- return Object.keys(node).filter(key => !KEY_BLACKLIST.has(key));
168
+ return vk.getKeys(node);
169
+ }
170
+
171
+ /**
172
+ * Traverse the given AST tree.
173
+ * @param {ASTNode} node The root node to traverse.
174
+ * @param {Object} options The option object.
175
+ * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`.
176
+ * @param {Function} [options.enter=noop] The callback function which is called on entering each node.
177
+ * @param {Function} [options.leave=noop] The callback function which is called on leaving each node.
178
+ * @returns {void}
179
+ */
180
+ static traverse(node, options) {
181
+ new Traverser().traverse(node, options);
182
+ }
183
+
184
+ /**
185
+ * The default visitor keys.
186
+ * @type {Object}
187
+ */
188
+ static get DEFAULT_VISITOR_KEYS() {
189
+ return vk.KEYS;
42
190
  }
43
191
  }
44
192
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "4.12.1",
3
+ "version": "4.15.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -39,12 +39,12 @@
39
39
  "chalk": "^2.1.0",
40
40
  "concat-stream": "^1.6.0",
41
41
  "cross-spawn": "^5.1.0",
42
- "debug": "^3.0.1",
42
+ "debug": "^3.1.0",
43
43
  "doctrine": "^2.0.2",
44
44
  "eslint-scope": "^3.7.1",
45
+ "eslint-visitor-keys": "^1.0.0",
45
46
  "espree": "^3.5.2",
46
47
  "esquery": "^1.0.0",
47
- "estraverse": "^4.2.0",
48
48
  "esutils": "^2.0.2",
49
49
  "file-entry-cache": "^2.0.0",
50
50
  "functional-red-black-tree": "^1.0.1",