Skip to content

Commit

Permalink
Merge branch 'main' into duplicate-test-cases
Browse files Browse the repository at this point in the history
* main:
  chore: Split Docs CI from core CI (eslint#17897)
  fix: Ensure config keys are printed for config errors (eslint#17980)
  chore: delete relative-module-resolver.js (eslint#17981)
  docs: migration guide entry for `no-inner-declarations` (eslint#17977)
  docs: Update README
  feat: maintain latest ecma version in ESLint (eslint#17958)
  feat!: no-inner-declaration new default behaviour and option (eslint#17885)
  feat: add `no-useless-assignment` rule (eslint#17625)
  fix: `no-misleading-character-class` edge cases with granular errors (eslint#17970)
  feat: `no-misleading-character-class` granular errors (eslint#17515)
  docs: fix number of code-path events on custom rules page (eslint#17969)
  docs: reorder entries in v9 migration guide (eslint#17967)
  fix!: handle `--output-file` for empty output when saving to disk (eslint#17957)
  • Loading branch information
bmish committed Jan 12, 2024
2 parents fbce335 + 1bf2520 commit 85b5070
Show file tree
Hide file tree
Showing 44 changed files with 3,270 additions and 315 deletions.
22 changes: 10 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,26 @@ jobs:
node-version: 'lts/*'
- name: Install Packages
run: npm install --force

- name: Install Docs Packages
working-directory: docs
run: npm install

- name: Lint Files
run: node Makefile lint

- name: Check Rule Files
run: node Makefile checkRuleFiles

- name: Check Licenses
run: node Makefile checkLicenses
- name: Install Docs Packages
working-directory: docs
run: npm install
- name: Stylelint Docs
working-directory: docs
run: npm run lint:scss

- name: Lint Docs JS Files
run: node Makefile lintDocsJS

- name: Check Rule Examples
run: node Makefile checkRuleExamples
- name: Build Docs Website
working-directory: docs
run: npm run build
- name: Validate internal links
working-directory: docs
run: npm run lint:links


test_on_node:
name: Test
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/docs-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI
on:
push:
branches: [main]
paths:
- 'docs/**'

pull_request:
branches: [main]
paths:
- 'docs/**'

permissions:
contents: read

jobs:
verify_files:
name: Verify Docs Files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'

- name: Install Docs Packages
working-directory: docs
run: npm install

- name: Stylelint Docs
working-directory: docs
run: npm run lint:scss

- name: Build Docs Website
working-directory: docs
run: npm run build

- name: Validate internal links
working-directory: docs
run: npm run lint:links
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ The people who review and fix bugs and help triage issues.
Bryan Mishkin
</a>
</td><td align="center" valign="top" width="11%">
<a href="https://github.com/JoshuaKGoldberg">
<img src="https://github.com/JoshuaKGoldberg.png?s=75" width="75" height="75" alt="Josh Goldberg ✨'s Avatar"><br />
Josh Goldberg ✨
</a>
</td><td align="center" valign="top" width="11%">
<a href="https://github.com/fasttime">
<img src="https://github.com/fasttime.png?s=75" width="75" height="75" alt="Francesco Trotta's Avatar"><br />
Francesco Trotta
Expand Down
16 changes: 16 additions & 0 deletions conf/ecma-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @fileoverview Configuration related to ECMAScript versions
* @author Milos Djermanovic
*/

"use strict";

/**
* The latest ECMAScript version supported by ESLint.
* @type {number} year-based ECMAScript version
*/
const LATEST_ECMA_VERSION = 2024;

module.exports = {
LATEST_ECMA_VERSION
};
35 changes: 35 additions & 0 deletions docs/src/_data/further_reading_links.json
Original file line number Diff line number Diff line change
Expand Up @@ -747,5 +747,40 @@
"logo": "https://codepoints.net/favicon.ico",
"title": "U+1680 OGHAM SPACE MARK:   – Unicode – Codepoints",
"description": " , codepoint U+1680 OGHAM SPACE MARK in Unicode, is located in the block “Ogham”. It belongs to the Ogham script and is a Space Separator."
},
"https://en.wikipedia.org/wiki/Dead_store": {
"domain": "en.wikipedia.org",
"url": "https://en.wikipedia.org/wiki/Dead_store",
"logo": "https://en.wikipedia.org/static/apple-touch/wikipedia.png",
"title": "Dead store - Wikipedia",
"description": null
},
"https://rules.sonarsource.com/javascript/RSPEC-1854/": {
"domain": "rules.sonarsource.com",
"url": "https://rules.sonarsource.com/javascript/RSPEC-1854/",
"logo": "https://rules.sonarsource.com/favicon.ico",
"title": "JavaScript static code analysis: Unused assignments should be removed",
"description": "Dead stores refer to assignments made to local variables that are subsequently never used or immediately overwritten. Such assignments are\nunnecessary and don’t contribute to the functionality or clarity of the code. They may even negatively impact performance. Removing them enhances code\ncleanlines…"
},
"https://cwe.mitre.org/data/definitions/563.html": {
"domain": "cwe.mitre.org",
"url": "https://cwe.mitre.org/data/definitions/563.html",
"logo": "https://cwe.mitre.org/favicon.ico",
"title": "CWE - CWE-563: Assignment to Variable without Use (4.13)",
"description": "Common Weakness Enumeration (CWE) is a list of software weaknesses."
},
"https://wiki.sei.cmu.edu/confluence/display/c/MSC13-C.+Detect+and+remove+unused+values": {
"domain": "wiki.sei.cmu.edu",
"url": "https://wiki.sei.cmu.edu/confluence/display/c/MSC13-C.+Detect+and+remove+unused+values",
"logo": "https://wiki.sei.cmu.edu/confluence/s/-ctumb3/9012/tu5x00/7/_/favicon.ico",
"title": "MSC13-C. Detect and remove unused values - SEI CERT C Coding Standard - Confluence",
"description": null
},
"https://wiki.sei.cmu.edu/confluence/display/java/MSC56-J.+Detect+and+remove+superfluous+code+and+values": {
"domain": "wiki.sei.cmu.edu",
"url": "https://wiki.sei.cmu.edu/confluence/display/java/MSC56-J.+Detect+and+remove+superfluous+code+and+values",
"logo": "https://wiki.sei.cmu.edu/confluence/s/-ctumb3/9012/tu5x00/7/_/favicon.ico",
"title": "MSC56-J. Detect and remove superfluous code and values - SEI CERT Oracle Coding Standard for Java - Confluence",
"description": null
}
}
2 changes: 1 addition & 1 deletion docs/src/extend/custom-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ Here, the `myCustomVar` variable is marked as used relative to a `ReturnStatemen

### Accessing Code Paths

ESLint analyzes code paths while traversing AST. You can access code path objects with five events related to code paths. For more information, refer to [Code Path Analysis](code-path-analysis).
ESLint analyzes code paths while traversing AST. You can access code path objects with seven events related to code paths. For more information, refer to [Code Path Analysis](code-path-analysis).

### Deprecated `SourceCode` Methods

Expand Down
159 changes: 149 additions & 10 deletions docs/src/rules/no-inner-declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ function anotherThing() {
}
```

In ES6, [block-level functions](https://leanpub.com/understandinges6/read#leanpub-auto-block-level-functions) (functions declared inside a block) are limited to the scope of the block they are declared in and outside of the block scope they can't be accessed and called, but only when the code is in strict mode (code with `"use strict"` tag or ESM modules). In non-strict mode, they can be accessed and called outside of the block scope.

```js
"use strict";

if (test) {
function doSomething () { }

doSomething(); // no error
}

doSomething(); // error
```

A variable declaration is permitted anywhere a statement can go, even nested deeply inside other blocks. This is often undesirable due to variable hoisting, and moving declarations to the root of the program or function body can increase clarity. Note that [block bindings](https://leanpub.com/understandinges6/read#leanpub-auto-block-bindings) (`let`, `const`) are not hoisted and therefore they are not affected by this rule.

```js
Expand Down Expand Up @@ -65,10 +79,11 @@ This rule requires that function declarations and, optionally, variable declarat

## Options

This rule has a string option:
This rule has a string and an object option:

* `"functions"` (default) disallows `function` declarations in nested blocks
* `"both"` disallows `function` and `var` declarations in nested blocks
* `{ blockScopedFunctions: "allow" }` (default) this option allows `function` declarations in nested blocks when code is in strict mode (code with `"use strict"` tag or ESM modules) and `languageOptions.ecmaVersion` is set to `2015` or above. This option can be disabled by setting it to `"disallow"`.

### functions

Expand All @@ -79,6 +94,8 @@ Examples of **incorrect** code for this rule with the default `"functions"` opti
```js
/*eslint no-inner-declarations: "error"*/

// script, non-strict code

if (test) {
function doSomething() { }
}
Expand All @@ -90,14 +107,6 @@ function doSomethingElse() {
}

if (foo) function f(){}

class C {
static {
if (test) {
function doSomething() { }
}
}
}
```

:::
Expand All @@ -115,6 +124,14 @@ function doSomethingElse() {
function doAnotherThing() { }
}

function doSomethingElse() {
"use strict";

if (test) {
function doAnotherThing() { }
}
}

class C {
static {
function doSomething() { }
Expand Down Expand Up @@ -195,6 +212,128 @@ class C {

:::

### blockScopedFunctions

Example of **incorrect** code for this rule with `{ blockScopedFunctions: "disallow" }` option with `ecmaVersion: 2015`:

::: incorrect { "sourceType": "script", "ecmaVersion": 2015 }

```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/

// non-strict code

if (test) {
function doSomething() { }
}

function doSomething() {
if (test) {
function doSomethingElse() { }
}
}

// strict code

function foo() {
"use strict";

if (test) {
function bar() { }
}
}
```

:::

Example of **correct** code for this rule with `{ blockScopedFunctions: "disallow" }` option with `ecmaVersion: 2015`:

::: correct { "sourceType": "script", "ecmaVersion": 2015 }

```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/

function doSomething() { }

function doSomething() {
function doSomethingElse() { }
}
```

:::

Example of **correct** code for this rule with `{ blockScopedFunctions: "allow" }` option with `ecmaVersion: 2015`:

::: correct { "sourceType": "script", "ecmaVersion": 2015 }

```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/

"use strict";

if (test) {
function doSomething() { }
}

function doSomething() {
if (test) {
function doSomethingElse() { }
}
}

// OR

function foo() {
"use strict";

if (test) {
function bar() { }
}
}
```

:::

`ESM modules` and both `class` declarations and expressions are always in strict mode.

::: correct { "sourceType": "module" }

```js
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/

if (test) {
function doSomething() { }
}

function doSomethingElse() {
if (test) {
function doAnotherThing() { }
}
}

class Some {
static {
if (test) {
function doSomething() { }
}
}
}

const C = class {
static {
if (test) {
function doSomething() { }
}
}
}
```

:::

## When Not To Use It

The function declaration portion rule will be rendered obsolete when [block-scoped functions](https://bugzilla.mozilla.org/show_bug.cgi?id=585536) land in ES6, but until then, it should be left on to enforce valid constructions. Disable checking variable declarations when using [block-scoped-var](block-scoped-var) or if declaring variables in nested blocks is acceptable despite hoisting.
By default, this rule disallows inner function declarations only in contexts where their behavior is unspecified and thus inconsistent (pre-ES6 environments) or legacy semantics apply (non-strict mode code). If your code targets pre-ES6 environments or is not in strict mode, you should enable this rule to prevent unexpected behavior.

In ES6+ environments, in strict mode code, the behavior of inner function declarations is well-defined and consistent - they are always block-scoped. If your code targets only ES6+ environments and is in strict mode (ES modules, or code with `"use strict"` directives) then there is no need to enable this rule unless you want to disallow inner functions as a stylistic choice, in which case you should enable this rule with the option `blockScopedFunctions: "disallow"`.

Disable checking variable declarations when using [block-scoped-var](block-scoped-var) or if declaring variables in nested blocks is acceptable despite hoisting.
2 changes: 2 additions & 0 deletions docs/src/rules/no-unused-vars.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: no-unused-vars
rule_type: problem
related_rules:
- no-useless-assignment
---


Expand Down
Loading

0 comments on commit 85b5070

Please sign in to comment.