Skip to content

Commit

Permalink
Use singular array element variable name in autofix for no-for-loop
Browse files Browse the repository at this point in the history
… rule (#745)
  • Loading branch information
bmish committed May 27, 2020
1 parent 48bd5c8 commit 2002093
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -40,6 +40,7 @@
"eslint-utils": "^2.0.0",
"import-modules": "^2.0.0",
"lodash": "^4.17.15",
"pluralize": "^8.0.0",
"read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.21",
"reserved-words": "^0.1.2",
Expand Down
10 changes: 9 additions & 1 deletion rules/no-for-loop.js
Expand Up @@ -3,6 +3,7 @@ const getDocumentationUrl = require('./utils/get-documentation-url');
const isLiteralValue = require('./utils/is-literal-value');
const {flatten} = require('lodash');
const avoidCapture = require('./utils/avoid-capture');
const {singular} = require('pluralize');

const defaultElementName = 'element';
const isLiteralZero = node => isLiteralValue(node, 0);
Expand Down Expand Up @@ -267,6 +268,13 @@ const getChildScopesRecursive = scope => [
...flatten(scope.childScopes.map(scope => getChildScopesRecursive(scope)))
];

const getSingularName = originalName => {
const singularName = singular(originalName);
if (singularName !== originalName) {
return singularName;
}
};

const create = context => {
const sourceCode = context.getSourceCode();
const {scopeManager} = sourceCode;
Expand Down Expand Up @@ -342,7 +350,7 @@ const create = context => {

const index = indexIdentifierName;
const element = elementIdentifierName ||
avoidCapture(defaultElementName, getChildScopesRecursive(bodyScope), context.parserOptions.ecmaVersion);
avoidCapture(getSingularName(arrayIdentifierName) || defaultElementName, getChildScopesRecursive(bodyScope), context.parserOptions.ecmaVersion);
const array = arrayIdentifierName;

let declarationElement = element;
Expand Down
51 changes: 51 additions & 0 deletions test/no-for-loop.js
Expand Up @@ -649,6 +649,57 @@ ruleTester.run('no-for-loop', rule, {
console.log(element);
console.log(element_);
}
`),

// Singularization:
...[
['plugin', 'plugins'], // Simple
['person', 'people'], // Irregular
['girlsAndBoy', 'girlsAndBoys'], // Multiple plurals
['largeCity', 'largeCities'], // CamelCase
['LARGE_CITY', 'LARGE_CITIES'], // Caps, snake_case
['element', 'news'], // No singular version, ends in s
['element', 'list'] // No singular version
].map(([elementName, arrayName]) =>
testCase(
`for(const i = 0; i < ${arrayName}.length; i++) {console.log(${arrayName}[i])}`,
`for(const ${elementName} of ${arrayName}) {console.log(${elementName})}`
)
),

// Singularization (avoid using reserved JavaScript keywords):
testCase(outdent`
for (let i = 0; i < cases.length; i++) {
console.log(cases[i]);
}
`, outdent`
for (const case_ of cases) {
console.log(case_);
}
`),
// Singularization (avoid variable name collision):
testCase(outdent`
for (let i = 0; i < cities.length; i++) {
console.log(cities[i]);
const city = foo();
console.log(city);
}
`, outdent`
for (const city_ of cities) {
console.log(city_);
const city = foo();
console.log(city);
}
`),
// Singularization (uses i):
testCase(outdent`
for (let i = 0; i < cities.length; i++) {
console.log(i, cities[i]);
}
`, outdent`
for (const [i, city] of cities.entries()) {
console.log(i, city);
}
`)
]
});
Expand Down

0 comments on commit 2002093

Please sign in to comment.