feat(lint): update docs & diagnostic for lint/nursery/noProto (#8414)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Bertie690 2025-12-12 14:23:44 -05:00 committed by GitHub
parent e035b91fa0
commit 09acf2a700
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 70 additions and 22 deletions

View file

@ -0,0 +1,7 @@
---
"@biomejs/biome": patch
---
Updated the documentation & diagnostic message for `lint/nursery/noProto`, mentioning the reasons for its longstanding deprecation and why more modern alternatives are preferred.
Notably, the rule clearly states that using `__proto__` inside object literal definitions is still allowed, being a standard way to set the prototype of a newly created object.

File diff suppressed because one or more lines are too long

View file

@ -7,11 +7,27 @@ use biome_rowan::{AstNode, declare_node_union};
use biome_rule_options::no_proto::NoProtoOptions;
declare_lint_rule! {
/// Disallow the use of the `__proto__` property.
/// Disallow the use of the deprecated `__proto__` object property.
///
/// The use of `__proto__` for getting or setting the prototype of an object
/// is deprecated. Use `Object.getPrototypeOf()` or
/// `Object.setPrototypeOf()` instead.
/// [`Object.prototype.__proto__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)
/// is a special accessor used to get or set the prototype of an object. \
///
/// However, it has been **deprecated** since _ECMAScript 2009_, being much slower and much less reliable than its
/// modern counterparts [`Object.getPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)
/// and [`Object.setPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf).
///
/// Since it is a regular property on `Object.prototype`,
/// `__proto__` **will not work** on `null`-prototype objects that do not extend from `Object.prototype`
/// nor ones having created their own `__proto__` properties via `Object.defineProperty`.
///
/// As such, this rule encourages the use of `Object.getPrototypeOf()` and `Object.setPrototypeOf()`
/// in lieu of directly accessing `__proto__`.
///
/// :::info
/// Note that this does **not** check for the use of `__proto__` inside object literal definitions
/// to set a newly created object's prototype, \
/// which is standard practice and well-optimized in modern browsers.
/// :::
///
/// ## Examples
///
@ -34,6 +50,15 @@ declare_lint_rule! {
/// ```js
/// Object.setPrototypeOf(obj, b);
/// ```
///
/// ```js
/// // This sets `foo`'s prototype to `null` (similar to `Object.create`), and is
/// // well-defined across browsers.
/// const foo = {
/// __proto__: null,
/// a: 1,
/// }
/// ```
pub NoProto {
version: "2.3.8",
name: "noProto",
@ -105,14 +130,16 @@ impl Rule for NoProto {
rule_category!(),
node.range(),
markup! {
"Unexpected use of "<Emphasis>"__proto__"</Emphasis>"."
"Avoid use of the deprecated "<Emphasis>"__proto__"</Emphasis>" accessor."
},
)
.note(markup! {
"The use of "<Emphasis>"__proto__"</Emphasis>" for getting or setting the prototype of an object is deprecated."
<Emphasis>"Object.prototype.__proto__"</Emphasis>" is an outdated way to get or set an object's prototype,"
"\nhaving been "<Emphasis>"deprecated in 2009"</Emphasis>" for being inefficient and unreliable."
})
.note(markup! {
"Use "<Emphasis>"Object.getPrototypeOf()"</Emphasis>" or "<Emphasis>"Object.setPrototypeOf()"</Emphasis>" instead."
<Emphasis>"Object.getPrototypeOf()"</Emphasis>" and "<Emphasis>"Object.setPrototypeOf()"</Emphasis>" "
"are modern alternatives that work on all objects and are more performant."
})
)
}

View file

@ -15,16 +15,17 @@ const d = obj["__proto__"];
```
invalid.js:1:1 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i Unexpected use of __proto__.
i Avoid use of the deprecated __proto__ accessor.
> 1 │ obj.__proto__ = a;
│ ^^^^^^^^^^^^^
2 │ obj["__proto__"] = b;
3 │ const c = obj.__proto__;
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
having been deprecated in 2009 for being inefficient and unreliable.
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
```
@ -32,7 +33,7 @@ invalid.js:1:1 lint/nursery/noProto ━━━━━━━━━━━━━━
```
invalid.js:2:1 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i Unexpected use of __proto__.
i Avoid use of the deprecated __proto__ accessor.
1 │ obj.__proto__ = a;
> 2 │ obj["__proto__"] = b;
@ -40,9 +41,10 @@ invalid.js:2:1 lint/nursery/noProto ━━━━━━━━━━━━━━
3 │ const c = obj.__proto__;
4 │ const d = obj["__proto__"];
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
having been deprecated in 2009 for being inefficient and unreliable.
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
```
@ -50,7 +52,7 @@ invalid.js:2:1 lint/nursery/noProto ━━━━━━━━━━━━━━
```
invalid.js:3:11 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i Unexpected use of __proto__.
i Avoid use of the deprecated __proto__ accessor.
1 │ obj.__proto__ = a;
2 │ obj["__proto__"] = b;
@ -59,9 +61,10 @@ invalid.js:3:11 lint/nursery/noProto ━━━━━━━━━━━━━━
4 │ const d = obj["__proto__"];
5 │
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
having been deprecated in 2009 for being inefficient and unreliable.
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
```
@ -69,7 +72,7 @@ invalid.js:3:11 lint/nursery/noProto ━━━━━━━━━━━━━━
```
invalid.js:4:11 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i Unexpected use of __proto__.
i Avoid use of the deprecated __proto__ accessor.
2 │ obj["__proto__"] = b;
3 │ const c = obj.__proto__;
@ -77,9 +80,10 @@ invalid.js:4:11 lint/nursery/noProto ━━━━━━━━━━━━━━
│ ^^^^^^^^^^^^^^^^
5 │
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
having been deprecated in 2009 for being inefficient and unreliable.
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
```

View file

@ -1,3 +1,8 @@
/* should not generate diagnostics */
const a = Object.getPrototypeOf(obj);
const b = {
__proto__: a,
val: 12
}
Object.setPrototypeOf(obj, b);

View file

@ -5,7 +5,12 @@ expression: valid.js
# Input
```js
/* should not generate diagnostics */
const a = Object.getPrototypeOf(obj);
const b = {
__proto__: a,
val: 12
}
Object.setPrototypeOf(obj, b);
```

View file

@ -1937,7 +1937,7 @@ See <https://biomejs.dev/linter/rules/no-parameters-only-used-in-recursion>
*/
noParametersOnlyUsedInRecursion?: NoParametersOnlyUsedInRecursionConfiguration;
/**
* Disallow the use of the __proto__ property.
* Disallow the use of the deprecated __proto__ object property.
See <https://biomejs.dev/linter/rules/no-proto>
*/
noProto?: NoProtoConfiguration;

View file

@ -5215,7 +5215,7 @@
]
},
"noProto": {
"description": "Disallow the use of the __proto__ property.\nSee <https://biomejs.dev/linter/rules/no-proto>",
"description": "Disallow the use of the deprecated __proto__ object property.\nSee <https://biomejs.dev/linter/rules/no-proto>",
"anyOf": [
{ "$ref": "#/$defs/NoProtoConfiguration" },
{ "type": "null" }