eslint 4.16.0 → 4.18.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 (89) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/conf/environments.js +3 -1
  3. package/conf/eslint-recommended.js +0 -0
  4. package/lib/linter.js +368 -366
  5. package/lib/rules/accessor-pairs.js +7 -3
  6. package/lib/rules/array-bracket-newline.js +11 -5
  7. package/lib/rules/array-bracket-spacing.js +11 -5
  8. package/lib/rules/array-callback-return.js +11 -5
  9. package/lib/rules/array-element-newline.js +8 -3
  10. package/lib/rules/arrow-body-style.js +16 -8
  11. package/lib/rules/arrow-parens.js +13 -9
  12. package/lib/rules/arrow-spacing.js +13 -5
  13. package/lib/rules/block-scoped-var.js +6 -2
  14. package/lib/rules/block-spacing.js +13 -6
  15. package/lib/rules/brace-style.js +16 -14
  16. package/lib/rules/callback-return.js +6 -2
  17. package/lib/rules/camelcase.js +6 -2
  18. package/lib/rules/capitalized-comments.js +11 -8
  19. package/lib/rules/class-methods-use-this.js +7 -3
  20. package/lib/rules/comma-dangle.js +7 -4
  21. package/lib/rules/comma-spacing.js +13 -10
  22. package/lib/rules/comma-style.js +9 -4
  23. package/lib/rules/complexity.js +6 -2
  24. package/lib/rules/computed-property-spacing.js +13 -5
  25. package/lib/rules/consistent-return.js +12 -7
  26. package/lib/rules/consistent-this.js +9 -4
  27. package/lib/rules/constructor-super.js +17 -8
  28. package/lib/rules/curly.js +59 -80
  29. package/lib/rules/default-case.js +6 -2
  30. package/lib/rules/dot-location.js +8 -3
  31. package/lib/rules/dot-notation.js +10 -5
  32. package/lib/rules/eol-last.js +7 -3
  33. package/lib/rules/eqeqeq.js +6 -2
  34. package/lib/rules/indent.js +0 -1
  35. package/lib/rules/key-spacing.js +3 -2
  36. package/lib/rules/keyword-spacing.js +6 -1
  37. package/lib/rules/max-len.js +2 -1
  38. package/lib/rules/no-alert.js +19 -18
  39. package/lib/rules/no-array-constructor.js +6 -2
  40. package/lib/rules/no-await-in-loop.js +75 -57
  41. package/lib/rules/no-bitwise.js +6 -2
  42. package/lib/rules/no-buffer-constructor.js +6 -3
  43. package/lib/rules/no-caller.js +6 -2
  44. package/lib/rules/no-case-declarations.js +6 -2
  45. package/lib/rules/no-catch-shadow.js +6 -2
  46. package/lib/rules/no-class-assign.js +6 -2
  47. package/lib/rules/no-compare-neg-zero.js +5 -2
  48. package/lib/rules/no-cond-assign.js +10 -4
  49. package/lib/rules/no-confusing-arrow.js +6 -2
  50. package/lib/rules/no-console.js +6 -2
  51. package/lib/rules/no-const-assign.js +6 -2
  52. package/lib/rules/no-constant-condition.js +6 -3
  53. package/lib/rules/no-continue.js +6 -2
  54. package/lib/rules/no-control-regex.js +7 -3
  55. package/lib/rules/no-debugger.js +5 -2
  56. package/lib/rules/no-delete-var.js +6 -2
  57. package/lib/rules/no-div-regex.js +6 -2
  58. package/lib/rules/no-dupe-args.js +6 -2
  59. package/lib/rules/no-dupe-class-members.js +6 -2
  60. package/lib/rules/no-dupe-keys.js +6 -2
  61. package/lib/rules/no-duplicate-case.js +6 -2
  62. package/lib/rules/no-else-return.js +7 -2
  63. package/lib/rules/no-empty-character-class.js +6 -2
  64. package/lib/rules/no-empty-function.js +6 -2
  65. package/lib/rules/no-empty-pattern.js +7 -3
  66. package/lib/rules/no-empty.js +7 -3
  67. package/lib/rules/no-eq-null.js +6 -2
  68. package/lib/rules/no-eval.js +6 -2
  69. package/lib/rules/no-ex-assign.js +6 -2
  70. package/lib/rules/no-extend-native.js +6 -2
  71. package/lib/rules/no-extra-bind.js +6 -2
  72. package/lib/rules/no-extra-boolean-cast.js +8 -3
  73. package/lib/rules/no-extra-label.js +6 -2
  74. package/lib/rules/no-extra-parens.js +5 -1
  75. package/lib/rules/no-extra-semi.js +6 -2
  76. package/lib/rules/no-self-assign.js +3 -1
  77. package/lib/rules/no-unused-vars.js +1 -1
  78. package/lib/rules/object-curly-newline.js +67 -19
  79. package/lib/rules/object-shorthand.js +9 -7
  80. package/lib/rules/padding-line-between-statements.js +6 -0
  81. package/lib/rules/require-await.js +5 -0
  82. package/lib/rules/rest-spread-spacing.js +6 -0
  83. package/lib/rules/space-unary-ops.js +1 -10
  84. package/lib/rules/template-tag-spacing.js +0 -0
  85. package/lib/util/glob-util.js +17 -4
  86. package/lib/util/interpolate.js +5 -1
  87. package/lib/util/npm-util.js +1 -1
  88. package/package.json +2 -2
  89. package/conf/default-config-options.js +0 -29
@@ -10,6 +10,7 @@
10
10
  //------------------------------------------------------------------------------
11
11
 
12
12
  const astUtils = require("../ast-utils");
13
+ const lodash = require("lodash");
13
14
 
14
15
  //------------------------------------------------------------------------------
15
16
  // Helpers
@@ -73,19 +74,57 @@ function normalizeOptionValue(value) {
73
74
  * Normalizes a given option value.
74
75
  *
75
76
  * @param {string|Object|undefined} options - An option value to parse.
76
- * @returns {{ObjectExpression: {multiline: boolean, minProperties: number}, ObjectPattern: {multiline: boolean, minProperties: number}}} Normalized option object.
77
+ * @returns {{
78
+ * ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean},
79
+ * ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean},
80
+ * ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean},
81
+ * ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean}
82
+ * }} Normalized option object.
77
83
  */
78
84
  function normalizeOptions(options) {
79
- if (options && (options.ObjectExpression || options.ObjectPattern)) {
85
+ const isNodeSpecificOption = lodash.overSome([lodash.isPlainObject, lodash.isString]);
86
+
87
+ if (lodash.isPlainObject(options) && lodash.some(options, isNodeSpecificOption)) {
80
88
  return {
81
89
  ObjectExpression: normalizeOptionValue(options.ObjectExpression),
82
- ObjectPattern: normalizeOptionValue(options.ObjectPattern)
90
+ ObjectPattern: normalizeOptionValue(options.ObjectPattern),
91
+ ImportDeclaration: normalizeOptionValue(options.ImportDeclaration),
92
+ ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration)
83
93
  };
84
94
  }
85
95
 
86
96
  const value = normalizeOptionValue(options);
87
97
 
88
- return { ObjectExpression: value, ObjectPattern: value };
98
+ return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value };
99
+ }
100
+
101
+ /**
102
+ * Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration
103
+ * node needs to be checked for missing line breaks
104
+ *
105
+ * @param {ASTNode} node - Node under inspection
106
+ * @param {Object} options - option specific to node type
107
+ * @param {Token} first - First object property
108
+ * @param {Token} last - Last object property
109
+ * @returns {boolean} `true` if node needs to be checked for missing line breaks
110
+ */
111
+ function areLineBreaksRequired(node, options, first, last) {
112
+ let objectProperties;
113
+
114
+ if (node.type === "ObjectExpression" || node.type === "ObjectPattern") {
115
+ objectProperties = node.properties;
116
+ } else {
117
+
118
+ // is ImportDeclaration or ExportNamedDeclaration
119
+ objectProperties = node.specifiers;
120
+ }
121
+
122
+ return objectProperties.length >= options.minProperties ||
123
+ (
124
+ options.multiline &&
125
+ objectProperties.length > 0 &&
126
+ first.loc.start.line !== last.loc.end.line
127
+ );
89
128
  }
90
129
 
91
130
  //------------------------------------------------------------------------------
@@ -109,7 +148,9 @@ module.exports = {
109
148
  type: "object",
110
149
  properties: {
111
150
  ObjectExpression: OPTION_VALUE,
112
- ObjectPattern: OPTION_VALUE
151
+ ObjectPattern: OPTION_VALUE,
152
+ ImportDeclaration: OPTION_VALUE,
153
+ ExportDeclaration: OPTION_VALUE
113
154
  },
114
155
  additionalProperties: false,
115
156
  minProperties: 1
@@ -125,32 +166,37 @@ module.exports = {
125
166
 
126
167
  /**
127
168
  * Reports a given node if it violated this rule.
128
- *
129
- * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node.
130
- * @param {{multiline: boolean, minProperties: number}} options - An option object.
169
+ * @param {ASTNode} node - A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node.
170
+ * @param {{multiline: boolean, minProperties: number, consistent: boolean}} options - An option object.
131
171
  * @returns {void}
132
172
  */
133
173
  function check(node) {
134
174
  const options = normalizedOptions[node.type];
175
+
176
+ if (
177
+ (node.type === "ImportDeclaration" &&
178
+ !node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) ||
179
+ (node.type === "ExportNamedDeclaration" &&
180
+ !node.specifiers.some(specifier => specifier.type === "ExportSpecifier"))
181
+ ) {
182
+ return;
183
+ }
184
+
135
185
  const openBrace = sourceCode.getFirstToken(node, token => token.value === "{");
186
+
136
187
  let closeBrace;
137
188
 
138
189
  if (node.typeAnnotation) {
139
190
  closeBrace = sourceCode.getTokenBefore(node.typeAnnotation);
140
191
  } else {
141
- closeBrace = sourceCode.getLastToken(node);
192
+ closeBrace = sourceCode.getLastToken(node, token => token.value === "}");
142
193
  }
143
194
 
144
195
  let first = sourceCode.getTokenAfter(openBrace, { includeComments: true });
145
196
  let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
146
- const needsLinebreaks = (
147
- node.properties.length >= options.minProperties ||
148
- (
149
- options.multiline &&
150
- node.properties.length > 0 &&
151
- first.loc.start.line !== last.loc.end.line
152
- )
153
- );
197
+
198
+ const needsLineBreaks = areLineBreaksRequired(node, options, first, last);
199
+
154
200
  const hasCommentsFirstToken = astUtils.isCommentToken(first);
155
201
  const hasCommentsLastToken = astUtils.isCommentToken(last);
156
202
 
@@ -165,7 +211,7 @@ module.exports = {
165
211
  first = sourceCode.getTokenAfter(openBrace);
166
212
  last = sourceCode.getTokenBefore(closeBrace);
167
213
 
168
- if (needsLinebreaks) {
214
+ if (needsLineBreaks) {
169
215
  if (astUtils.isTokenOnSameLine(openBrace, first)) {
170
216
  context.report({
171
217
  message: "Expected a line break after this opening brace.",
@@ -244,7 +290,9 @@ module.exports = {
244
290
 
245
291
  return {
246
292
  ObjectExpression: check,
247
- ObjectPattern: check
293
+ ObjectPattern: check,
294
+ ImportDeclaration: check,
295
+ ExportNamedDeclaration: check
248
296
  };
249
297
  }
250
298
  };
@@ -131,7 +131,7 @@ module.exports = {
131
131
  *
132
132
  */
133
133
  function canHaveShorthand(property) {
134
- return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
134
+ return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
135
135
  }
136
136
 
137
137
  /**
@@ -233,10 +233,11 @@ module.exports = {
233
233
  const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
234
234
  let keyPrefix = "";
235
235
 
236
+ if (node.value.async) {
237
+ keyPrefix += "async ";
238
+ }
236
239
  if (node.value.generator) {
237
- keyPrefix = "*";
238
- } else if (node.value.async) {
239
- keyPrefix = "async ";
240
+ keyPrefix += "*";
240
241
  }
241
242
 
242
243
  if (node.value.type === "FunctionExpression") {
@@ -273,10 +274,11 @@ module.exports = {
273
274
  const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
274
275
  let functionHeader = "function";
275
276
 
277
+ if (node.value.async) {
278
+ functionHeader = `async ${functionHeader}`;
279
+ }
276
280
  if (node.value.generator) {
277
- functionHeader = "function*";
278
- } else if (node.value.async) {
279
- functionHeader = "async function";
281
+ functionHeader = `${functionHeader}*`;
280
282
  }
281
283
 
282
284
  return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`);
@@ -358,6 +358,12 @@ const StatementTypes = {
358
358
  node.loc.start.line !== node.loc.end.line &&
359
359
  isBlockLikeStatement(sourceCode, node)
360
360
  },
361
+ "multiline-expression": {
362
+ test: (node, sourceCode) =>
363
+ node.loc.start.line !== node.loc.end.line &&
364
+ node.type === "ExpressionStatement" &&
365
+ !isDirectivePrologue(node, sourceCode)
366
+ },
361
367
 
362
368
  block: newNodeTypeTester("BlockStatement"),
363
369
  empty: newNodeTypeTester("EmptyStatement"),
@@ -90,6 +90,11 @@ module.exports = {
90
90
 
91
91
  AwaitExpression() {
92
92
  scopeInfo.hasAwait = true;
93
+ },
94
+ ForOfStatement(node) {
95
+ if (node.await) {
96
+ scopeInfo.hasAwait = true;
97
+ }
93
98
  }
94
99
  };
95
100
  }
@@ -47,9 +47,15 @@ module.exports = {
47
47
  switch (node.type) {
48
48
  case "SpreadElement":
49
49
  type = "spread";
50
+ if (node.parent.type === "ObjectExpression") {
51
+ type += " property";
52
+ }
50
53
  break;
51
54
  case "RestElement":
52
55
  type = "rest";
56
+ if (node.parent.type === "ObjectPattern") {
57
+ type += " property";
58
+ }
53
59
  break;
54
60
  case "ExperimentalSpreadProperty":
55
61
  type = "spread property";
@@ -66,15 +66,6 @@ module.exports = {
66
66
  node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!";
67
67
  }
68
68
 
69
- /**
70
- * Check if the node's child argument is an "ObjectExpression"
71
- * @param {ASTnode} node AST node
72
- * @returns {boolean} Whether or not the argument's type is "ObjectExpression"
73
- */
74
- function isArgumentObjectExpression(node) {
75
- return node.argument && node.argument.type && node.argument.type === "ObjectExpression";
76
- }
77
-
78
69
  /**
79
70
  * Checks if an override exists for a given operator.
80
71
  * @param {string} operator Operator
@@ -125,7 +116,7 @@ module.exports = {
125
116
  * @returns {void}
126
117
  */
127
118
  function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) {
128
- if (isArgumentObjectExpression(node)) {
119
+ if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) {
129
120
  if (secondToken.range[0] > firstToken.range[1]) {
130
121
  context.report({
131
122
  node,
File without changes
@@ -8,7 +8,8 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const fs = require("fs"),
11
+ const lodash = require("lodash"),
12
+ fs = require("fs"),
12
13
  path = require("path"),
13
14
  GlobSync = require("./glob"),
14
15
 
@@ -88,6 +89,8 @@ function resolveFileGlobPatterns(patterns, options) {
88
89
  return patterns.filter(p => p.length).map(processPathExtensions);
89
90
  }
90
91
 
92
+ const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/;
93
+
91
94
  /**
92
95
  * Build a list of absolute filesnames on which ESLint will act.
93
96
  * Ignored files are excluded from the results, as are duplicates.
@@ -107,6 +110,11 @@ function listFilesToProcess(globPatterns, options) {
107
110
 
108
111
  const cwd = (options && options.cwd) || process.cwd();
109
112
 
113
+ const getIgnorePaths = lodash.memoize(
114
+ optionsObj =>
115
+ new IgnoredPaths(optionsObj)
116
+ );
117
+
110
118
  /**
111
119
  * Executes the linter on a file defined by the `filename`. Skips
112
120
  * unsupported file extensions and any files that are already linted.
@@ -151,15 +159,20 @@ function listFilesToProcess(globPatterns, options) {
151
159
  const file = path.resolve(cwd, pattern);
152
160
 
153
161
  if (fs.existsSync(file) && fs.statSync(file).isFile()) {
154
- const ignoredPaths = new IgnoredPaths(options);
162
+ const ignoredPaths = getIgnorePaths(options);
155
163
 
156
164
  addFile(fs.realpathSync(file), true, ignoredPaths);
157
165
  } else {
158
166
 
159
167
  // regex to find .hidden or /.hidden patterns, but not ./relative or ../relative
160
- const globIncludesDotfiles = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/.test(pattern);
168
+ const globIncludesDotfiles = dotfilesPattern.test(pattern);
169
+ let newOptions = options;
170
+
171
+ if (!options.dotfiles) {
172
+ newOptions = Object.assign({}, options, { dotfiles: globIncludesDotfiles });
173
+ }
161
174
 
162
- const ignoredPaths = new IgnoredPaths(Object.assign({}, options, { dotfiles: options.dotfiles || globIncludesDotfiles }));
175
+ const ignoredPaths = getIgnorePaths(newOptions);
163
176
  const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker();
164
177
  const globOptions = {
165
178
  nodir: true,
@@ -13,7 +13,11 @@ module.exports = (text, data) => {
13
13
  if (!data) {
14
14
  return text;
15
15
  }
16
- return text.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (fullMatch, term) => {
16
+
17
+ // Substitution content for any {{ }} markers.
18
+ return text.replace(/\{\{([^{}]+?)\}\}/g, (fullMatch, termWithWhitespace) => {
19
+ const term = termWithWhitespace.trim();
20
+
17
21
  if (term in data) {
18
22
  return data[term];
19
23
  }
@@ -60,7 +60,7 @@ function installSyncSaveDev(packages) {
60
60
  if (error && error.code === "ENOENT") {
61
61
  const pluralS = packages.length > 1 ? "s" : "";
62
62
 
63
- log.error(`Could not execute npm. Please install the following package${pluralS} with your package manager of choice: ${packages.join(", ")}`);
63
+ log.error(`Could not execute npm. Please install the following package${pluralS} with a package manager of your choice: ${packages.join(", ")}`);
64
64
  }
65
65
  }
66
66
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "4.16.0",
3
+ "version": "4.18.2",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -69,7 +69,7 @@
69
69
  "semver": "^5.3.0",
70
70
  "strip-ansi": "^4.0.0",
71
71
  "strip-json-comments": "~2.0.1",
72
- "table": "^4.0.1",
72
+ "table": "4.0.2",
73
73
  "text-table": "~0.2.0"
74
74
  },
75
75
  "devDependencies": {
@@ -1,29 +0,0 @@
1
- /**
2
- * @fileoverview Default config options
3
- * @author Teddy Katz
4
- */
5
-
6
- "use strict";
7
-
8
- /**
9
- * Freezes an object and all its nested properties
10
- * @param {Object} obj The object to deeply freeze
11
- * @returns {Object} `obj` after freezing it
12
- */
13
- function deepFreeze(obj) {
14
- if (obj === null || typeof obj !== "object") {
15
- return obj;
16
- }
17
-
18
- Object.keys(obj).map(key => obj[key]).forEach(deepFreeze);
19
- return Object.freeze(obj);
20
- }
21
-
22
- module.exports = deepFreeze({
23
- env: {},
24
- globals: {},
25
- rules: {},
26
- settings: {},
27
- parser: "espree",
28
- parserOptions: {}
29
- });