Skip to content

Commit 09acf2a

Browse files
feat(lint): update docs & diagnostic for lint/nursery/noProto (#8414)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent e035b91 commit 09acf2a

File tree

8 files changed

+70
-22
lines changed

8 files changed

+70
-22
lines changed

.changeset/fast-spoons-float.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Updated the documentation & diagnostic message for `lint/nursery/noProto`, mentioning the reasons for its longstanding deprecation and why more modern alternatives are preferred.
6+
7+
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.

crates/biome_configuration/src/analyzer/linter/rules.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/biome_js_analyze/src/lint/nursery/no_proto.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,27 @@ use biome_rowan::{AstNode, declare_node_union};
77
use biome_rule_options::no_proto::NoProtoOptions;
88

99
declare_lint_rule! {
10-
/// Disallow the use of the `__proto__` property.
10+
/// Disallow the use of the deprecated `__proto__` object property.
1111
///
12-
/// The use of `__proto__` for getting or setting the prototype of an object
13-
/// is deprecated. Use `Object.getPrototypeOf()` or
14-
/// `Object.setPrototypeOf()` instead.
12+
/// [`Object.prototype.__proto__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)
13+
/// is a special accessor used to get or set the prototype of an object. \
14+
///
15+
/// However, it has been **deprecated** since _ECMAScript 2009_, being much slower and much less reliable than its
16+
/// modern counterparts [`Object.getPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)
17+
/// and [`Object.setPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf).
18+
///
19+
/// Since it is a regular property on `Object.prototype`,
20+
/// `__proto__` **will not work** on `null`-prototype objects that do not extend from `Object.prototype`
21+
/// nor ones having created their own `__proto__` properties via `Object.defineProperty`.
22+
///
23+
/// As such, this rule encourages the use of `Object.getPrototypeOf()` and `Object.setPrototypeOf()`
24+
/// in lieu of directly accessing `__proto__`.
25+
///
26+
/// :::info
27+
/// Note that this does **not** check for the use of `__proto__` inside object literal definitions
28+
/// to set a newly created object's prototype, \
29+
/// which is standard practice and well-optimized in modern browsers.
30+
/// :::
1531
///
1632
/// ## Examples
1733
///
@@ -34,6 +50,15 @@ declare_lint_rule! {
3450
/// ```js
3551
/// Object.setPrototypeOf(obj, b);
3652
/// ```
53+
///
54+
/// ```js
55+
/// // This sets `foo`'s prototype to `null` (similar to `Object.create`), and is
56+
/// // well-defined across browsers.
57+
/// const foo = {
58+
/// __proto__: null,
59+
/// a: 1,
60+
/// }
61+
/// ```
3762
pub NoProto {
3863
version: "2.3.8",
3964
name: "noProto",
@@ -105,14 +130,16 @@ impl Rule for NoProto {
105130
rule_category!(),
106131
node.range(),
107132
markup! {
108-
"Unexpected use of "<Emphasis>"__proto__"</Emphasis>"."
133+
"Avoid use of the deprecated "<Emphasis>"__proto__"</Emphasis>" accessor."
109134
},
110135
)
111136
.note(markup! {
112-
"The use of "<Emphasis>"__proto__"</Emphasis>" for getting or setting the prototype of an object is deprecated."
137+
<Emphasis>"Object.prototype.__proto__"</Emphasis>" is an outdated way to get or set an object's prototype,"
138+
"\nhaving been "<Emphasis>"deprecated in 2009"</Emphasis>" for being inefficient and unreliable."
113139
})
114140
.note(markup! {
115-
"Use "<Emphasis>"Object.getPrototypeOf()"</Emphasis>" or "<Emphasis>"Object.setPrototypeOf()"</Emphasis>" instead."
141+
<Emphasis>"Object.getPrototypeOf()"</Emphasis>" and "<Emphasis>"Object.setPrototypeOf()"</Emphasis>" "
142+
"are modern alternatives that work on all objects and are more performant."
116143
})
117144
)
118145
}

crates/biome_js_analyze/tests/specs/nursery/noProto/invalid.js.snap

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,44 @@ const d = obj["__proto__"];
1515
```
1616
invalid.js:1:1 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1717
18-
i Unexpected use of __proto__.
18+
i Avoid use of the deprecated __proto__ accessor.
1919
2020
> 1 │ obj.__proto__ = a;
2121
│ ^^^^^^^^^^^^^
2222
2 │ obj["__proto__"] = b;
2323
3 │ const c = obj.__proto__;
2424
25-
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
25+
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
26+
having been deprecated in 2009 for being inefficient and unreliable.
2627
27-
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
28+
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
2829
2930
3031
```
3132

3233
```
3334
invalid.js:2:1 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3435
35-
i Unexpected use of __proto__.
36+
i Avoid use of the deprecated __proto__ accessor.
3637
3738
1 │ obj.__proto__ = a;
3839
> 2 │ obj["__proto__"] = b;
3940
│ ^^^^^^^^^^^^^^^^
4041
3 │ const c = obj.__proto__;
4142
4 │ const d = obj["__proto__"];
4243
43-
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
44+
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
45+
having been deprecated in 2009 for being inefficient and unreliable.
4446
45-
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
47+
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
4648
4749
4850
```
4951

5052
```
5153
invalid.js:3:11 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5254
53-
i Unexpected use of __proto__.
55+
i Avoid use of the deprecated __proto__ accessor.
5456
5557
1 │ obj.__proto__ = a;
5658
2 │ obj["__proto__"] = b;
@@ -59,27 +61,29 @@ invalid.js:3:11 lint/nursery/noProto ━━━━━━━━━━━━━━
5961
4 │ const d = obj["__proto__"];
6062
5 │
6163
62-
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
64+
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
65+
having been deprecated in 2009 for being inefficient and unreliable.
6366
64-
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
67+
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
6568
6669
6770
```
6871

6972
```
7073
invalid.js:4:11 lint/nursery/noProto ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7174
72-
i Unexpected use of __proto__.
75+
i Avoid use of the deprecated __proto__ accessor.
7376
7477
2 │ obj["__proto__"] = b;
7578
3 │ const c = obj.__proto__;
7679
> 4 │ const d = obj["__proto__"];
7780
│ ^^^^^^^^^^^^^^^^
7881
5 │
7982
80-
i The use of __proto__ for getting or setting the prototype of an object is deprecated.
83+
i Object.prototype.__proto__ is an outdated way to get or set an object's prototype,
84+
having been deprecated in 2009 for being inefficient and unreliable.
8185
82-
i Use Object.getPrototypeOf() or Object.setPrototypeOf() instead.
86+
i Object.getPrototypeOf() and Object.setPrototypeOf() are modern alternatives that work on all objects and are more performant.
8387
8488
8589
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
/* should not generate diagnostics */
2+
23
const a = Object.getPrototypeOf(obj);
4+
const b = {
5+
__proto__: a,
6+
val: 12
7+
}
38
Object.setPrototypeOf(obj, b);

crates/biome_js_analyze/tests/specs/nursery/noProto/valid.js.snap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ expression: valid.js
55
# Input
66
```js
77
/* should not generate diagnostics */
8+
89
const a = Object.getPrototypeOf(obj);
10+
const b = {
11+
__proto__: a,
12+
val: 12
13+
}
914
Object.setPrototypeOf(obj, b);
1015
1116
```

packages/@biomejs/backend-jsonrpc/src/workspace.ts

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@biomejs/biome/configuration_schema.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)