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 +42 -0
- package/README.md +12 -7
- package/lib/cli.js +9 -1
- package/lib/config/config-file.js +1 -1
- package/lib/config/config-validator.js +12 -12
- package/lib/formatters/html-template-message.html +1 -1
- package/lib/formatters/html.js +18 -6
- package/lib/formatters/json-with-metadata.js +16 -0
- package/lib/linter.js +16 -4
- package/lib/rules/implicit-arrow-linebreak.js +17 -172
- package/lib/rules/no-warning-comments.js +2 -2
- package/lib/testers/rule-tester.js +1 -1
- package/lib/util/glob-utils.js +12 -1
- package/package.json +6 -6
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
|
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
|
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
|
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,
|
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,
|
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,
|
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,
|
260
|
+
function validate(config, ruleMapper, envContext, source = null) {
|
261
261
|
validateConfigSchema(config, source);
|
262
|
-
validateRules(config.rules,
|
263
|
-
validateEnvironment(config.env,
|
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,
|
267
|
-
validateEnvironment(override.env,
|
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="
|
6
|
+
<a href="<%= ruleUrl %>" target="_blank" rel="noopener noreferrer"><%= ruleId %></a>
|
7
7
|
</td>
|
8
8
|
</tr>
|
package/lib/formatters/html.js
CHANGED
@@ -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
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
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
|
-
|
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
|
-
|
50
|
+
const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken);
|
51
|
+
const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken);
|
206
52
|
|
207
|
-
if (
|
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:
|
55
|
+
node: firstTokenOfBody,
|
217
56
|
messageId: "expected",
|
218
|
-
fix: fixer => fixer.insertTextBefore(
|
57
|
+
fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n")
|
219
58
|
});
|
220
|
-
} else if (
|
59
|
+
} else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") {
|
221
60
|
context.report({
|
222
|
-
node:
|
61
|
+
node: firstTokenOfBody,
|
223
62
|
messageId: "unexpected",
|
224
|
-
fix
|
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, "
|
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, "
|
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,
|
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),
|
package/lib/util/glob-utils.js
CHANGED
@@ -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.
|
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.
|
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.
|
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",
|