Skip to content

Commit

Permalink
Merge branch 'master' into ignore-5
Browse files Browse the repository at this point in the history
* master:
  Chore: Add rel/abs path tests in `no-restricted-{imports/modules}` rules (eslint#14910)
  Upgrade: Debug 4.0.1 > 4.3.2 (eslint#14892)
  Chore: add assertions on reporting location in `semi` (eslint#14899)
  Fix: no-useless-computed-key edge cases with class fields (refs eslint#14857) (eslint#14903)
  Upgrade: `js-yaml` to v4 (eslint#14890)
  Fix: prefer-destructuring PrivateIdentifier false positive (refs eslint#14857) (eslint#14897)
  Fix: dot-notation false positive with private identifier (refs eslint#14857) (eslint#14898)
  Sponsors: Sync README with website
  Sponsors: Sync README with website
  Docs: improve rule details for `no-console` (fixes eslint#14793) (eslint#14901)
  Update: check class fields in no-extra-parens (refs eslint#14857) (eslint#14906)
  Docs: add class fields in no-multi-assign documentation (refs eslint#14857) (eslint#14907)
  Docs: add class fields in func-names documentation (refs eslint#14857) (eslint#14908)
  Upgrade: `eslint-visitor-keys` to v3 (eslint#14902)
  Upgrade: `markdownlint` dev dependencies (eslint#14883)
  Upgrade: @humanwhocodes/config-array to 0.6 (eslint#14891)
  Chore: Specify Node 14.x for Verify Files CI job (eslint#14896)
  • Loading branch information
bmish committed Aug 11, 2021
2 parents 36a7205 + 3b6cd89 commit 9279e9f
Show file tree
Hide file tree
Showing 26 changed files with 1,059 additions and 140 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -12,6 +12,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14.x'
- name: Install Packages
run: npm install
- name: Lint Files
Expand Down
1 change: 1 addition & 0 deletions .markdownlintignore
@@ -0,0 +1 @@
CHANGELOG.md
9 changes: 5 additions & 4 deletions Makefile.js
Expand Up @@ -43,7 +43,7 @@ const { cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, test } = requir
const PERF_MULTIPLIER = 13e6;

const OPEN_SOURCE_LICENSES = [
/MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u
/MIT/u, /BSD/u, /Apache/u, /ISC/u, /WTF/u, /Public Domain/u, /LGPL/u, /Python/u
];

//------------------------------------------------------------------------------
Expand All @@ -66,7 +66,8 @@ const NODE = "node ", // intentional extra space
// Files
RULE_FILES = glob.sync("lib/rules/*.js").filter(filePath => path.basename(filePath) !== "index.js"),
JSON_FILES = find("conf/").filter(fileType("json")),
MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")),
MARKDOWNLINT_IGNORED_FILES = fs.readFileSync(path.join(__dirname, ".markdownlintignore"), "utf-8").split("\n"),
MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")).filter(file => !MARKDOWNLINT_IGNORED_FILES.includes(file)),
TEST_FILES = "\"tests/{bin,lib,tools}/**/*.js\"",
PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslintrc.yml"),
PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
Expand Down Expand Up @@ -213,7 +214,7 @@ function generateRuleIndexPage() {
// `.rules` will be `undefined` if all rules in category are deprecated.
categoriesData.categories = categoriesData.categories.filter(category => !!category.rules);

const output = yaml.safeDump(categoriesData, { sortKeys: true });
const output = yaml.dump(categoriesData, { sortKeys: true });

output.to(outputFile);
}
Expand Down Expand Up @@ -389,7 +390,7 @@ function getFirstVersionOfDeletion(filePath) {
* @private
*/
function lintMarkdown(files) {
const config = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")),
const config = yaml.load(fs.readFileSync(path.join(__dirname, "./.markdownlint.yml"), "utf8")),
result = markdownlint.sync({
files,
config,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -298,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/photomatt/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
<p><a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://coinbase.com"><img src="https://avatars.githubusercontent.com/u/1885080?v=4" alt="Coinbase" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://retool.com/"><img src="https://images.opencollective.com/retool/98ea68e/logo.png" alt="Retool" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://mobilen.nu"><img src="https://images.opencollective.com/mobilen/e19860d/logo.png" alt="Mobilen" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="null"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
<p><a href="https://troypoint.com"><img src="https://images.opencollective.com/troypoint/080f96f/avatar.png" alt="TROYPOINT" height="32"></a> <a href="https://mobilen.nu"><img src="https://images.opencollective.com/mobilen/e19860d/logo.png" alt="Mobilen" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="null"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
<!--sponsorsend-->

## <a name="technology-sponsors"></a>Technology Sponsors
Expand Down
13 changes: 13 additions & 0 deletions docs/rules/dot-notation.md
Expand Up @@ -46,6 +46,19 @@ var foo = { "class": "CS 101" }
var x = foo["class"]; // Property name is a reserved word, square-bracket notation required
```

Examples of additional **correct** code for the `{ "allowKeywords": false }` option:

```js
/*eslint dot-notation: ["error", { "allowKeywords": false }]*/

class C {
#in;
foo() {
this.#in; // Dot notation is required for private identifiers
}
}
```

### allowPattern

For example, when preparing data to be sent to an external API, it is often required to use property names that include underscores. If the `camelcase` rule is in effect, these [snake case](https://en.wikipedia.org/wiki/Snake_case) properties would not be allowed. By providing an `allowPattern` to the `dot-notation` rule, these snake case properties can be accessed with bracket notation.
Expand Down
11 changes: 9 additions & 2 deletions docs/rules/func-names.md
Expand Up @@ -17,14 +17,14 @@ This rule can enforce or disallow the use of named function expressions.
This rule has a string option:

* `"always"` (default) requires function expressions to have a name
* `"as-needed"` requires function expressions to have a name, if the name cannot be assigned automatically in an ES6 environment
* `"as-needed"` requires function expressions to have a name, if the name isn't assigned automatically per the ECMAScript specification.
* `"never"` disallows named function expressions, except in recursive functions, where a name is needed

This rule has an object option:

* `"generators": "always" | "as-needed" | "never"`
* `"always"` require named generators
* `"as-needed"` require named generators if the name cannot be assigned automatically in an ES6 environment.
* `"as-needed"` require named generators if the name isn't assigned automatically per the ECMAScript specification.
* `"never"` disallow named generators where possible.

When a value for `generators` is not provided the behavior for generator functions falls back to the base option.
Expand Down Expand Up @@ -98,6 +98,13 @@ const cat = {
meow: function() {}
}

class C {
#bar = function() {};
baz = function() {};
}

quux ??= function() {};

(function bar() {
// ...
}())
Expand Down
3 changes: 2 additions & 1 deletion docs/rules/no-console.md
Expand Up @@ -9,7 +9,7 @@ console.error("That shouldn't have happened.");

## Rule Details

This rule disallows calls to methods of the `console` object.
This rule disallows calls or assignments to methods of the `console` object.

Examples of **incorrect** code for this rule:

Expand All @@ -19,6 +19,7 @@ Examples of **incorrect** code for this rule:
console.log("Log a debug level message.");
console.warn("Log a warn level message.");
console.error("Log an error level message.");
console.log = foo();
```

Examples of **correct** code for this rule:
Expand Down
16 changes: 16 additions & 0 deletions docs/rules/no-extra-parens.md
Expand Up @@ -48,6 +48,14 @@ for (a of (b));
typeof (a);

(function(){} ? a() : b());

class A {
[(x)] = 1;
}

class B {
x = (y + z);
}
```

Examples of **correct** code for this rule with the default `"all"` option:
Expand All @@ -72,6 +80,14 @@ for (a of b);
for (a in b, c);

for (a in b);

class A {
[x] = 1;
}

class B {
x = y + z;
}
```

### conditionalAssign
Expand Down
21 changes: 20 additions & 1 deletion docs/rules/no-multi-assign.md
Expand Up @@ -26,12 +26,19 @@ const foo = bar = "baz";
let a =
b =
c;

class Foo {
a = b = 10;
}

a = b = "quux";
```

Examples of **correct** code for this rule:

```js
/*eslint no-multi-assign: "error"*/

var a = 5;
var b = 5;
var c = 5;
Expand All @@ -41,13 +48,21 @@ const bar = "baz";

let a = c;
let b = c;

class Foo {
a = 10;
b = 10;
}

a = "quux";
b = "quux";
```

## Options

This rule has an object option:

* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration. Default is `false`.
* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Default is `false`.

### ignoreNonDeclaration

Expand All @@ -73,6 +88,10 @@ Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option
let a = b = "baz";

const foo = bar = 1;

class Foo {
a = b = 10;
}
```

## Related Rules
Expand Down
59 changes: 55 additions & 4 deletions docs/rules/no-useless-computed-key.md
Expand Up @@ -20,7 +20,6 @@ Examples of **incorrect** code for this rule:

```js
/*eslint no-useless-computed-key: "error"*/
/*eslint-env es6*/

var a = { ['0']: 0 };
var a = { ['0+1,234']: 0 };
Expand All @@ -41,6 +40,18 @@ var c = { a: 0 };
var c = { '0+1,234': 0 };
```

Examples of additional **correct** code for this rule:

```js
/*eslint no-useless-computed-key: "error"*/

var c = {
"__proto__": foo, // defines object's prototype

["__proto__"]: bar // defines a property named "__proto__"
};
```

## Options

This rule has an object option:
Expand All @@ -52,24 +63,64 @@ This rule has an object option:
By default, this rule does not check class declarations and class expressions,
as the default value for `enforceForClassMembers` is `false`.

When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed
keys inside of class methods, getters and setters.
When `enforceForClassMembers` is set to `true`, the rule will also disallow unnecessary computed keys inside of class fields, class methods, class getters, and class setters.

Examples of **incorrect** code for `{ "enforceForClassMembers": true }`:
Examples of **incorrect** code for this rule with the `{ "enforceForClassMembers": true }` option:

```js
/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/

class Foo {
["foo"] = "bar";

[0]() {}
['a']() {}
get ['b']() {}
set ['c'](value) {}

static ["foo"] = "bar";

static ['a']() {}
}
```

Examples of **correct** code for this rule with the `{ "enforceForClassMembers": true }` option:

```js
/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/

class Foo {
"foo" = "bar";

0() {}
'a'() {}
get 'b'() {}
set 'c'(value) {}

static "foo" = "bar";

static 'a'() {}
}
```

Examples of additional **correct** code for this rule with the `{ "enforceForClassMembers": true }` option:

```js
/*eslint no-useless-computed-key: ["error", { "enforceForClassMembers": true }]*/

class Foo {
["constructor"]; // instance field named "constructor"

"constructor"() {} // the constructor of this class

["constructor"]() {} // method named "constructor"

static ["constructor"]; // static field named "constructor"

static ["prototype"]; // runtime error, it would be a parsing error without `[]`
}
```

## When Not To Use It

If you don't want to be notified about unnecessary computed property keys, you can safely disable this rule.
11 changes: 11 additions & 0 deletions docs/rules/prefer-destructuring.md
Expand Up @@ -62,6 +62,17 @@ Examples of **correct** code when `enforceForRenamedProperties` is enabled:
var { bar: foo } = object;
```

Examples of additional **correct** code when `enforceForRenamedProperties` is enabled:

```javascript
class C {
#x;
foo() {
const bar = this.#x; // private identifiers are not allowed in destructuring
}
}
```

An example configuration, with the defaults `array` and `object` filled in, looks like this:

```json
Expand Down
2 changes: 1 addition & 1 deletion lib/cli-engine/formatters/tap.js
Expand Up @@ -31,7 +31,7 @@ function outputDiagnostics(diagnostic) {
const prefix = " ";
let output = `${prefix}---\n`;

output += prefix + yaml.safeDump(diagnostic).split("\n").join(`\n${prefix}`);
output += prefix + yaml.dump(diagnostic).split("\n").join(`\n${prefix}`);
output += "...\n";
return output;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/init/config-file.js
Expand Up @@ -63,7 +63,7 @@ function writeYAMLConfigFile(config, filePath) {
// lazy load YAML to improve performance when not used
const yaml = require("js-yaml");

const content = yaml.safeDump(config, { sortKeys: true });
const content = yaml.dump(config, { sortKeys: true });

fs.writeFileSync(filePath, content, "utf8");
}
Expand Down
1 change: 1 addition & 0 deletions lib/rules/dot-notation.js
Expand Up @@ -141,6 +141,7 @@ module.exports = {
if (
!allowKeywords &&
!node.computed &&
node.property.type === "Identifier" &&
keywords.indexOf(String(node.property.name)) !== -1
) {
context.report({
Expand Down
23 changes: 16 additions & 7 deletions lib/rules/no-extra-parens.js
Expand Up @@ -808,13 +808,6 @@ module.exports = {

CallExpression: checkCallNew,

ClassBody(node) {
node.body
.filter(member => member.type === "MethodDefinition" && member.computed && member.key)
.filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR))
.forEach(member => report(member.key));
},

ConditionalExpression(node) {
if (isReturnAssignException(node)) {
return;
Expand Down Expand Up @@ -1063,6 +1056,12 @@ module.exports = {
}
},

"MethodDefinition[computed=true]"(node) {
if (hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.key);
}
},

NewExpression: checkCallNew,

ObjectExpression(node) {
Expand Down Expand Up @@ -1090,6 +1089,16 @@ module.exports = {
}
},

PropertyDefinition(node) {
if (node.computed && hasExcessParensWithPrecedence(node.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.key);
}

if (node.value && hasExcessParensWithPrecedence(node.value, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.value);
}
},

RestElement(node) {
const argument = node.argument;

Expand Down

0 comments on commit 9279e9f

Please sign in to comment.