Skip to content

Commit

Permalink
feat(lint): add temporary linter
Browse files Browse the repository at this point in the history
  • Loading branch information
fujiyamaorange committed May 16, 2024
1 parent fd6b7a4 commit de4f3a9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 10 deletions.
23 changes: 15 additions & 8 deletions crates/biome_js_analyze/src/lint/nursery/use_semantic_elements.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use biome_analyze::{context::RuleContext, declare_rule, Ast, Rule, RuleDiagnostic, RuleSource};
use biome_console::markup;
use biome_js_syntax::JsxOpeningElement;
use biome_js_syntax::{AnyJsxAttribute, JsxOpeningElement};
use biome_rowan::AstNode;

declare_rule! {
Expand Down Expand Up @@ -39,33 +39,40 @@ declare_rule! {

impl Rule for UseSemanticElements {
type Query = Ast<JsxOpeningElement>;
type State = ();
type State = AnyJsxAttribute;
type Signals = Option<Self::State>;
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let node = ctx.query();
panic!("[LOG] node: {:?}", node);
let attributes = node.attributes();
for attr in attributes {
let attr_value = attr.as_jsx_attribute().unwrap().name_value_token().unwrap();
let attr_name = attr_value.text_trimmed();
if attr_name == "role" {
return Some(attr);
}
}

None
}

fn diagnostic(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<RuleDiagnostic> {
fn diagnostic(_ctx: &RuleContext<Self>, state: &Self::State) -> Option<RuleDiagnostic> {
//
// Read our guidelines to write great diagnostics:
// https://docs.rs/biome_analyze/latest/biome_analyze/#what-a-rule-should-say-to-the-user
//
let node = ctx.query();

Some(
RuleDiagnostic::new(
rule_category!(),
node.range(),
state.range(),
markup! {
"Variable is read here."
"This JSX element uses a `role` attribute. Use a semantic element instead."
},
)
.note(markup! {
"This note will give you more information."
"Semantic elements like `<button>`, `<input>`, `<textarea>`, `<a>`, `<img>`, `<table>`, `<article>`, `<section>`, `<nav>`, `<aside>`, `<header>`, `<footer>`, `<main>`, `<figure>`, `<figcaption>`, `<details>`, `<summary>`, `<dialog>`, `<menu>`, `<menuitem>`, `<fieldset>`, `<legend>`, `<caption>`, `<colgroup>`, `<col>`, `<optgroup>`, `<option>`, `<select>`, `<datalist>`, `<output>`, `<progress>`, `<meter>`, `<time>`, `<audio>`, `<video>`, `<track>`, `<source>`, `<embed>`, `<object>`, `<param>`, `<iframe>`, `<canvas>`, `<map>`, `<area>`, `<svg>`, `<math>` are more accessible and provide better semantics."
}),
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const checkbox = () => (
<div role="checkbox" />
<div role="checkbox" ></div>
);

const Image = () => (
<div role="img" />
<div role="img" ></div>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: invalid.js
---
# Input
```jsx
const checkbox = () => (
<div role="checkbox" ></div>
);

const Image = () => (
<div role="img" ></div>
);

```

# Diagnostics
```
invalid.js:2:10 lint/nursery/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! This JSX element uses a `role` attribute. Use a semantic element instead.
1 │ const checkbox = () => (
> 2 │ <div role="checkbox" ></div>
│ ^^^^^^^^^^^^^^^
3 │ );
4 │
i Semantic elements like `<button>`, `<input>`, `<textarea>`, `<a>`, `<img>`, `<table>`, `<article>`, `<section>`, `<nav>`, `<aside>`, `<header>`, `<footer>`, `<main>`, `<figure>`, `<figcaption>`, `<details>`, `<summary>`, `<dialog>`, `<menu>`, `<menuitem>`, `<fieldset>`, `<legend>`, `<caption>`, `<colgroup>`, `<col>`, `<optgroup>`, `<option>`, `<select>`, `<datalist>`, `<output>`, `<progress>`, `<meter>`, `<time>`, `<audio>`, `<video>`, `<track>`, `<source>`, `<embed>`, `<object>`, `<param>`, `<iframe>`, `<canvas>`, `<map>`, `<area>`, `<svg>`, `<math>` are more accessible and provide better semantics.
```

```
invalid.js:6:10 lint/nursery/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! This JSX element uses a `role` attribute. Use a semantic element instead.
5 │ const Image = () => (
> 6 │ <div role="img" ></div>
│ ^^^^^^^^^^
7 │ );
8 │
i Semantic elements like `<button>`, `<input>`, `<textarea>`, `<a>`, `<img>`, `<table>`, `<article>`, `<section>`, `<nav>`, `<aside>`, `<header>`, `<footer>`, `<main>`, `<figure>`, `<figcaption>`, `<details>`, `<summary>`, `<dialog>`, `<menu>`, `<menuitem>`, `<fieldset>`, `<legend>`, `<caption>`, `<colgroup>`, `<col>`, `<optgroup>`, `<option>`, `<select>`, `<datalist>`, `<output>`, `<progress>`, `<meter>`, `<time>`, `<audio>`, `<video>`, `<track>`, `<source>`, `<embed>`, `<object>`, `<param>`, `<iframe>`, `<canvas>`, `<map>`, `<area>`, `<svg>`, `<math>` are more accessible and provide better semantics.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: valid.js
---
# Input
```jsx
export const Component = () => (
<div>
hello world
<header>header</header>
<img alt="" src="image.jpg" />
</div>
);

```

0 comments on commit de4f3a9

Please sign in to comment.