eslint-plugin-ember
Advanced tools
Comparing version 6.9.0 to 6.9.1
@@ -0,1 +1,10 @@ | ||
## v6.9.1 (2019-08-14) | ||
#### :bug: Bug Fix | ||
* [#472](https://github.com/ember-cli/eslint-plugin-ember/pull/472) Improve handling of nested keys inside braces for `require-computed-property-dependencies` rule ([@bmish](https://github.com/bmish)) | ||
* [#471](https://github.com/ember-cli/eslint-plugin-ember/pull/471) Improve detection of missing dependencies in `require-computed-property-dependencies` rule ([@bmish](https://github.com/bmish)) | ||
#### Committers: 1 | ||
- Bryan Mishkin ([@bmish](https://github.com/bmish)) | ||
## v6.9.0 (2019-08-12) | ||
@@ -2,0 +11,0 @@ |
@@ -189,4 +189,3 @@ 'use strict'; | ||
utils.isMemberExpression(child) && | ||
!utils.isCallExpression(child.parent) && | ||
!utils.isMemberExpression(child.parent) && | ||
!(utils.isCallExpression(child.parent) && child.parent.callee === child) && | ||
propertyGetterUtils.isSimpleThisExpression(child) | ||
@@ -277,3 +276,3 @@ ) { | ||
function keyExistsAsPrefixInList(keys, key) { | ||
return keys.some(currentKey => currentKey.startsWith(`${key}.`)); | ||
return keys.some(currentKey => computedPropertyDependencyMatchesKeyPath(currentKey, key)); | ||
} | ||
@@ -328,17 +327,19 @@ | ||
const undeclaredKeys = usedKeys | ||
.filter(usedKey => | ||
expandedDeclaredKeys.every( | ||
declaredKey => | ||
declaredKey !== usedKey && | ||
!computedPropertyDependencyMatchesKeyPath(declaredKey, usedKey) | ||
const undeclaredKeys = removeRedundantKeys( | ||
usedKeys | ||
.filter(usedKey => | ||
expandedDeclaredKeys.every( | ||
declaredKey => | ||
declaredKey !== usedKey && | ||
!computedPropertyDependencyMatchesKeyPath(declaredKey, usedKey) | ||
) | ||
) | ||
) | ||
.reduce((keys, key) => { | ||
if (keys.indexOf(key) < 0) { | ||
keys.push(key); | ||
} | ||
return keys; | ||
}, []) | ||
.sort(); | ||
.reduce((keys, key) => { | ||
if (keys.indexOf(key) < 0) { | ||
keys.push(key); | ||
} | ||
return keys; | ||
}, []) | ||
.sort() | ||
); | ||
@@ -352,3 +353,3 @@ if (undeclaredKeys.length > 0) { | ||
fix(fixer) { | ||
const missingDependenciesAsArguments = dependencyKeys( | ||
const missingDependenciesAsArguments = collapseKeys( | ||
removeRedundantKeys([...undeclaredKeys, ...expandedDeclaredKeys]) | ||
@@ -381,7 +382,12 @@ ); | ||
/** | ||
* ["foo.bar", "foo.baz", "quux.[]"] => "'foo.{bar,baz}', 'quux.[]'" | ||
* Collapse dependency keys with braces if possible. | ||
* | ||
* Example: | ||
* Input: ["foo.bar", "foo.baz", "quux.[]"] | ||
* Output: "'foo.{bar,baz}', 'quux.[]'" | ||
* | ||
* @param {Array<string>} keys | ||
* @returns string | ||
*/ | ||
function dependencyKeys(keys) { | ||
function collapseKeys(keys) { | ||
const uniqueKeys = Array.from(new Set(keys)); | ||
@@ -431,2 +437,8 @@ | ||
/** | ||
* Expand any brace usage in a dependency key. | ||
* | ||
* Example: | ||
* Input: "foo.{bar,baz}" | ||
* Output: ["foo.bar", "foo.baz"] | ||
* | ||
* @param {string} key | ||
@@ -436,18 +448,28 @@ * @returns {Array<string>} | ||
function expandKey(key) { | ||
return key | ||
.split('.') // ["foo", "{bar,baz}"] | ||
.map(part => part.replace(/\{|\}/g, '').split(',')) // [["foo"], ["baz", "baz"]] | ||
.reduce( | ||
(acc, nextParts) => | ||
// iteration 1 (["foo"]): do nothing (duplicate 0 times), resulting in acc === [["foo"]] | ||
// iteration 2 (["bar", "baz"]): duplicate acc once, resulting in `[["foo"], ["foo"]] | ||
duplicateArrays(acc, nextParts.length - 1).map((base, index) => | ||
// evenly distribute the parts across the repeated base keys. | ||
// nextParts[0 % 2] => "bar" | ||
// nextParts[1 % 2] => "baz" | ||
base.concat(nextParts[index % nextParts.length]) | ||
), | ||
[[]] | ||
) // [["foo", "bar"], ["foo", "baz"]] | ||
.map(expanded => expanded.join('.')); // ["foo.bar", "foo.baz"] | ||
if (key.includes('{')) { | ||
// key = "foo.{bar,baz}" | ||
const keyParts = key.split('{'); // ["foo", "{bar,baz}"] | ||
const keyBeforeCurly = keyParts[0].substring(0, keyParts[0].length - 1); // "foo" | ||
const keyAfterCurly = keyParts[1]; // "{bar,baz}" | ||
const keyAfterCurlySplitByCommas = keyAfterCurly.replace(/\{|\}/g, '').split(','); // ["bar", "baz"] | ||
const keyRecombined = [[keyBeforeCurly], keyAfterCurlySplitByCommas]; // [["foo"], ["baz", "baz"]] | ||
return keyRecombined | ||
.reduce( | ||
(acc, nextParts) => | ||
// iteration 1 (["foo"]): do nothing (duplicate 0 times), resulting in acc === [["foo"]] | ||
// iteration 2 (["bar", "baz"]): duplicate acc once, resulting in `[["foo"], ["foo"]] | ||
duplicateArrays(acc, nextParts.length - 1).map((base, index) => | ||
// evenly distribute the parts across the repeated base keys. | ||
// nextParts[0 % 2] => "bar" | ||
// nextParts[1 % 2] => "baz" | ||
base.concat(nextParts[index % nextParts.length]) | ||
), | ||
[[]] | ||
) // [["foo", "bar"], ["foo", "baz"]] | ||
.map(expanded => expanded.join('.')); // ["foo.bar", "foo.baz"] | ||
} else { | ||
// No braces. | ||
// Example: "hello.world" | ||
return key; | ||
} | ||
} | ||
@@ -454,0 +476,0 @@ |
{ | ||
"name": "eslint-plugin-ember", | ||
"version": "6.9.0", | ||
"version": "6.9.1", | ||
"description": "Eslint plugin for Ember.js apps", | ||
@@ -64,3 +64,3 @@ "main": "lib/index.js", | ||
"@ember-data/rfc395-data": "^0.0.4", | ||
"ember-rfc176-data": "^0.3.9", | ||
"ember-rfc176-data": "^0.3.10", | ||
"snake-case": "^2.1.0" | ||
@@ -67,0 +67,0 @@ }, |
236578
5058
Updatedember-rfc176-data@^0.3.10