eslint-plugin-unicorn 20.0.0 → 20.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-unicorn",
3
- "version": "20.0.0",
3
+ "version": "20.1.0",
4
4
  "description": "Various awesome ESLint rules",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/eslint-plugin-unicorn",
@@ -36,10 +36,11 @@
36
36
  "ci-info": "^2.0.0",
37
37
  "clean-regexp": "^1.0.0",
38
38
  "eslint-ast-utils": "^1.1.0",
39
- "eslint-template-visitor": "^1.1.0",
39
+ "eslint-template-visitor": "^2.0.0",
40
40
  "eslint-utils": "^2.0.0",
41
41
  "import-modules": "^2.0.0",
42
42
  "lodash": "^4.17.15",
43
+ "pluralize": "^8.0.0",
43
44
  "read-pkg-up": "^7.0.1",
44
45
  "regexp-tree": "^0.1.21",
45
46
  "reserved-words": "^0.1.2",
@@ -2,6 +2,8 @@
2
2
  const getDocumentationUrl = require('./utils/get-documentation-url');
3
3
  const isLiteralValue = require('./utils/is-literal-value');
4
4
  const {flatten} = require('lodash');
5
+ const avoidCapture = require('./utils/avoid-capture');
6
+ const {singular} = require('pluralize');
5
7
 
6
8
  const defaultElementName = 'element';
7
9
  const isLiteralZero = node => isLiteralValue(node, 0);
@@ -261,6 +263,18 @@ const getReferencesInChildScopes = (scope, name) => {
261
263
  ];
262
264
  };
263
265
 
266
+ const getChildScopesRecursive = scope => [
267
+ scope,
268
+ ...flatten(scope.childScopes.map(scope => getChildScopesRecursive(scope)))
269
+ ];
270
+
271
+ const getSingularName = originalName => {
272
+ const singularName = singular(originalName);
273
+ if (singularName !== originalName) {
274
+ return singularName;
275
+ }
276
+ };
277
+
264
278
  const create = context => {
265
279
  const sourceCode = context.getSourceCode();
266
280
  const {scopeManager} = sourceCode;
@@ -331,11 +345,12 @@ const create = context => {
331
345
  const shouldFix = !someVariablesLeakOutOfTheLoop(node, [indexVariable, elementVariable].filter(Boolean), forScope);
332
346
 
333
347
  if (shouldFix) {
334
- problem.fix = fixer => {
348
+ problem.fix = function * (fixer) {
335
349
  const shouldGenerateIndex = isIndexVariableUsedElsewhereInTheLoopBody(indexVariable, bodyScope, arrayIdentifierName);
336
350
 
337
351
  const index = indexIdentifierName;
338
- const element = elementIdentifierName || defaultElementName;
352
+ const element = elementIdentifierName ||
353
+ avoidCapture(getSingularName(arrayIdentifierName) || defaultElementName, getChildScopesRecursive(bodyScope), context.parserOptions.ecmaVersion);
339
354
  const array = arrayIdentifierName;
340
355
 
341
356
  let declarationElement = element;
@@ -357,24 +372,24 @@ const create = context => {
357
372
  `${declarationType} [${index}, ${declarationElement}] of ${array}.entries()` :
358
373
  `${declarationType} ${declarationElement} of ${array}`;
359
374
 
360
- return [
361
- fixer.replaceTextRange([
362
- node.init.range[0],
363
- node.update.range[1]
364
- ], replacement),
365
- ...arrayReferences.map(reference => {
366
- if (reference === elementReference) {
367
- return;
368
- }
369
-
370
- return fixer.replaceText(reference.identifier.parent, element);
371
- }),
372
- elementNode && (
373
- removeDeclaration ?
374
- fixer.removeRange(getRemovalRange(elementNode, sourceCode)) :
375
- fixer.replaceText(elementNode.init, element)
376
- )
377
- ].filter(Boolean);
375
+ yield fixer.replaceTextRange([
376
+ node.init.range[0],
377
+ node.update.range[1]
378
+ ], replacement);
379
+
380
+ for (const reference of arrayReferences) {
381
+ if (reference !== elementReference) {
382
+ yield fixer.replaceText(reference.identifier.parent, element);
383
+ }
384
+ }
385
+
386
+ if (elementNode) {
387
+ if (removeDeclaration) {
388
+ yield fixer.removeRange(getRemovalRange(elementNode, sourceCode));
389
+ } else {
390
+ yield fixer.replaceText(elementNode.init, element);
391
+ }
392
+ }
378
393
  };
379
394
  }
380
395