eslint 3.9.0 → 3.10.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 (112) hide show
  1. package/CHANGELOG.md +60 -1
  2. package/LICENSE +1 -1
  3. package/README.md +1 -1
  4. package/bin/eslint.js +5 -5
  5. package/conf/eslint.json +1 -0
  6. package/lib/ast-utils.js +1 -3
  7. package/lib/cli-engine.js +9 -11
  8. package/lib/code-path-analysis/debug-helpers.js +4 -4
  9. package/lib/config/autoconfig.js +23 -35
  10. package/lib/config/config-file.js +1 -1
  11. package/lib/config/config-initializer.js +12 -20
  12. package/lib/config/config-ops.js +7 -9
  13. package/lib/config/config-rule.js +14 -18
  14. package/lib/config/config-validator.js +3 -3
  15. package/lib/config/environments.js +1 -1
  16. package/lib/config.js +2 -2
  17. package/lib/eslint.js +21 -23
  18. package/lib/file-finder.js +1 -1
  19. package/lib/formatters/checkstyle.js +2 -2
  20. package/lib/formatters/compact.js +2 -2
  21. package/lib/formatters/html.js +9 -11
  22. package/lib/formatters/jslint-xml.js +2 -2
  23. package/lib/formatters/junit.js +2 -2
  24. package/lib/formatters/stylish.js +3 -7
  25. package/lib/formatters/table.js +4 -6
  26. package/lib/formatters/tap.js +2 -2
  27. package/lib/formatters/unix.js +2 -2
  28. package/lib/formatters/visualstudio.js +2 -2
  29. package/lib/load-rules.js +1 -1
  30. package/lib/rules/arrow-body-style.js +1 -1
  31. package/lib/rules/arrow-parens.js +9 -2
  32. package/lib/rules/brace-style.js +2 -2
  33. package/lib/rules/comma-spacing.js +2 -2
  34. package/lib/rules/comma-style.js +51 -4
  35. package/lib/rules/consistent-this.js +5 -9
  36. package/lib/rules/constructor-super.js +1 -1
  37. package/lib/rules/curly.js +10 -7
  38. package/lib/rules/default-case.js +1 -3
  39. package/lib/rules/eqeqeq.js +19 -7
  40. package/lib/rules/func-names.js +23 -4
  41. package/lib/rules/global-require.js +3 -7
  42. package/lib/rules/handle-callback-err.js +1 -3
  43. package/lib/rules/id-length.js +1 -1
  44. package/lib/rules/indent.js +10 -25
  45. package/lib/rules/key-spacing.js +4 -4
  46. package/lib/rules/keyword-spacing.js +1 -1
  47. package/lib/rules/lines-around-comment.js +5 -11
  48. package/lib/rules/lines-around-directive.js +23 -4
  49. package/lib/rules/max-len.js +5 -11
  50. package/lib/rules/max-lines.js +4 -12
  51. package/lib/rules/max-statements.js +11 -2
  52. package/lib/rules/newline-after-var.js +1 -1
  53. package/lib/rules/newline-before-return.js +2 -4
  54. package/lib/rules/no-alert.js +2 -4
  55. package/lib/rules/no-class-assign.js +1 -1
  56. package/lib/rules/no-const-assign.js +1 -1
  57. package/lib/rules/no-control-regex.js +2 -2
  58. package/lib/rules/no-duplicate-case.js +1 -1
  59. package/lib/rules/no-ex-assign.js +1 -1
  60. package/lib/rules/no-extend-native.js +3 -7
  61. package/lib/rules/no-extra-boolean-cast.js +14 -3
  62. package/lib/rules/no-extra-parens.js +4 -4
  63. package/lib/rules/no-func-assign.js +1 -1
  64. package/lib/rules/no-implicit-globals.js +4 -4
  65. package/lib/rules/no-irregular-whitespace.js +3 -3
  66. package/lib/rules/no-mixed-operators.js +1 -3
  67. package/lib/rules/no-mixed-requires.js +2 -2
  68. package/lib/rules/no-mixed-spaces-and-tabs.js +3 -3
  69. package/lib/rules/no-multi-spaces.js +1 -1
  70. package/lib/rules/no-new-symbol.js +1 -1
  71. package/lib/rules/no-redeclare.js +2 -4
  72. package/lib/rules/no-restricted-globals.js +2 -2
  73. package/lib/rules/no-restricted-imports.js +45 -11
  74. package/lib/rules/no-restricted-modules.js +53 -36
  75. package/lib/rules/no-restricted-syntax.js +2 -4
  76. package/lib/rules/no-return-await.js +77 -0
  77. package/lib/rules/no-tabs.js +1 -1
  78. package/lib/rules/no-this-before-super.js +2 -2
  79. package/lib/rules/no-undef.js +1 -1
  80. package/lib/rules/no-underscore-dangle.js +1 -3
  81. package/lib/rules/no-unused-vars.js +2 -6
  82. package/lib/rules/no-use-before-define.js +1 -1
  83. package/lib/rules/no-useless-escape.js +8 -54
  84. package/lib/rules/no-useless-return.js +6 -0
  85. package/lib/rules/no-warning-comments.js +2 -2
  86. package/lib/rules/object-shorthand.js +21 -10
  87. package/lib/rules/one-var-declaration-per-line.js +1 -1
  88. package/lib/rules/prefer-const.js +1 -3
  89. package/lib/rules/prefer-reflect.js +2 -1
  90. package/lib/rules/quote-props.js +1 -1
  91. package/lib/rules/quotes.js +1 -1
  92. package/lib/rules/radix.js +2 -2
  93. package/lib/rules/require-jsdoc.js +8 -0
  94. package/lib/rules/sort-vars.js +1 -1
  95. package/lib/rules/space-in-parens.js +1 -1
  96. package/lib/rules/space-infix-ops.js +1 -1
  97. package/lib/rules/spaced-comment.js +1 -1
  98. package/lib/rules/symbol-description.js +1 -1
  99. package/lib/rules/valid-jsdoc.js +3 -3
  100. package/lib/rules.js +2 -2
  101. package/lib/testers/event-generator-tester.js +5 -5
  102. package/lib/testers/rule-tester.js +11 -13
  103. package/lib/timing.js +11 -13
  104. package/lib/util/comment-event-generator.js +1 -1
  105. package/lib/util/glob-util.js +3 -5
  106. package/lib/util/npm-util.js +1 -1
  107. package/lib/util/source-code-fixer.js +3 -5
  108. package/lib/util/source-code-util.js +4 -4
  109. package/lib/util/source-code.js +3 -3
  110. package/lib/util/traverser.js +1 -3
  111. package/lib/util/xml-escape.js +1 -1
  112. package/package.json +3 -3
@@ -22,9 +22,7 @@ module.exports = {
22
22
  type: "array",
23
23
  items: [
24
24
  {
25
- enum: Object.keys(nodeTypes).map(function(k) {
26
- return nodeTypes[k];
27
- })
25
+ enum: Object.keys(nodeTypes).map(k => nodeTypes[k])
28
26
  }
29
27
  ],
30
28
  uniqueItems: true,
@@ -43,7 +41,7 @@ module.exports = {
43
41
  context.report(node, "Using '{{type}}' is not allowed.", node);
44
42
  }
45
43
 
46
- return context.options.reduce(function(result, nodeType) {
44
+ return context.options.reduce((result, nodeType) => {
47
45
  result[nodeType] = warn;
48
46
 
49
47
  return result;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @fileoverview Disallows unnecessary `return await`
3
+ * @author Jordan Harband
4
+ */
5
+ "use strict";
6
+
7
+ const astUtils = require("../ast-utils");
8
+
9
+ //------------------------------------------------------------------------------
10
+ // Rule Definition
11
+ //------------------------------------------------------------------------------
12
+
13
+ const message = "Redundant use of `await` on a return value.";
14
+
15
+ module.exports = {
16
+ meta: {
17
+ docs: {
18
+ description: "disallow unnecessary `return await`",
19
+ category: "Best Practices",
20
+ recommended: false // TODO: set to true
21
+ },
22
+ fixable: false,
23
+ schema: [
24
+ ]
25
+ },
26
+
27
+ create(context) {
28
+
29
+ /**
30
+ * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting
31
+ * this function. For example, a statement in a `try` block will always have an error handler. A statement in
32
+ * a `catch` block will only have an error handler if there is also a `finally` block.
33
+ * @param {ASTNode} node A node representing a location where an could be thrown
34
+ * @returns {boolean} `true` if a thrown error will be caught/handled in this function
35
+ */
36
+ function hasErrorHandler(node) {
37
+ let ancestor = node;
38
+
39
+ while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") {
40
+ if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) {
41
+ return true;
42
+ }
43
+ ancestor = ancestor.parent;
44
+ }
45
+ return false;
46
+ }
47
+
48
+ return {
49
+ ArrowFunctionExpression(node) {
50
+ if (node.async && node.body.type === "AwaitExpression") {
51
+ const sourceCode = context.getSourceCode();
52
+ const loc = node.body.loc;
53
+
54
+ context.report({
55
+ node: sourceCode.getFirstToken(node.body),
56
+ loc,
57
+ message,
58
+ });
59
+ }
60
+ },
61
+ ReturnStatement(node) {
62
+ const argument = node.argument;
63
+
64
+ if (argument && argument.type === "AwaitExpression" && !hasErrorHandler(node)) {
65
+ const sourceCode = context.getSourceCode();
66
+ const loc = argument.loc;
67
+
68
+ context.report({
69
+ node: sourceCode.getFirstToken(argument),
70
+ loc,
71
+ message,
72
+ });
73
+ }
74
+ },
75
+ };
76
+ }
77
+ };
@@ -17,7 +17,7 @@ const regex = /\t/;
17
17
  module.exports = {
18
18
  meta: {
19
19
  docs: {
20
- description: "disallow tabs in file",
20
+ description: "disallow all tabs",
21
21
  category: "Stylistic Issues",
22
22
  recommended: false
23
23
  },
@@ -179,7 +179,7 @@ module.exports = {
179
179
  return;
180
180
  }
181
181
 
182
- codePath.traverseSegments(function(segment, controller) {
182
+ codePath.traverseSegments((segment, controller) => {
183
183
  const info = segInfoMap[segment.id];
184
184
 
185
185
  for (let i = 0; i < info.invalidNodes.length; ++i) {
@@ -237,7 +237,7 @@ module.exports = {
237
237
  // Update information inside of the loop.
238
238
  funcInfo.codePath.traverseSegments(
239
239
  {first: toSegment, last: fromSegment},
240
- function(segment, controller) {
240
+ (segment, controller) => {
241
241
  const info = segInfoMap[segment.id];
242
242
 
243
243
  if (info.superCalled) {
@@ -52,7 +52,7 @@ module.exports = {
52
52
  "Program:exit"(/* node */) {
53
53
  const globalScope = context.getScope();
54
54
 
55
- globalScope.through.forEach(function(ref) {
55
+ globalScope.through.forEach(ref => {
56
56
  const identifier = ref.identifier;
57
57
 
58
58
  if (!considerTypeOf && hasTypeOfOperator(identifier)) {
@@ -57,9 +57,7 @@ module.exports = {
57
57
  * @private
58
58
  */
59
59
  function isAllowed(identifier) {
60
- return ALLOWED_VARIABLES.some(function(ident) {
61
- return ident === identifier;
62
- });
60
+ return ALLOWED_VARIABLES.some(ident => ident === identifier);
63
61
  }
64
62
 
65
63
  /**
@@ -390,15 +390,11 @@ module.exports = {
390
390
  * @private
391
391
  */
392
392
  function isUsedVariable(variable) {
393
- const functionNodes = variable.defs.filter(function(def) {
394
- return def.type === "FunctionName";
395
- }).map(function(def) {
396
- return def.node;
397
- }),
393
+ const functionNodes = variable.defs.filter(def => def.type === "FunctionName").map(def => def.node),
398
394
  isFunctionDefinition = functionNodes.length > 0;
399
395
  let rhsNode = null;
400
396
 
401
- return variable.references.some(function(ref) {
397
+ return variable.references.some(ref => {
402
398
  if (isForInRef(ref)) {
403
399
  return true;
404
400
  }
@@ -187,7 +187,7 @@ module.exports = {
187
187
  * @private
188
188
  */
189
189
  function findVariablesInScope(scope) {
190
- scope.references.forEach(function(reference) {
190
+ scope.references.forEach(reference => {
191
191
  const variable = reference.resolved;
192
192
 
193
193
  // Skips when the reference is:
@@ -22,55 +22,10 @@ function union(setA, setB) {
22
22
  }());
23
23
  }
24
24
 
25
- const VALID_STRING_ESCAPES = [
26
- "\\",
27
- "n",
28
- "r",
29
- "v",
30
- "t",
31
- "b",
32
- "f",
33
- "u",
34
- "x",
35
- "\n",
36
- "\r"
37
- ];
38
-
39
- const REGEX_GENERAL_ESCAPES = new Set([
40
- "\\",
41
- "b",
42
- "c",
43
- "d",
44
- "D",
45
- "f",
46
- "n",
47
- "r",
48
- "s",
49
- "S",
50
- "t",
51
- "v",
52
- "w",
53
- "W",
54
- "x",
55
- "u"
56
- ]);
57
- const REGEX_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set(["]"]));
58
- const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set([
59
- "^",
60
- "/",
61
- ".",
62
- "$",
63
- "*",
64
- "+",
65
- "?",
66
- "[",
67
- "{",
68
- "}",
69
- "|",
70
- "(",
71
- ")",
72
- "B"
73
- ]));
25
+ const VALID_STRING_ESCAPES = new Set("\\nrvtbfux\n\r");
26
+ const REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnrsStvwWxu0123456789");
27
+ const REGEX_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("]"));
28
+ const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()B"));
74
29
 
75
30
  /**
76
31
  * Parses a regular expression into a list of characters with character class info.
@@ -150,15 +105,14 @@ module.exports = {
150
105
  * Checks if the escape character in given string slice is unnecessary.
151
106
  *
152
107
  * @private
153
- * @param {string[]} escapes - list of valid escapes
154
108
  * @param {ASTNode} node - node to validate.
155
109
  * @param {string} match - string slice to validate.
156
110
  * @returns {void}
157
111
  */
158
- function validateString(escapes, node, match) {
112
+ function validateString(node, match) {
159
113
  const isTemplateElement = node.type === "TemplateElement";
160
114
  const escapedChar = match[0][1];
161
- let isUnnecessaryEscape = escapes.indexOf(escapedChar) === -1;
115
+ let isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar);
162
116
  let isQuoteEscape;
163
117
 
164
118
  if (isTemplateElement) {
@@ -208,14 +162,14 @@ module.exports = {
208
162
  * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/.
209
163
  * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25.
210
164
  */
211
- if (node.parent.type === "JSXAttribute") {
165
+ if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement") {
212
166
  return;
213
167
  }
214
168
 
215
169
  let match;
216
170
 
217
171
  while ((match = pattern.exec(value))) {
218
- validateString(VALID_STRING_ESCAPES, node, match);
172
+ validateString(node, match);
219
173
  }
220
174
  } else if (node.regex) {
221
175
  parseRegExp(node.regex.pattern)
@@ -107,6 +107,7 @@ module.exports = {
107
107
 
108
108
  create(context) {
109
109
  const segmentInfoMap = new WeakMap();
110
+ const usedUnreachableSegments = new WeakSet();
110
111
  let scopeInfo = null;
111
112
 
112
113
  /**
@@ -175,8 +176,10 @@ module.exports = {
175
176
  */
176
177
  function markReturnStatementsOnSegmentAsUsed(segment) {
177
178
  if (!segment.reachable) {
179
+ usedUnreachableSegments.add(segment);
178
180
  segment.allPrevSegments
179
181
  .filter(isReturned)
182
+ .filter(prevSegment => !usedUnreachableSegments.has(prevSegment))
180
183
  .forEach(markReturnStatementsOnSegmentAsUsed);
181
184
  return;
182
185
  }
@@ -254,6 +257,9 @@ module.exports = {
254
257
 
255
258
  // Adds ReturnStatement node to check whether it's useless or not.
256
259
  ReturnStatement(node) {
260
+ if (node.argument) {
261
+ markReturnStatementsOnCurrentSegmentsAsUsed();
262
+ }
257
263
  if (node.argument || isInLoop(node) || isInFinally(node)) {
258
264
  return;
259
265
  }
@@ -95,7 +95,7 @@ module.exports = {
95
95
  function commentContainsWarningTerm(comment) {
96
96
  const matches = [];
97
97
 
98
- warningRegExps.forEach(function(regex, index) {
98
+ warningRegExps.forEach((regex, index) => {
99
99
  if (regex.test(comment)) {
100
100
  matches.push(warningTerms[index]);
101
101
  }
@@ -116,7 +116,7 @@ module.exports = {
116
116
 
117
117
  const matches = commentContainsWarningTerm(node.value);
118
118
 
119
- matches.forEach(function(matchedTerm) {
119
+ matches.forEach(matchedTerm => {
120
120
  context.report({
121
121
  node,
122
122
  message: "Unexpected '{{matchedTerm}}' comment.",
@@ -100,6 +100,7 @@ module.exports = {
100
100
  const PARAMS = context.options[1] || {};
101
101
  const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors;
102
102
  const AVOID_QUOTES = PARAMS.avoidQuotes;
103
+ const sourceCode = context.getSourceCode();
103
104
 
104
105
  //--------------------------------------------------------------------------
105
106
  // Helpers
@@ -296,14 +297,19 @@ module.exports = {
296
297
  node,
297
298
  message: "Expected method shorthand.",
298
299
  fix(fixer) {
300
+
301
+ // NOTE: If this rule is enhanced to handle arrow functions as well, this logic needs to be updated.
302
+ const functionToken = sourceCode.getTokens(node).find(token => token.type === "Keyword" && token.value === "function");
303
+
299
304
  if (node.value.generator) {
300
- return fixer.replaceTextRange(
301
- [node.key.range[0], node.value.range[0] + "function*".length],
302
- `*[${node.key.name}]`
303
- );
305
+ return fixer.replaceTextRange([sourceCode.getTokenBefore(node.key).range[0], sourceCode.getTokenAfter(functionToken).range[1]], `*[${sourceCode.getText(node.key)}]`);
306
+ }
307
+
308
+ if (node.value.async) {
309
+ return fixer.replaceTextRange([sourceCode.getTokenBefore(node.key).range[0], functionToken.range[1]], `async [${sourceCode.getText(node.key)}]`);
304
310
  }
305
311
 
306
- return fixer.removeRange([node.key.range[1] + 1, node.value.range[0] + "function".length]);
312
+ return fixer.removeRange([sourceCode.getTokenAfter(node.key).range[1], functionToken.range[1]]);
307
313
  }
308
314
  });
309
315
  return;
@@ -314,14 +320,19 @@ module.exports = {
314
320
  node,
315
321
  message: "Expected method shorthand.",
316
322
  fix(fixer) {
323
+
324
+ // NOTE: If this rule is enhanced to handle arrow functions as well, this logic needs to be updated.
325
+ const functionToken = sourceCode.getTokens(node).find(token => token.type === "Keyword" && token.value === "function");
326
+
317
327
  if (node.value.generator) {
318
- return fixer.replaceTextRange(
319
- [node.key.range[0], node.value.range[0] + "function*".length],
320
- `*${node.key.name}`
321
- );
328
+ return fixer.replaceTextRange([node.key.range[0], sourceCode.getTokenAfter(functionToken).range[1]], `*${sourceCode.getText(node.key)}`);
329
+ }
330
+
331
+ if (node.value.async) {
332
+ return fixer.replaceTextRange([node.key.range[0], functionToken.range[1]], `async ${sourceCode.getText(node.key)}`);
322
333
  }
323
334
 
324
- return fixer.removeRange([node.key.range[1], node.value.range[0] + "function".length]);
335
+ return fixer.removeRange([node.key.range[1], functionToken.range[1]]);
325
336
  }
326
337
  });
327
338
  } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) {
@@ -59,7 +59,7 @@ module.exports = {
59
59
  const declarations = node.declarations;
60
60
  let prev;
61
61
 
62
- declarations.forEach(function(current) {
62
+ declarations.forEach(current => {
63
63
  if (prev && prev.loc.end.line === current.loc.start.line) {
64
64
  if (always || prev.init || current.init) {
65
65
  context.report({
@@ -270,9 +270,7 @@ module.exports = {
270
270
  message: "'{{name}}' is never reassigned. Use 'const' instead.",
271
271
  data: node
272
272
  },
273
- varDeclParent = findUp(node, "VariableDeclaration", function(parentNode) {
274
- return lodash.endsWith(parentNode.type, "Statement");
275
- }),
273
+ varDeclParent = findUp(node, "VariableDeclaration", parentNode => lodash.endsWith(parentNode.type, "Statement")),
276
274
  isNormalVarDecl = (node.parent.parent.parent.type === "ForInStatement" ||
277
275
  node.parent.parent.parent.type === "ForOfStatement" ||
278
276
  node.parent.init),
@@ -14,7 +14,8 @@ module.exports = {
14
14
  docs: {
15
15
  description: "require `Reflect` methods where applicable",
16
16
  category: "ECMAScript 6",
17
- recommended: false
17
+ recommended: false,
18
+ replacedBy: []
18
19
  },
19
20
 
20
21
  deprecated: true,
@@ -213,7 +213,7 @@ module.exports = {
213
213
  let keywordKeyName = null,
214
214
  necessaryQuotes = false;
215
215
 
216
- node.properties.forEach(function(property) {
216
+ node.properties.forEach(property => {
217
217
  const key = property.key;
218
218
  let tokens;
219
219
 
@@ -51,7 +51,7 @@ QUOTE_SETTINGS.backtick.convert = function(str) {
51
51
  if (newQuote === oldQuote) {
52
52
  return str;
53
53
  }
54
- return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, function(match, escaped, newline) {
54
+ return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, (match, escaped, newline) => {
55
55
  if (escaped === oldQuote || oldQuote === "`" && escaped === "${") {
56
56
  return escaped; // unescape
57
57
  }
@@ -145,7 +145,7 @@ module.exports = {
145
145
  // Check `parseInt()`
146
146
  variable = astUtils.getVariableByName(scope, "parseInt");
147
147
  if (!isShadowed(variable)) {
148
- variable.references.forEach(function(reference) {
148
+ variable.references.forEach(reference => {
149
149
  const node = reference.identifier;
150
150
 
151
151
  if (astUtils.isCallee(node)) {
@@ -157,7 +157,7 @@ module.exports = {
157
157
  // Check `Number.parseInt()`
158
158
  variable = astUtils.getVariableByName(scope, "Number");
159
159
  if (!isShadowed(variable)) {
160
- variable.references.forEach(function(reference) {
160
+ variable.references.forEach(reference => {
161
161
  const node = reference.identifier.parent;
162
162
 
163
163
  if (isParseIntMethod(node) && astUtils.isCallee(node)) {
@@ -27,6 +27,9 @@ module.exports = {
27
27
  },
28
28
  FunctionDeclaration: {
29
29
  type: "boolean"
30
+ },
31
+ ArrowFunctionExpression: {
32
+ type: "boolean"
30
33
  }
31
34
  },
32
35
  additionalProperties: false
@@ -98,6 +101,11 @@ module.exports = {
98
101
  if (options.ClassDeclaration) {
99
102
  checkJsDoc(node);
100
103
  }
104
+ },
105
+ ArrowFunctionExpression(node) {
106
+ if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") {
107
+ checkJsDoc(node);
108
+ }
101
109
  }
102
110
  };
103
111
  }
@@ -37,7 +37,7 @@ module.exports = {
37
37
 
38
38
  return {
39
39
  VariableDeclaration(node) {
40
- node.declarations.reduce(function(memo, decl) {
40
+ node.declarations.reduce((memo, decl) => {
41
41
  if (decl.id.type === "ObjectPattern" || decl.id.type === "ArrayPattern") {
42
42
  return memo;
43
43
  }
@@ -220,7 +220,7 @@ module.exports = {
220
220
  exceptions = getExceptions();
221
221
  const tokens = sourceCode.tokensAndComments;
222
222
 
223
- tokens.forEach(function(token, i) {
223
+ tokens.forEach((token, i) => {
224
224
  const prevToken = tokens[i - 1];
225
225
  const nextToken = tokens[i + 1];
226
226
 
@@ -57,7 +57,7 @@ module.exports = {
57
57
  const op = tokens[i];
58
58
 
59
59
  if (
60
- op.type === "Punctuator" &&
60
+ (op.type === "Punctuator" || op.type === "Keyword") &&
61
61
  OPERATORS.indexOf(op.value) >= 0 &&
62
62
  (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0])
63
63
  ) {
@@ -240,7 +240,7 @@ module.exports = {
240
240
  const config = context.options[1] || {};
241
241
  const balanced = config.block && config.block.balanced;
242
242
 
243
- const styleRules = ["block", "line"].reduce(function(rule, type) {
243
+ const styleRules = ["block", "line"].reduce((rule, type) => {
244
244
  const markers = parseMarkersOption(config[type] && config[type].markers || config.markers);
245
245
  const exceptions = config[type] && config[type].exceptions || config.exceptions || [];
246
246
  const endNeverPattern = "[ \t]+$";
@@ -51,7 +51,7 @@ module.exports = {
51
51
  const variable = astUtils.getVariableByName(scope, "Symbol");
52
52
 
53
53
  if (variable && variable.defs.length === 0) {
54
- variable.references.forEach(function(reference) {
54
+ variable.references.forEach(reference => {
55
55
  const node = reference.identifier;
56
56
 
57
57
  if (astUtils.isCallee(node)) {
@@ -202,7 +202,7 @@ module.exports = {
202
202
 
203
203
  elements.forEach(validateType.bind(null, jsdocNode));
204
204
 
205
- typesToCheck.forEach(function(typeToCheck) {
205
+ typesToCheck.forEach(typeToCheck => {
206
206
  if (typeToCheck.expectedType &&
207
207
  typeToCheck.expectedType !== typeToCheck.currentType) {
208
208
  context.report({
@@ -254,7 +254,7 @@ module.exports = {
254
254
  return;
255
255
  }
256
256
 
257
- jsdoc.tags.forEach(function(tag) {
257
+ jsdoc.tags.forEach(tag => {
258
258
 
259
259
  switch (tag.title.toLowerCase()) {
260
260
 
@@ -352,7 +352,7 @@ module.exports = {
352
352
  const jsdocParams = Object.keys(params);
353
353
 
354
354
  if (node.params) {
355
- node.params.forEach(function(param, i) {
355
+ node.params.forEach((param, i) => {
356
356
  if (param.type === "AssignmentPattern") {
357
357
  param = param.left;
358
358
  }
package/lib/rules.js CHANGED
@@ -40,7 +40,7 @@ function define(ruleId, ruleModule) {
40
40
  function load(rulesDir, cwd) {
41
41
  const newRules = loadRules(rulesDir, cwd);
42
42
 
43
- Object.keys(newRules).forEach(function(ruleId) {
43
+ Object.keys(newRules).forEach(ruleId => {
44
44
  define(ruleId, newRules[ruleId]);
45
45
  });
46
46
  }
@@ -53,7 +53,7 @@ function load(rulesDir, cwd) {
53
53
  */
54
54
  function importPlugin(plugin, pluginName) {
55
55
  if (plugin.rules) {
56
- Object.keys(plugin.rules).forEach(function(ruleId) {
56
+ Object.keys(plugin.rules).forEach(ruleId => {
57
57
  const qualifiedRuleId = `${pluginName}/${ruleId}`,
58
58
  rule = plugin.rules[ruleId];
59
59
 
@@ -44,19 +44,19 @@ module.exports = {
44
44
  * @returns {void}
45
45
  */
46
46
  testEventGeneratorInterface(instance) {
47
- this.describe("should implement EventGenerator interface", function() {
48
- this.it("should have `emitter` property.", function() {
47
+ this.describe("should implement EventGenerator interface", () => {
48
+ this.it("should have `emitter` property.", () => {
49
49
  assert.equal(typeof instance.emitter, "object");
50
50
  assert.equal(typeof instance.emitter.emit, "function");
51
51
  });
52
52
 
53
- this.it("should have `enterNode` property.", function() {
53
+ this.it("should have `enterNode` property.", () => {
54
54
  assert.equal(typeof instance.enterNode, "function");
55
55
  });
56
56
 
57
- this.it("should have `leaveNode` property.", function() {
57
+ this.it("should have `leaveNode` property.", () => {
58
58
  assert.equal(typeof instance.leaveNode, "function");
59
59
  });
60
- }.bind(this));
60
+ });
61
61
  }
62
62
  };