eslint 5.15.0 → 5.16.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,45 @@
1
+ v5.16.0 - March 29, 2019
2
+
3
+ * [`dfef227`](https://github.com/eslint/eslint/commit/dfef227091955a2f8f3fa8c76ad79de8a77e7955) Build: gensite passes rulesMeta to formatter rendering (#11567) (Kevin Partington)
4
+ * [`c06d38c`](https://github.com/eslint/eslint/commit/c06d38c81bd9203c904587396a65d3c8cc7f2944) Fix: Allow HTML formatter to handle no meta data (#11566) (Ilya Volodin)
5
+ * [`87a5c03`](https://github.com/eslint/eslint/commit/87a5c034977cf4538ff3539d2f8776a987c5942a) Docs: `func-style`: clarify when `allowArrowFunctions` is used (#11548) (Oliver Joseph Ash)
6
+ * [`bc3e427`](https://github.com/eslint/eslint/commit/bc3e427ee8875c53eac6b6762884b50074f1adfc) Update: pass rule meta to formatters RFC 10 (#11551) (Chris Meyer)
7
+ * [`b452f27`](https://github.com/eslint/eslint/commit/b452f270bc0b523d88d5d827c95be3096f82e99d) Chore: Update README to pull in reviewer data (#11506) (Nicholas C. Zakas)
8
+ * [`afe3d25`](https://github.com/eslint/eslint/commit/afe3d25f8afb88caee43f7202d0eb96f33a92a6b) Upgrade: Bump js-yaml dependency to fix Denial of Service vulnerability (#11550) (Vernon de Goede)
9
+ * [`4fe7eb7`](https://github.com/eslint/eslint/commit/4fe7eb7cecdc2395cf1eeaa20921bda8460b00c2) Chore: use nyc instead of istanbul (#11532) (Toru Nagashima)
10
+ * [`f16af43`](https://github.com/eslint/eslint/commit/f16af439694aab473c647d8fae47c402bd489447) Chore: fix formatters/table test (#11534) (Toru Nagashima)
11
+ * [`78358a8`](https://github.com/eslint/eslint/commit/78358a8f66e95c4fcc921f2497e8a5ec5f1537ec) Docs: fix duplicate punctuation in CLI docs (#11528) (Teddy Katz)
12
+
13
+ v5.15.3 - March 18, 2019
14
+
15
+ * [`71adc66`](https://github.com/eslint/eslint/commit/71adc665b9649b173adc76f80723b8de20664ae1) Fix: avoid moving comments in implicit-arrow-linebreak (fixes #11521) (#11522) (Teddy Katz)
16
+ * [`1f715a2`](https://github.com/eslint/eslint/commit/1f715a20c145d8ccc38f3310afccd838495d09d4) Chore: make test-case-property-ordering reasonable (#11511) (Toru Nagashima)
17
+
18
+ v5.15.2 - March 15, 2019
19
+
20
+ * [`29dbca7`](https://github.com/eslint/eslint/commit/29dbca73d762a809adb2f457b527e144426d54a7) Fix: implicit-arrow-linebreak adds extra characters (fixes #11268) (#11407) (Mark de Dios)
21
+ * [`5d2083f`](https://github.com/eslint/eslint/commit/5d2083fa3e14c024197f6c386ff72237a145e258) Upgrade: eslint-scope@4.0.3 (#11513) (Teddy Katz)
22
+ * [`a5dae7c`](https://github.com/eslint/eslint/commit/a5dae7c3d30231c2f5f075d98c2c8825899bab16) Fix: Empty glob pattern incorrectly expands to "/**" (#11476) (Ben Chauvette)
23
+ * [`448e8da`](https://github.com/eslint/eslint/commit/448e8da94d09b397e98ffcb6f22b55a578ef79c1) Chore: improve crash reporting (fixes #11304) (#11463) (Alex Zherdev)
24
+ * [`0f56dc6`](https://github.com/eslint/eslint/commit/0f56dc6d9eadad05dc3d5c9d1d9ddef94e10c5d3) Chore: make config validator params more consistent (#11435) (薛定谔的猫)
25
+ * [`d6c1122`](https://github.com/eslint/eslint/commit/d6c112289f0f16ade070865c8786831b7940ca79) Docs: Add working groups to maintainer guide (#11400) (Nicholas C. Zakas)
26
+ * [`5fdb4d3`](https://github.com/eslint/eslint/commit/5fdb4d3fb01b9d8a4c2dff71ed9cddb2f8feefb0) Build: compile deps to ES5 when generating browser file (fixes #11504) (#11505) (Teddy Katz)
27
+ * [`06fa165`](https://github.com/eslint/eslint/commit/06fa1655c3da8394ed9144d727115fc434b0416f) Build: update CI testing configuration (#11500) (Reece Dunham)
28
+ * [`956e883`](https://github.com/eslint/eslint/commit/956e883c21fd9f393bf6718d032a4e2e53b33f22) Docs: Fix example in no-restricted-modules docs (#11454) (Paul O’Shannessy)
29
+ * [`2c7431d`](https://github.com/eslint/eslint/commit/2c7431d6b32063f74e3837ee727f26af215eada7) Docs: fix json schema example dead link (#11498) (kazuya kawaguchi)
30
+ * [`e7266c2`](https://github.com/eslint/eslint/commit/e7266c2478aff5d66e7859313feb49e3a129f85e) Docs: Fix invalid JSON in "Specifying Parser Options" (#11492) (Mihira Jayasekera)
31
+ * [`6693161`](https://github.com/eslint/eslint/commit/6693161978a83e0730d5ea0fecdb627c5a2acdfd) Sponsors: Sync README with website (ESLint Jenkins)
32
+ * [`62fee4a`](https://github.com/eslint/eslint/commit/62fee4a976897d158c8c137339728cd280333286) Chore: eslint-config-eslint enable comma-dangle functions: "never" (#11434) (薛定谔的猫)
33
+ * [`34a5382`](https://github.com/eslint/eslint/commit/34a53829e7a63ff2f6b371d77ce283bbdd373b91) Build: copy bundled espree to website directory (#11478) (Pig Fang)
34
+ * [`f078f9a`](https://github.com/eslint/eslint/commit/f078f9a9e094ec00c61a6ef1c9550d017631e69a) Chore: use "file:" dependencies for internal rules/config (#11465) (Teddy Katz)
35
+ * [`0756128`](https://github.com/eslint/eslint/commit/075612871f85aa04cef8137bd32247e128ad600b) Docs: Add `visualstudio` to formatter list (#11480) (Patrick Eriksson)
36
+ * [`44de9d7`](https://github.com/eslint/eslint/commit/44de9d7e1aa2fcae475a97b8f597b7d8094566b2) Docs: Fix typo in func-name-matching rule docs (#11484) (Iulian Onofrei)
37
+
38
+ v5.15.1 - March 4, 2019
39
+
40
+ * [`fe1a892`](https://github.com/eslint/eslint/commit/fe1a892f85b09c3d2fea05bef011530a678a6af5) Build: bundle espree (fixes eslint/eslint.github.io#546) (#11467) (薛定谔的猫)
41
+ * [`458053b`](https://github.com/eslint/eslint/commit/458053b0b541f857bf233dacbde5ba80681820f8) Fix: avoid creating invalid regex in no-warning-comments (fixes #11471) (#11472) (Teddy Katz)
42
+
1
43
  v5.15.0 - March 1, 2019
2
44
 
3
45
  * [`4088c6c`](https://github.com/eslint/eslint/commit/4088c6c9d4578cd581ce8ff4385d90b58a75b755) Build: Remove path.resolve in webpack build (#11462) (Kevin Partington)
package/README.md CHANGED
@@ -193,12 +193,13 @@ According to our policy, any minor update may report more errors than the previo
193
193
 
194
194
  These folks keep the project moving and are resources for help.
195
195
 
196
+ <!-- NOTE: This section is autogenerated. Do not manually edit.-->
197
+ <!--teamstart-->
198
+
196
199
  ### Technical Steering Committee (TSC)
197
200
 
198
201
  The people who manage releases, review feature requests, and meet regularly to ensure ESLint is properly maintained.
199
202
 
200
- <!-- NOTE: This section is autogenerated. Do not manually edit.-->
201
- <!--tscstart-->
202
203
  <table><tbody><tr><td align="center" valign="top" width="11%">
203
204
  <a href="https://github.com/nzakas">
204
205
  <img src="https://github.com/nzakas.png?s=75" width="75" height="75"><br />
@@ -239,14 +240,15 @@ Kai Cataldo
239
240
  <img src="https://github.com/not-an-aardvark.png?s=75" width="75" height="75"><br />
240
241
  Teddy Katz
241
242
  </a>
242
- </td></tr></tbody></table><!--tscend-->
243
+ </td></tr></tbody></table>
244
+
245
+
246
+
243
247
 
244
248
  ### Committers
245
249
 
246
250
  The people who review and fix bugs and help triage issues.
247
251
 
248
- <!-- NOTE: This section is autogenerated. Do not manually edit.-->
249
- <!--committersstart-->
250
252
  <table><tbody><tr><td align="center" valign="top" width="11%">
251
253
  <a href="https://github.com/aladdin-add">
252
254
  <img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
@@ -257,7 +259,10 @@ The people who review and fix bugs and help triage issues.
257
259
  <img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
258
260
  Pig Fang
259
261
  </a>
260
- </td></tr></tbody></table><!--committersend-->
262
+ </td></tr></tbody></table>
263
+
264
+
265
+ <!--teamend-->
261
266
 
262
267
  ## Sponsors
263
268
 
@@ -268,7 +273,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
268
273
  <h3>Gold Sponsors</h3>
269
274
  <p><a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
270
275
  <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F68ed8b70-ebf2-11e6-9958-cb7e79408c56.png&height=96" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
271
- <p><a href="http://faithlife.com/ref/about"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Ffaithlife.com&height=96" alt="Faithlife" height="32"></a></p>
276
+ <p><a href="http://faithlife.com/ref/about"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Ffaithlife.com&height=96" alt="Faithlife" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Fjsheroes.io&height=96" alt="JSHeroes " height="32"></a></p>
272
277
  <!--sponsorsend-->
273
278
 
274
279
  ## Technology Sponsors
package/lib/cli.js CHANGED
@@ -81,15 +81,23 @@ function translateOptions(cliOptions) {
81
81
  */
82
82
  function printResults(engine, results, format, outputFile) {
83
83
  let formatter;
84
+ let rules;
84
85
 
85
86
  try {
86
87
  formatter = engine.getFormatter(format);
88
+ rules = engine.getRules();
87
89
  } catch (e) {
88
90
  log.error(e.message);
89
91
  return false;
90
92
  }
91
93
 
92
- const output = formatter(results);
94
+ const rulesMeta = {};
95
+
96
+ rules.forEach((rule, ruleId) => {
97
+ rulesMeta[ruleId] = rule.meta;
98
+ });
99
+
100
+ const output = formatter(results, { rulesMeta });
93
101
 
94
102
  if (output) {
95
103
  if (outputFile) {
@@ -541,7 +541,7 @@ function loadFromDisk(resolvedPath, configContext) {
541
541
  const ruleMap = configContext.linterContext.getRules();
542
542
 
543
543
  // validate the configuration before continuing
544
- validator.validate(config, resolvedPath.configFullName, ruleMap.get.bind(ruleMap), configContext.linterContext.environments);
544
+ validator.validate(config, ruleMap.get.bind(ruleMap), configContext.linterContext.environments, resolvedPath.configFullName);
545
545
 
546
546
  /*
547
547
  * If an `extends` property is defined, it represents a configuration file to use as
@@ -116,7 +116,7 @@ function validateRuleSchema(rule, localOptions) {
116
116
  * no source is prepended to the message.
117
117
  * @returns {void}
118
118
  */
119
- function validateRuleOptions(rule, ruleId, options, source) {
119
+ function validateRuleOptions(rule, ruleId, options, source = null) {
120
120
  if (!rule) {
121
121
  return;
122
122
  }
@@ -140,11 +140,11 @@ function validateRuleOptions(rule, ruleId, options, source) {
140
140
  /**
141
141
  * Validates an environment object
142
142
  * @param {Object} environment The environment config object to validate.
143
- * @param {string} source The name of the configuration source to report in any errors.
144
143
  * @param {Environments} envContext Env context
144
+ * @param {string} source The name of the configuration source to report in any errors.
145
145
  * @returns {void}
146
146
  */
147
- function validateEnvironment(environment, source, envContext) {
147
+ function validateEnvironment(environment, envContext, source = null) {
148
148
 
149
149
  // not having an environment is ok
150
150
  if (!environment) {
@@ -163,11 +163,11 @@ function validateEnvironment(environment, source, envContext) {
163
163
  /**
164
164
  * Validates a rules config object
165
165
  * @param {Object} rulesConfig The rules config object to validate.
166
- * @param {string} source The name of the configuration source to report in any errors.
167
166
  * @param {function(string): {create: Function}} ruleMapper A mapper function from strings to loaded rules
167
+ * @param {string} source The name of the configuration source to report in any errors.
168
168
  * @returns {void}
169
169
  */
170
- function validateRules(rulesConfig, source, ruleMapper) {
170
+ function validateRules(rulesConfig, ruleMapper, source = null) {
171
171
  if (!rulesConfig) {
172
172
  return;
173
173
  }
@@ -228,7 +228,7 @@ const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
228
228
  * @param {string} source The name of the configuration source to report in any errors.
229
229
  * @returns {void}
230
230
  */
231
- function validateConfigSchema(config, source) {
231
+ function validateConfigSchema(config, source = null) {
232
232
  validateSchema = validateSchema || ajv.compile(configSchema);
233
233
 
234
234
  if (!validateSchema(config)) {
@@ -252,19 +252,19 @@ function validateConfigSchema(config, source) {
252
252
  /**
253
253
  * Validates an entire config object.
254
254
  * @param {Object} config The config object to validate.
255
- * @param {string} source The name of the configuration source to report in any errors.
256
255
  * @param {function(string): {create: Function}} ruleMapper A mapper function from rule IDs to defined rules
257
256
  * @param {Environments} envContext The env context
257
+ * @param {string} source The name of the configuration source to report in any errors.
258
258
  * @returns {void}
259
259
  */
260
- function validate(config, source, ruleMapper, envContext) {
260
+ function validate(config, ruleMapper, envContext, source = null) {
261
261
  validateConfigSchema(config, source);
262
- validateRules(config.rules, source, ruleMapper);
263
- validateEnvironment(config.env, source, envContext);
262
+ validateRules(config.rules, ruleMapper, source);
263
+ validateEnvironment(config.env, envContext, source);
264
264
 
265
265
  for (const override of config.overrides || []) {
266
- validateRules(override.rules, source, ruleMapper);
267
- validateEnvironment(override.env, source, envContext);
266
+ validateRules(override.rules, ruleMapper, source);
267
+ validateEnvironment(override.env, envContext, source);
268
268
  }
269
269
  }
270
270
 
@@ -3,6 +3,6 @@
3
3
  <td class="clr-<%= severityNumber %>"><%= severityName %></td>
4
4
  <td><%- message %></td>
5
5
  <td>
6
- <a href="https://eslint.org/docs/rules/<%= ruleId %>" target="_blank" rel="noopener noreferrer"><%= ruleId %></a>
6
+ <a href="<%= ruleUrl %>" target="_blank" rel="noopener noreferrer"><%= ruleId %></a>
7
7
  </td>
8
8
  </tr>
@@ -62,9 +62,10 @@ function renderColor(totalErrors, totalWarnings) {
62
62
  * Get HTML (table rows) describing the messages.
63
63
  * @param {Array} messages Messages.
64
64
  * @param {int} parentIndex Index of the parent HTML row.
65
+ * @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
65
66
  * @returns {string} HTML (table rows) describing the messages.
66
67
  */
67
- function renderMessages(messages, parentIndex) {
68
+ function renderMessages(messages, parentIndex, rulesMeta) {
68
69
 
69
70
  /**
70
71
  * Get HTML (table row) describing a message.
@@ -74,6 +75,13 @@ function renderMessages(messages, parentIndex) {
74
75
  return lodash.map(messages, message => {
75
76
  const lineNumber = message.line || 0;
76
77
  const columnNumber = message.column || 0;
78
+ let ruleUrl;
79
+
80
+ if (rulesMeta) {
81
+ const meta = rulesMeta[message.ruleId];
82
+
83
+ ruleUrl = lodash.get(meta, "docs.url", null);
84
+ }
77
85
 
78
86
  return messageTemplate({
79
87
  parentIndex,
@@ -82,33 +90,37 @@ function renderMessages(messages, parentIndex) {
82
90
  severityNumber: message.severity,
83
91
  severityName: message.severity === 1 ? "Warning" : "Error",
84
92
  message: message.message,
85
- ruleId: message.ruleId
93
+ ruleId: message.ruleId,
94
+ ruleUrl
86
95
  });
87
96
  }).join("\n");
88
97
  }
89
98
 
90
99
  /**
91
100
  * @param {Array} results Test results.
101
+ * @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
92
102
  * @returns {string} HTML string describing the results.
93
103
  */
94
- function renderResults(results) {
104
+ function renderResults(results, rulesMeta) {
95
105
  return lodash.map(results, (result, index) => resultTemplate({
96
106
  index,
97
107
  color: renderColor(result.errorCount, result.warningCount),
98
108
  filePath: result.filePath,
99
109
  summary: renderSummary(result.errorCount, result.warningCount)
100
110
 
101
- }) + renderMessages(result.messages, index)).join("\n");
111
+ }) + renderMessages(result.messages, index, rulesMeta)).join("\n");
102
112
  }
103
113
 
104
114
  //------------------------------------------------------------------------------
105
115
  // Public Interface
106
116
  //------------------------------------------------------------------------------
107
117
 
108
- module.exports = function(results) {
118
+ module.exports = function(results, data) {
109
119
  let totalErrors,
110
120
  totalWarnings;
111
121
 
122
+ const metaData = data ? data.rulesMeta : {};
123
+
112
124
  totalErrors = 0;
113
125
  totalWarnings = 0;
114
126
 
@@ -122,6 +134,6 @@ module.exports = function(results) {
122
134
  date: new Date(),
123
135
  reportColor: renderColor(totalErrors, totalWarnings),
124
136
  reportSummary: renderSummary(totalErrors, totalWarnings),
125
- results: renderResults(results)
137
+ results: renderResults(results, metaData)
126
138
  });
127
139
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview JSON reporter, including rules metadata
3
+ * @author Chris Meyer
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Public Interface
9
+ //------------------------------------------------------------------------------
10
+
11
+ module.exports = function(results, data) {
12
+ return JSON.stringify({
13
+ results,
14
+ metadata: data
15
+ });
16
+ };
package/lib/linter.js CHANGED
@@ -747,10 +747,15 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
747
747
  nodeQueue.forEach(traversalInfo => {
748
748
  currentNode = traversalInfo.node;
749
749
 
750
- if (traversalInfo.isEntering) {
751
- eventGenerator.enterNode(currentNode);
752
- } else {
753
- eventGenerator.leaveNode(currentNode);
750
+ try {
751
+ if (traversalInfo.isEntering) {
752
+ eventGenerator.enterNode(currentNode);
753
+ } else {
754
+ eventGenerator.leaveNode(currentNode);
755
+ }
756
+ } catch (err) {
757
+ err.currentNode = currentNode;
758
+ throw err;
754
759
  }
755
760
  });
756
761
 
@@ -901,8 +906,15 @@ module.exports = class Linter {
901
906
  options.filename
902
907
  );
903
908
  } catch (err) {
909
+ err.message += `\nOccurred while linting ${options.filename}`;
904
910
  debug("An error occurred while traversing");
905
911
  debug("Filename:", options.filename);
912
+ if (err.currentNode) {
913
+ const { line } = err.currentNode.loc.start;
914
+
915
+ debug("Line:", line);
916
+ err.message += `:${line}`;
917
+ }
906
918
  debug("Parser Options:", parserOptions);
907
919
  debug("Parser Path:", parserName);
908
920
  debug("Settings:", settings);
@@ -4,11 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- const {
8
- isArrowToken,
9
- isParenthesised,
10
- isOpeningParenToken
11
- } = require("../util/ast-utils");
7
+ const { isCommentToken, isNotOpeningParenToken } = require("../util/ast-utils");
12
8
 
13
9
  //------------------------------------------------------------------------------
14
10
  // Rule Definition
@@ -39,153 +35,7 @@ module.exports = {
39
35
 
40
36
  create(context) {
41
37
  const sourceCode = context.getSourceCode();
42
-
43
- //----------------------------------------------------------------------
44
- // Helpers
45
- //----------------------------------------------------------------------
46
- /**
47
- * Gets the applicable preference for a particular keyword
48
- * @returns {string} The applicable option for the keyword, e.g. 'beside'
49
- */
50
- function getOption() {
51
- return context.options[0] || "beside";
52
- }
53
-
54
- /**
55
- * Formats the comments depending on whether it's a line or block comment.
56
- * @param {Comment[]} comments The array of comments between the arrow and body
57
- * @param {Integer} column The column number of the first token
58
- * @returns {string} A string of comment text joined by line breaks
59
- */
60
- function formatComments(comments, column) {
61
- const whiteSpaces = " ".repeat(column);
62
-
63
- return `${comments.map(comment => {
64
-
65
- if (comment.type === "Line") {
66
- return `//${comment.value}`;
67
- }
68
-
69
- return `/*${comment.value}*/`;
70
- }).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`;
71
- }
72
-
73
- /**
74
- * Finds the first token to prepend comments to depending on the parent type
75
- * @param {Node} node The validated node
76
- * @returns {Token|Node} The node to prepend comments to
77
- */
78
- function findFirstToken(node) {
79
- switch (node.parent.type) {
80
- case "VariableDeclarator":
81
-
82
- // If the parent is first or only declarator, return the declaration, else, declarator
83
- return sourceCode.getFirstToken(
84
- node.parent.parent.declarations.length === 1 ||
85
- node.parent.parent.declarations[0].id.name === node.parent.id.name
86
- ? node.parent.parent : node.parent
87
- );
88
- case "CallExpression":
89
- case "Property":
90
-
91
- // find the object key
92
- return sourceCode.getFirstToken(node.parent);
93
- default:
94
- return node;
95
- }
96
- }
97
-
98
- /**
99
- * Helper function for adding parentheses fixes for nodes containing nested arrow functions
100
- * @param {Fixer} fixer Fixer
101
- * @param {Token} arrow - The arrow token
102
- * @param {ASTNode} arrowBody - The arrow function body
103
- * @returns {Function[]} autofixer -- wraps function bodies with parentheses
104
- */
105
- function addParentheses(fixer, arrow, arrowBody) {
106
- const parenthesesFixes = [];
107
- let closingParentheses = "";
108
-
109
- let followingBody = arrowBody;
110
- let currentArrow = arrow;
111
-
112
- while (currentArrow) {
113
- if (!isParenthesised(sourceCode, followingBody)) {
114
- parenthesesFixes.push(
115
- fixer.insertTextAfter(currentArrow, " (")
116
- );
117
-
118
- const paramsToken = sourceCode.getTokenBefore(currentArrow, token =>
119
- isOpeningParenToken(token) || token.type === "Identifier");
120
-
121
- const whiteSpaces = " ".repeat(paramsToken.loc.start.column);
122
-
123
- closingParentheses = `\n${whiteSpaces})${closingParentheses}`;
124
- }
125
-
126
- currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken);
127
-
128
- if (currentArrow) {
129
- followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token));
130
- }
131
- }
132
-
133
- return [...parenthesesFixes,
134
- fixer.insertTextAfter(arrowBody, closingParentheses)
135
- ];
136
- }
137
-
138
- /**
139
- * Autofixes the function body to collapse onto the same line as the arrow.
140
- * If comments exist, prepends the comments before the arrow function.
141
- * If the function body contains arrow functions, appends the function bodies with parentheses.
142
- * @param {Token} arrowToken The arrow token.
143
- * @param {ASTNode} arrowBody the function body
144
- * @param {ASTNode} node The evaluated node
145
- * @returns {Function} autofixer -- validates the node to adhere to besides
146
- */
147
- function autoFixBesides(arrowToken, arrowBody, node) {
148
- return fixer => {
149
- const placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " ");
150
-
151
- const comments = sourceCode.getCommentsInside(node).filter(comment =>
152
- comment.loc.start.line < arrowBody.loc.start.line);
153
-
154
- if (comments.length) {
155
-
156
- // If the grandparent is not a variable declarator
157
- if (
158
- arrowBody.parent &&
159
- arrowBody.parent.parent &&
160
- arrowBody.parent.parent.type !== "VariableDeclarator"
161
- ) {
162
-
163
- // If any arrow functions follow, return the necessary parens fixes.
164
- if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
165
- return addParentheses(fixer, arrowToken, arrowBody);
166
- }
167
-
168
- // If any arrow functions precede, the necessary fixes have already been returned, so return null.
169
- if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
170
- return null;
171
- }
172
- }
173
-
174
- const firstToken = findFirstToken(node);
175
-
176
- const commentText = formatComments(comments, firstToken.loc.start.column);
177
-
178
- const commentBeforeExpression = fixer.insertTextBeforeRange(
179
- firstToken.range,
180
- commentText
181
- );
182
-
183
- return [placeBesides, commentBeforeExpression];
184
- }
185
-
186
- return placeBesides;
187
- };
188
- }
38
+ const option = context.options[0] || "beside";
189
39
 
190
40
  /**
191
41
  * Validates the location of an arrow function body
@@ -193,35 +43,30 @@ module.exports = {
193
43
  * @returns {void}
194
44
  */
195
45
  function validateExpression(node) {
196
- const option = getOption();
197
-
198
- let tokenBefore = sourceCode.getTokenBefore(node.body);
199
- const hasParens = tokenBefore.value === "(";
200
-
201
- if (node.type === "BlockStatement") {
46
+ if (node.body.type === "BlockStatement") {
202
47
  return;
203
48
  }
204
49
 
205
- let fixerTarget = node.body;
50
+ const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken);
51
+ const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken);
206
52
 
207
- if (hasParens) {
208
-
209
- // Gets the first token before the function body that is not an open paren
210
- tokenBefore = sourceCode.getTokenBefore(node.body, token => token.value !== "(");
211
- fixerTarget = sourceCode.getTokenAfter(tokenBefore);
212
- }
213
-
214
- if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") {
53
+ if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") {
215
54
  context.report({
216
- node: fixerTarget,
55
+ node: firstTokenOfBody,
217
56
  messageId: "expected",
218
- fix: fixer => fixer.insertTextBefore(fixerTarget, "\n")
57
+ fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n")
219
58
  });
220
- } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") {
59
+ } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") {
221
60
  context.report({
222
- node: fixerTarget,
61
+ node: firstTokenOfBody,
223
62
  messageId: "unexpected",
224
- fix: autoFixBesides(tokenBefore, fixerTarget, node)
63
+ fix(fixer) {
64
+ if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) {
65
+ return null;
66
+ }
67
+
68
+ return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " ");
69
+ }
225
70
  });
226
71
  }
227
72
  }
@@ -95,7 +95,7 @@ module.exports = {
95
95
  * ^\s*TERM\b. This checks the word boundary
96
96
  * at the beginning of the comment.
97
97
  */
98
- return new RegExp(prefix + escaped + suffix, "iu");
98
+ return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
99
99
  }
100
100
 
101
101
  /*
@@ -103,7 +103,7 @@ module.exports = {
103
103
  * \bTERM\b|\bTERM\b, this checks the entire comment
104
104
  * for the term.
105
105
  */
106
- return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "iu");
106
+ return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
107
107
  }
108
108
 
109
109
  const warningRegExps = warningTerms.map(convertToRegExp);
@@ -379,7 +379,7 @@ class RuleTester {
379
379
  }
380
380
  }
381
381
 
382
- validator.validate(config, "rule-tester", ruleMap.get.bind(ruleMap), new Environments());
382
+ validator.validate(config, ruleMap.get.bind(ruleMap), new Environments(), "rule-tester");
383
383
 
384
384
  return {
385
385
  messages: linter.verify(code, config, filename, true),
@@ -70,6 +70,10 @@ function processPath(options) {
70
70
  * @private
71
71
  */
72
72
  return function(pathname) {
73
+ if (pathname === "") {
74
+ return "";
75
+ }
76
+
73
77
  let newPath = pathname;
74
78
  const resolvedPath = path.resolve(cwd, pathname);
75
79
 
@@ -201,6 +205,13 @@ function listFilesToProcess(globPatterns, providedOptions) {
201
205
 
202
206
  debug("Creating list of files to process.");
203
207
  const resolvedPathsByGlobPattern = resolvedGlobPatterns.map(pattern => {
208
+ if (pattern === "") {
209
+ return [{
210
+ filename: "",
211
+ behavior: SILENTLY_IGNORE
212
+ }];
213
+ }
214
+
204
215
  const file = path.resolve(cwd, pattern);
205
216
 
206
217
  if (options.globInputPaths === false || (fs.existsSync(file) && fs.statSync(file).isFile())) {
@@ -240,7 +251,7 @@ function listFilesToProcess(globPatterns, providedOptions) {
240
251
  });
241
252
 
242
253
  const allPathDescriptors = resolvedPathsByGlobPattern.reduce((pathsForAllGlobs, pathsForCurrentGlob, index) => {
243
- if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE)) {
254
+ if (pathsForCurrentGlob.every(pathDescriptor => pathDescriptor.behavior === SILENTLY_IGNORE && pathDescriptor.filename !== "")) {
244
255
  throw new (pathsForCurrentGlob.length ? AllFilesIgnoredError : NoFilesFoundError)(globPatterns[index]);
245
256
  }
246
257
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "5.15.0",
3
+ "version": "5.16.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -41,7 +41,7 @@
41
41
  "cross-spawn": "^6.0.5",
42
42
  "debug": "^4.0.1",
43
43
  "doctrine": "^3.0.0",
44
- "eslint-scope": "^4.0.2",
44
+ "eslint-scope": "^4.0.3",
45
45
  "eslint-utils": "^1.3.1",
46
46
  "eslint-visitor-keys": "^1.0.0",
47
47
  "espree": "^5.0.1",
@@ -55,7 +55,7 @@
55
55
  "import-fresh": "^3.0.0",
56
56
  "imurmurhash": "^0.1.4",
57
57
  "inquirer": "^6.2.2",
58
- "js-yaml": "^3.12.0",
58
+ "js-yaml": "^3.13.0",
59
59
  "json-stable-stringify-without-jsonify": "^1.0.1",
60
60
  "levn": "^0.3.0",
61
61
  "lodash": "^4.17.11",
@@ -85,14 +85,13 @@
85
85
  "coveralls": "^3.0.1",
86
86
  "dateformat": "^3.0.3",
87
87
  "ejs": "^2.6.1",
88
+ "eslint-config-eslint": "file:packages/eslint-config-eslint",
88
89
  "eslint-plugin-eslint-plugin": "^2.0.1",
90
+ "eslint-plugin-internal-rules": "file:tools/internal-rules",
89
91
  "eslint-plugin-node": "^8.0.0",
90
- "eslint-plugin-rulesdir": "^0.1.0",
91
92
  "eslint-release": "^1.2.0",
92
- "eslint-rule-composer": "^0.3.0",
93
93
  "eslump": "^2.0.0",
94
94
  "esprima": "^4.0.1",
95
- "istanbul": "^0.4.5",
96
95
  "jsdoc": "^3.5.5",
97
96
  "karma": "^3.1.4",
98
97
  "karma-chrome-launcher": "^2.2.0",
@@ -105,6 +104,7 @@
105
104
  "mocha": "^5.0.5",
106
105
  "mock-fs": "^4.8.0",
107
106
  "npm-license": "^0.3.3",
107
+ "nyc": "^13.3.0",
108
108
  "proxyquire": "^2.0.1",
109
109
  "puppeteer": "^1.12.2",
110
110
  "shelljs": "^0.8.2",