Skip to content

Commit

Permalink
refactor(useLiteralKeys): ignore __proto__ computed property
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Apr 13, 2024
1 parent 8b6ee60 commit aef6d3e
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 46 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,17 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @Conaclos

- [complexity/useLiteralKeys](https://biomejs.dev/linter/rules/use-literal-keys/) no longer report computed properties named `__proto__` ([#2430](https://github.com/biomejs/biome/issues/2430)).

In JavaScript, `{["__proto__"]: null}` and `{__proto__: null}` have not the same semantic.
The first code set a regular property to `null`.
The second one set the prototype of the object to `null`.
See the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto) for more details.

The rule now ignores computed properties named `__proto__`.

Contributed by @Conaclos

#### Bug fixes

- Lint rules `useNodejsImportProtocol`, `useNodeAssertStrict`, `noRestrictedImports`, `noNodejsModules` will no longer check `declare module` statements anymore. Contributed by @Sec-ant
Expand Down
40 changes: 15 additions & 25 deletions crates/biome_js_analyze/src/lint/complexity/use_literal_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use biome_js_factory::make::{
js_static_member_expression, token,
};
use biome_js_syntax::{
AnyJsAssignment, AnyJsComputedMember, AnyJsExpression, AnyJsLiteralExpression,
AnyJsMemberExpression, AnyJsName, AnyJsObjectMemberName, JsComputedMemberName,
JsLiteralMemberName, JsSyntaxKind, T,
AnyJsAssignment, AnyJsComputedMember, AnyJsMemberExpression, AnyJsName, AnyJsObjectMemberName,
JsComputedMemberName, JsLiteralMemberName, JsSyntaxKind, T,
};
use biome_rowan::{declare_node_union, AstNode, BatchMutationExt, TextRange};
use biome_unicode_table::is_js_ident;
Expand Down Expand Up @@ -82,28 +81,19 @@ impl Rule for UseLiteralKeys {
}
AnyJsMember::JsComputedMemberName(member) => member.expression().ok()?,
};
match inner_expression {
AnyJsExpression::AnyJsLiteralExpression(
AnyJsLiteralExpression::JsStringLiteralExpression(string_literal),
) => {
let value = string_literal.inner_string_text().ok()?;
// A computed property `["something"]` can always be simplified to a string literal "something".
if matches!(node, AnyJsMember::JsComputedMemberName(_)) || is_js_ident(&value) {
return Some((string_literal.range(), value.to_string()));
}
}
AnyJsExpression::JsTemplateExpression(template_expression) => {
let mut value = String::new();
for element in template_expression.elements() {
let chunk = element.as_js_template_chunk_element()?;
value.push_str(chunk.template_chunk_token().ok()?.text_trimmed());
}
// A computed property ``[`something`]`` can always be simplified to a string literal "something".
if matches!(node, AnyJsMember::JsComputedMemberName(_)) || is_js_ident(&value) {
return Some((template_expression.range(), value));
}
}
_ => {}
let value = inner_expression.as_static_value()?;
let value = value.as_string_constant()?;
// `{["__proto__"]: null }` and `{"__proto__": null}`/`{"__proto__": null}`
// have different semantic.
// The first is a regular property.
// The second is a specical property that changes the object prototype.
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
if matches!(node, AnyJsMember::JsComputedMemberName(_)) && value == "__proto__" {
return None;
}
// A computed property `["something"]` can always be simplified to a string literal "something".
if matches!(node, AnyJsMember::JsComputedMemberName(_)) || is_js_ident(&value) {
return Some((inner_expression.range(), value.to_string()));
}
None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ a = {
a = {
[""]: 2
}
a = {
"__proto__": null,
}

// optional chain
a?.["b"]?.['c']?.d?.e?.["f"]
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ a = {
a = {
[""]: 2
}
a = {
"__proto__": null,
}

// optional chain
a?.["b"]?.['c']?.d?.e?.["f"]
Expand Down Expand Up @@ -641,7 +644,7 @@ invalid.js:37:3 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━
> 37 │ [""]: 2
│ ^^
38 │ }
39 │
39 │ a = {
i Unsafe fix: Use a literal key instead.
Expand All @@ -651,54 +654,71 @@ invalid.js:37:3 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━
```

```
invalid.js:41:5 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid.js:40:2 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! The computed expression can be simplified without the use of a string literal.
40 │ // optional chain
> 41 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ ^^^
38 │ }
39 │ a = {
> 40 │ "__proto__": null,
│ ^^^^^^^^^^^
41 │ }
42 │
i Unsafe fix: Use a literal key instead.
41 │ a?.["b"]?.['c']?.d?.e?.["f"]
40 │ → "__proto__":·null,
│ - -
```

```
invalid.js:44:5 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! The computed expression can be simplified without the use of a string literal.
43 │ // optional chain
> 44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ ^^^
45 │
i Unsafe fix: Use a literal key instead.
44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ -- --
```

```
invalid.js:41:12 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid.js:44:12 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! The computed expression can be simplified without the use of a string literal.
40 │ // optional chain
> 41 │ a?.["b"]?.['c']?.d?.e?.["f"]
43 │ // optional chain
> 44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ ^^^
42
45
i Unsafe fix: Use a literal key instead.
41 │ a?.["b"]?.['c']?.d?.e?.["f"]
44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ -- --
```

```
invalid.js:41:25 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid.js:44:25 lint/complexity/useLiteralKeys FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! The computed expression can be simplified without the use of a string literal.
40 │ // optional chain
> 41 │ a?.["b"]?.['c']?.d?.e?.["f"]
43 │ // optional chain
> 44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ ^^^
42
45
i Unsafe fix: Use a literal key instead.
41 │ a?.["b"]?.['c']?.d?.e?.["f"]
44 │ a?.["b"]?.['c']?.d?.e?.["f"]
│ -- --
```


Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ class C { a = 0 }
class C { a(){} }
class C { get a(){} }
class C { set a(x){} }
a = {
["__proto__"]: null,
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class C { a = 0 }
class C { a(){} }
class C { get a(){} }
class C { set a(x){} }

a = {
["__proto__"]: null,
}
```


11 changes: 11 additions & 0 deletions website/src/content/docs/internals/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,17 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @Conaclos

- [complexity/useLiteralKeys](https://biomejs.dev/linter/rules/use-literal-keys/) no longer report computed properties named `__proto__` ([#2430](https://github.com/biomejs/biome/issues/2430)).

In JavaScript, `{["__proto__"]: null}` and `{__proto__: null}` have not the same semantic.
The first code set a regular property to `null`.
The second one set the prototype of the object to `null`.
See the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto) for more details.

The rule now ignores computed properties named `__proto__`.

Contributed by @Conaclos

#### Bug fixes

- Lint rules `useNodejsImportProtocol`, `useNodeAssertStrict`, `noRestrictedImports`, `noNodejsModules` will no longer check `declare module` statements anymore. Contributed by @Sec-ant
Expand Down

0 comments on commit aef6d3e

Please sign in to comment.