Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
feat(rome_js_analyze): noEmptyPattern (#2731)
Browse files Browse the repository at this point in the history
  • Loading branch information
IWANABETHATGUY authored Jun 21, 2022
1 parent cf4189c commit bcaf744
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crates/rome_js_analyze/src/analyzers.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions crates/rome_js_analyze/src/analyzers/no_empty_pattern.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleCategory, RuleDiagnostic};
use rome_console::markup;
use rome_js_syntax::{JsArrayBindingPattern, JsObjectBindingPattern};
use rome_rowan::{declare_node_union, AstNode, AstSeparatedList};

declare_rule! {
/// Disallows empty destructuring patterns.
/// ## Examples
///
/// ### Valid
/// The following cases are valid because they create new bindings.
///
/// ```js
/// var {a = {}} = foo;
/// var {a, b = {}} = foo;
/// var {a = []} = foo;
/// function foo({a = {}}) {}
/// function foo({a = []}) {}
/// var [a] = foo;
/// ```
///
/// ### Invalid
///
/// ```js,expect_diagnostic
/// var {} = foo;
/// ```
///
/// ```js,expect_diagnostic
/// var {a: {}} = foo;
/// ```
///
/// ```js,expect_diagnostic
/// function foo({}) {}
/// ```
///
pub(crate) NoEmptyPattern = "noEmptyPattern"
}

impl Rule for NoEmptyPattern {
const CATEGORY: RuleCategory = RuleCategory::Lint;

type Query = JsAnyBindPatternLike;
type State = ();

fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
match ctx.query() {
JsAnyBindPatternLike::JsArrayBindingPattern(array) => {
if array.elements().len() == 0 {
Some(())
} else {
None
}
}
JsAnyBindPatternLike::JsObjectBindingPattern(object) => {
if object.properties().len() == 0 {
Some(())
} else {
None
}
}
}
}

fn diagnostic(ctx: &RuleContext<Self>, _: &Self::State) -> Option<RuleDiagnostic> {
let node = ctx.query();
let node_type = match node {
JsAnyBindPatternLike::JsArrayBindingPattern(_) => "array",
JsAnyBindPatternLike::JsObjectBindingPattern(_) => "object",
};

Some(RuleDiagnostic::warning(
node.range(),
markup! {
"Unexpected empty "{node_type}" pattern."
},
))
}
}

declare_node_union! {
/// enum of `JsObjectBindingPattern` and `JsArrayBindingPattern`
pub(crate) JsAnyBindPatternLike = JsArrayBindingPattern | JsObjectBindingPattern
}
3 changes: 3 additions & 0 deletions crates/rome_js_analyze/src/registry.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions crates/rome_js_analyze/tests/specs/noEmptyPattern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// valid
var {a = {}} = foo;
var {a, b = {}} = foo;
var {a = []} = foo;
function foo({a = {}}) {}
function foo({a = []}) {}
var [a] = foo;
// invalid
var {} = foo;
var [] = foo;
var {a: {}} = foo;
var {a, b: {}} = foo;
var {a: []} = foo;
function foo({}) {};
function foo([]) {};
function foo({a: {}}) {};
function foo({a: []}) {};
118 changes: 118 additions & 0 deletions crates/rome_js_analyze/tests/specs/noEmptyPattern.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
source: crates/rome_js_analyze/tests/spec_tests.rs
assertion_line: 98
expression: noEmptyPattern.js
---
# Input
```js
// valid
var {a = {}} = foo;
var {a, b = {}} = foo;
var {a = []} = foo;
function foo({a = {}}) {}
function foo({a = []}) {}
var [a] = foo;
// invalid
var {} = foo;
var [] = foo;
var {a: {}} = foo;
var {a, b: {}} = foo;
var {a: []} = foo;
function foo({}) {};
function foo([]) {};
function foo({a: {}}) {};
function foo({a: []}) {};
```

# Diagnostics
```
warning[noEmptyPattern]: Unexpected empty object pattern.
┌─ noEmptyPattern.js:9:5
9 │ var {} = foo;
│ --
```

```
warning[noEmptyPattern]: Unexpected empty array pattern.
┌─ noEmptyPattern.js:10:5
10 │ var [] = foo;
│ --
```

```
warning[noEmptyPattern]: Unexpected empty object pattern.
┌─ noEmptyPattern.js:11:9
11 │ var {a: {}} = foo;
│ --
```

```
warning[noEmptyPattern]: Unexpected empty object pattern.
┌─ noEmptyPattern.js:12:12
12 │ var {a, b: {}} = foo;
│ --
```

```
warning[noEmptyPattern]: Unexpected empty array pattern.
┌─ noEmptyPattern.js:13:9
13 │ var {a: []} = foo;
│ --
```

```
warning[noEmptyPattern]: Unexpected empty object pattern.
┌─ noEmptyPattern.js:14:14
14 │ function foo({}) {};
│ --
```

```
warning[noEmptyPattern]: Unexpected empty array pattern.
┌─ noEmptyPattern.js:15:14
15 │ function foo([]) {};
│ --
```

```
warning[noEmptyPattern]: Unexpected empty object pattern.
┌─ noEmptyPattern.js:16:18
16 │ function foo({a: {}}) {};
│ --
```

```
warning[noEmptyPattern]: Unexpected empty array pattern.
┌─ noEmptyPattern.js:17:18
17 │ function foo({a: []}) {};
│ --
```


7 changes: 7 additions & 0 deletions website/src/docs/lint/rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ Disallow the use of the <code>delete</code> operator
Require the use of <code>===</code> and <code>!==</code>
</div>
<div class="rule">
<h3 data-toc-exclude id="noEmptyPattern">
<a href="/docs/lint/rules/noEmptyPattern">noEmptyPattern</a>
<a class="header-anchor" href="#noEmptyPattern"></a>
</h3>
Disallows empty destructuring patterns.
</div>
<div class="rule">
<h3 data-toc-exclude id="noImplicitBoolean">
<a href="/docs/lint/rules/noImplicitBoolean">noImplicitBoolean</a>
<a class="header-anchor" href="#noImplicitBoolean"></a>
Expand Down
62 changes: 62 additions & 0 deletions website/src/docs/lint/rules/noEmptyPattern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Lint Rule noEmptyPattern
layout: layouts/rule.liquid
---

# noEmptyPattern

Disallows empty destructuring patterns.

## Examples

### Valid

The following cases are valid because they create new bindings.

```jsx
var {a = {}} = foo;
var {a, b = {}} = foo;
var {a = []} = foo;
function foo({a = {}}) {}
function foo({a = []}) {}
var [a] = foo;
```

### Invalid

```jsx
var {} = foo;
```

{% raw %}<pre class="language-text"><code class="language-text"><span style="color: Orange;">warning</span><span style="color: Orange;">[</span><span style="color: Orange;">noEmptyPattern</span><span style="color: Orange;">]</span><em>: </em><em>Unexpected empty object pattern.</em>
<span style="color: rgb(38, 148, 255);">┌</span><span style="color: rgb(38, 148, 255);">─</span> noEmptyPattern.js:1:5
<span style="color: rgb(38, 148, 255);">│</span>
<span style="color: rgb(38, 148, 255);">1</span> <span style="color: rgb(38, 148, 255);">│</span> var {} = foo;
<span style="color: rgb(38, 148, 255);">│</span> <span style="color: rgb(38, 148, 255);">-</span><span style="color: rgb(38, 148, 255);">-</span>

</code></pre>{% endraw %}

```jsx
var {a: {}} = foo;
```

{% raw %}<pre class="language-text"><code class="language-text"><span style="color: Orange;">warning</span><span style="color: Orange;">[</span><span style="color: Orange;">noEmptyPattern</span><span style="color: Orange;">]</span><em>: </em><em>Unexpected empty object pattern.</em>
<span style="color: rgb(38, 148, 255);">┌</span><span style="color: rgb(38, 148, 255);">─</span> noEmptyPattern.js:1:9
<span style="color: rgb(38, 148, 255);">│</span>
<span style="color: rgb(38, 148, 255);">1</span> <span style="color: rgb(38, 148, 255);">│</span> var {a: {}} = foo;
<span style="color: rgb(38, 148, 255);">│</span> <span style="color: rgb(38, 148, 255);">-</span><span style="color: rgb(38, 148, 255);">-</span>

</code></pre>{% endraw %}

```jsx
function foo({}) {}
```

{% raw %}<pre class="language-text"><code class="language-text"><span style="color: Orange;">warning</span><span style="color: Orange;">[</span><span style="color: Orange;">noEmptyPattern</span><span style="color: Orange;">]</span><em>: </em><em>Unexpected empty object pattern.</em>
<span style="color: rgb(38, 148, 255);">┌</span><span style="color: rgb(38, 148, 255);">─</span> noEmptyPattern.js:1:14
<span style="color: rgb(38, 148, 255);">│</span>
<span style="color: rgb(38, 148, 255);">1</span> <span style="color: rgb(38, 148, 255);">│</span> function foo({}) {}
<span style="color: rgb(38, 148, 255);">│</span> <span style="color: rgb(38, 148, 255);">-</span><span style="color: rgb(38, 148, 255);">-</span>

</code></pre>{% endraw %}

0 comments on commit bcaf744

Please sign in to comment.