From e88b579cdfb0a7d6800861531fa9261c4ef76ba6 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 10:18:59 -0300 Subject: [PATCH 1/7] support for object and array bindings when exporting --- .../noUnusedVariables/noUnusedVariables.js | 2 ++ .../noUnusedVariables/noUnusedVariables.js.snap | 3 ++- crates/rome_js_semantic/src/events.rs | 15 +++++++++++++-- crates/rome_js_semantic/src/semantic_model.rs | 7 +++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js b/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js index d7927f94667..3464e556137 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js +++ b/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js @@ -67,3 +67,5 @@ const a = { a; +export const { A } = z; +export const [ B ] = z; \ No newline at end of file diff --git a/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js.snap b/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js.snap index d70fd9f11cc..4117b1040ac 100644 --- a/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js.snap +++ b/crates/rome_js_analyze/tests/specs/correctness/noUnusedVariables/noUnusedVariables.js.snap @@ -73,7 +73,8 @@ const a = { a; - +export const { A } = z; +export const [ B ] = z; ``` # Diagnostics diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 0eb5f725a8d..2f2438c3804 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -371,6 +371,17 @@ impl SemanticEventExtractor { self.push_binding_into_scope(hoisted_scope_id, &name_token); self.export_class_expression(node, &parent); } + JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | JS_OBJECT_BINDING_PATTERN_PROPERTY => { + let declarator = parent.parent()? + .parent()? + .parent()?; + self.export_variable_declarator(node, &declarator); + } + JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { + let declarator = parent.parent()? + .parent()?; + self.export_variable_declarator(node, &declarator); + } TS_TYPE_ALIAS_DECLARATION => { let hoisted_scope_id = self.scope_index_to_hoist_declarations(1); self.push_binding_into_scope(hoisted_scope_id, &name_token); @@ -542,7 +553,7 @@ impl SemanticEventExtractor { /// 1 - Match all references and declarations; /// 2 - Unmatched references are promoted to its parent scope or become [UnresolvedReference] events; /// 3 - All declarations of this scope are removed; - /// 4 - All shawed declarations are restored. + /// 4 - All shadowed declarations are restored. fn pop_scope(&mut self, range: TextRange) { debug_assert!(!self.scopes.is_empty()); @@ -820,7 +831,7 @@ impl SemanticEventExtractor { } } - // Check if a function is exported and raise the [Exported] event. + // Check if a variable is exported and raise the [Exported] event. fn export_variable_declarator( &mut self, binding: &JsSyntaxNode, diff --git a/crates/rome_js_semantic/src/semantic_model.rs b/crates/rome_js_semantic/src/semantic_model.rs index 935c5e28e2d..8ade4af01bd 100644 --- a/crates/rome_js_semantic/src/semantic_model.rs +++ b/crates/rome_js_semantic/src/semantic_model.rs @@ -1428,6 +1428,13 @@ mod test { assert_is_exported(true, "A", "enum A {}; module.exports = A"); assert_is_exported(true, "A", "enum A {}; exports = A"); assert_is_exported(true, "A", "enum A {}; exports.A = A"); + + // Object binding + assert_is_exported(true, "A", "export const { A } = a;"); + assert_is_exported(true, "b", "export const { A: b } = a;"); + + // Array binding + assert_is_exported(true, "A", "export const [A] = a;"); } #[test] From 45f5da5d698b665e8d1a2493a692e0990432ba3e Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 10:32:04 -0300 Subject: [PATCH 2/7] fmt and clippy issues --- crates/rome_js_semantic/src/events.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 2f2438c3804..4fa7a7cd8a4 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -372,14 +372,11 @@ impl SemanticEventExtractor { self.export_class_expression(node, &parent); } JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | JS_OBJECT_BINDING_PATTERN_PROPERTY => { - let declarator = parent.parent()? - .parent()? - .parent()?; + let declarator = parent.parent()?.parent()?.parent()?; self.export_variable_declarator(node, &declarator); } JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { - let declarator = parent.parent()? - .parent()?; + let declarator = parent.parent()?.parent()?; self.export_variable_declarator(node, &declarator); } TS_TYPE_ALIAS_DECLARATION => { From dd957a7005ff09620a65a89d65c7effbb5ce7327 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 14:00:34 -0300 Subject: [PATCH 3/7] support recursive navigation from binding to declarator --- crates/rome_js_semantic/src/events.rs | 20 +++++++++++++------ crates/rome_js_semantic/src/semantic_model.rs | 9 +++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 4fa7a7cd8a4..0d5bf14d7fb 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -371,12 +371,20 @@ impl SemanticEventExtractor { self.push_binding_into_scope(hoisted_scope_id, &name_token); self.export_class_expression(node, &parent); } - JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | JS_OBJECT_BINDING_PATTERN_PROPERTY => { - let declarator = parent.parent()?.parent()?.parent()?; - self.export_variable_declarator(node, &declarator); - } - JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { - let declarator = parent.parent()?.parent()?; + JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY + | JS_OBJECT_BINDING_PATTERN_PROPERTY + | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST=> { + let declarator = parent.ancestors() + .skip_while(|x| { + matches!(x.kind(), + JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | + JS_OBJECT_BINDING_PATTERN_PROPERTY_LIST | + JS_OBJECT_BINDING_PATTERN_PROPERTY | + JS_OBJECT_BINDING_PATTERN | + JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST | + JS_ARRAY_BINDING_PATTERN + ) + }).next()?; self.export_variable_declarator(node, &declarator); } TS_TYPE_ALIAS_DECLARATION => { diff --git a/crates/rome_js_semantic/src/semantic_model.rs b/crates/rome_js_semantic/src/semantic_model.rs index 8ade4af01bd..5e4242c4d88 100644 --- a/crates/rome_js_semantic/src/semantic_model.rs +++ b/crates/rome_js_semantic/src/semantic_model.rs @@ -1429,12 +1429,13 @@ mod test { assert_is_exported(true, "A", "enum A {}; exports = A"); assert_is_exported(true, "A", "enum A {}; exports.A = A"); - // Object binding + // Object and Array bindings assert_is_exported(true, "A", "export const { A } = a;"); assert_is_exported(true, "b", "export const { A: b } = a;"); - - // Array binding - assert_is_exported(true, "A", "export const [A] = a;"); + assert_is_exported(true, "A", "export const [ A ] = a;"); + assert_is_exported(true, "A", "export const [{ A }] = a;"); + assert_is_exported(true, "D", "export const [{ C: [ D ] }] = a;"); + assert_is_exported(true, "E", "export const [{ C: [{ E }] }] = a;"); } #[test] From d81e6276380e95fa97a895ee9900bf1010b08900 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 14:23:42 -0300 Subject: [PATCH 4/7] checking binding is inside a declarator --- crates/rome_js_semantic/src/events.rs | 33 +- website/docs/src/lint/rules/index.md | 490 ------------------ .../lint/rules/useExhaustiveDependencies.md | 148 ------ 3 files changed, 18 insertions(+), 653 deletions(-) delete mode 100644 website/docs/src/lint/rules/index.md delete mode 100644 website/docs/src/lint/rules/useExhaustiveDependencies.md diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 0d5bf14d7fb..b24c4dbac4a 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -371,21 +371,24 @@ impl SemanticEventExtractor { self.push_binding_into_scope(hoisted_scope_id, &name_token); self.export_class_expression(node, &parent); } - JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY - | JS_OBJECT_BINDING_PATTERN_PROPERTY - | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST=> { - let declarator = parent.ancestors() - .skip_while(|x| { - matches!(x.kind(), - JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | - JS_OBJECT_BINDING_PATTERN_PROPERTY_LIST | - JS_OBJECT_BINDING_PATTERN_PROPERTY | - JS_OBJECT_BINDING_PATTERN | - JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST | - JS_ARRAY_BINDING_PATTERN - ) - }).next()?; - self.export_variable_declarator(node, &declarator); + JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY + | JS_OBJECT_BINDING_PATTERN_PROPERTY + | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { + let possible_declarator = parent.ancestors().find(|x| { + !matches!( + x.kind(), + JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY + | JS_OBJECT_BINDING_PATTERN_PROPERTY_LIST + | JS_OBJECT_BINDING_PATTERN_PROPERTY + | JS_OBJECT_BINDING_PATTERN + | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST + | JS_ARRAY_BINDING_PATTERN + ) + })?; + + if let JS_VARIABLE_DECLARATOR = possible_declarator.kind() { + self.export_variable_declarator(node, &possible_declarator); + } } TS_TYPE_ALIAS_DECLARATION => { let hoisted_scope_id = self.scope_index_to_hoist_declarations(1); diff --git a/website/docs/src/lint/rules/index.md b/website/docs/src/lint/rules/index.md deleted file mode 100644 index 89b262267bc..00000000000 --- a/website/docs/src/lint/rules/index.md +++ /dev/null @@ -1,490 +0,0 @@ ---- -title: Lint Rules -main-class: rules ---- - -# Rules - - -## Accessibility - -Rules focused on preventing accessibility problems. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noAutofocus"> - <a href="/lint/rules/noAutofocus">noAutofocus</a> - <span class="recommended">recommended</span> -</h3> -Avoid the <code>autoFocus</code> attribute -</section> -<section class="rule"> -<h3 data-toc-exclude id="noPositiveTabindex"> - <a href="/lint/rules/noPositiveTabindex">noPositiveTabindex</a> - <span class="recommended">recommended</span> -</h3> -Prevent the usage of positive integers on <code>tabIndex</code> property -</section> -<section class="rule"> -<h3 data-toc-exclude id="useAltText"> - <a href="/lint/rules/useAltText">useAltText</a> - <span class="recommended">recommended</span> -</h3> -It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useAnchorContent"> - <a href="/lint/rules/useAnchorContent">useAnchorContent</a> - <span class="recommended">recommended</span> -</h3> -Enforce that anchor elements have content and that the content is accessible to screen readers. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useBlankTarget"> - <a href="/lint/rules/useBlankTarget">useBlankTarget</a> - <span class="recommended">recommended</span> -</h3> -Disallow <code>target="_blank"</code> attribute without <code>rel="noreferrer"</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="useButtonType"> - <a href="/lint/rules/useButtonType">useButtonType</a> - <span class="recommended">recommended</span> -</h3> -Enforces the usage of the attribute <code>type</code> for the element <code>button</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="useKeyWithClickEvents"> - <a href="/lint/rules/useKeyWithClickEvents">useKeyWithClickEvents</a> - <span class="recommended">recommended</span> -</h3> -Enforce to have the <code>onClick</code> mouse event with the <code>onKeyUp</code>, the <code>onKeyDown</code>, or the <code>noKeyPress</code> keyboard event. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useKeyWithMouseEvents"> - <a href="/lint/rules/useKeyWithMouseEvents">useKeyWithMouseEvents</a> - <span class="recommended">recommended</span> -</h3> -Enforce that <code>onMouseOver</code>/<code>onMouseOut</code> are accompanied by <code>onFocus</code>/<code>onBlur</code> for keyboard-only users. -It is important to take into account users with physical disabilities who cannot use a mouse, -who use assistive technology or screenreader. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useValidAnchor"> - <a href="/lint/rules/useValidAnchor">useValidAnchor</a> - <span class="recommended">recommended</span> -</h3> -Enforce that all anchors are valid, and they are navigable elements. -</section> - -</div> - -## Complexity - -Rules that focus on inspecting complex code that could be simplified. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noExtraBooleanCast"> - <a href="/lint/rules/noExtraBooleanCast">noExtraBooleanCast</a> - <span class="recommended">recommended</span> -</h3> -Disallow unnecessary boolean casts -</section> -<section class="rule"> -<h3 data-toc-exclude id="useSimplifiedLogicExpression"> - <a href="/lint/rules/useSimplifiedLogicExpression">useSimplifiedLogicExpression</a> - <span class="recommended">recommended</span> -</h3> -Discard redundant terms from logical expressions. -</section> - -</div> - -## Correctness - -Rules that detect incorrect or useless code. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noArguments"> - <a href="/lint/rules/noArguments">noArguments</a> - <span class="recommended">recommended</span> -</h3> -Disallow the use of <code>arguments</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="noArrayIndexKey"> - <a href="/lint/rules/noArrayIndexKey">noArrayIndexKey</a> - <span class="recommended">recommended</span> -</h3> -Discourage the usage of Array index in keys. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noAsyncPromiseExecutor"> - <a href="/lint/rules/noAsyncPromiseExecutor">noAsyncPromiseExecutor</a> - <span class="recommended">recommended</span> -</h3> -Disallows using an async function as a Promise executor. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noCatchAssign"> - <a href="/lint/rules/noCatchAssign">noCatchAssign</a> - <span class="recommended">recommended</span> -</h3> -Disallow reassigning exceptions in catch clauses -</section> -<section class="rule"> -<h3 data-toc-exclude id="noChildrenProp"> - <a href="/lint/rules/noChildrenProp">noChildrenProp</a> - <span class="recommended">recommended</span> -</h3> -Prevent passing of <strong>children</strong> as props. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noCommentText"> - <a href="/lint/rules/noCommentText">noCommentText</a> - <span class="recommended">recommended</span> -</h3> -Prevent comments from being inserted as text nodes -</section> -<section class="rule"> -<h3 data-toc-exclude id="noCompareNegZero"> - <a href="/lint/rules/noCompareNegZero">noCompareNegZero</a> - <span class="recommended">recommended</span> -</h3> -Disallow comparing against <code>-0</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="noDebugger"> - <a href="/lint/rules/noDebugger">noDebugger</a> - <span class="recommended">recommended</span> -</h3> -Disallow the use of <code>debugger</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="noDelete"> - <a href="/lint/rules/noDelete">noDelete</a> - <span class="recommended">recommended</span> -</h3> -Disallow the use of the <code>delete</code> operator -</section> -<section class="rule"> -<h3 data-toc-exclude id="noDoubleEquals"> - <a href="/lint/rules/noDoubleEquals">noDoubleEquals</a> - <span class="recommended">recommended</span> -</h3> -Require the use of <code>===</code> and <code>!==</code> -</section> -<section class="rule"> -<h3 data-toc-exclude id="noDupeArgs"> - <a href="/lint/rules/noDupeArgs">noDupeArgs</a> - <span class="recommended">recommended</span> -</h3> -Disallow duplicate function arguments name. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noEmptyPattern"> - <a href="/lint/rules/noEmptyPattern">noEmptyPattern</a> - <span class="recommended">recommended</span> -</h3> -Disallows empty destructuring patterns. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noFunctionAssign"> - <a href="/lint/rules/noFunctionAssign">noFunctionAssign</a> - <span class="recommended">recommended</span> -</h3> -Disallow reassigning function declarations. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noImportAssign"> - <a href="/lint/rules/noImportAssign">noImportAssign</a> - <span class="recommended">recommended</span> -</h3> -Disallow assigning to imported bindings -</section> -<section class="rule"> -<h3 data-toc-exclude id="noLabelVar"> - <a href="/lint/rules/noLabelVar">noLabelVar</a> - <span class="recommended">recommended</span> -</h3> -Disallow labels that share a name with a variable -</section> -<section class="rule"> -<h3 data-toc-exclude id="noMultipleSpacesInRegularExpressionLiterals"> - <a href="/lint/rules/noMultipleSpacesInRegularExpressionLiterals">noMultipleSpacesInRegularExpressionLiterals</a> - <span class="recommended">recommended</span> -</h3> -Disallow unclear usage of multiple space characters in regular expression literals -</section> -<section class="rule"> -<h3 data-toc-exclude id="noNewSymbol"> - <a href="/lint/rules/noNewSymbol">noNewSymbol</a> - <span class="recommended">recommended</span> -</h3> -Disallow <code>new</code> operators with the <code>Symbol</code> object -</section> -<section class="rule"> -<h3 data-toc-exclude id="noRenderReturnValue"> - <a href="/lint/rules/noRenderReturnValue">noRenderReturnValue</a> - <span class="recommended">recommended</span> -</h3> -Prevent the usage of the return value of <code>React.render</code>. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noRestrictedGlobals"> - <a href="/lint/rules/noRestrictedGlobals">noRestrictedGlobals</a> -</h3> -This rule allows you to specify global variable names that you don’t want to use in your application. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noShadowRestrictedNames"> - <a href="/lint/rules/noShadowRestrictedNames">noShadowRestrictedNames</a> - <span class="recommended">recommended</span> -</h3> -Disallow identifiers from shadowing restricted names. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noSparseArray"> - <a href="/lint/rules/noSparseArray">noSparseArray</a> - <span class="recommended">recommended</span> -</h3> -Disallow sparse arrays -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUndeclaredVariables"> - <a href="/lint/rules/noUndeclaredVariables">noUndeclaredVariables</a> -</h3> -Prevents the usage of variables that haven't been declared inside the document -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUnnecessaryContinue"> - <a href="/lint/rules/noUnnecessaryContinue">noUnnecessaryContinue</a> - <span class="recommended">recommended</span> -</h3> -Avoid using unnecessary <code>continue</code>. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUnreachable"> - <a href="/lint/rules/noUnreachable">noUnreachable</a> - <span class="recommended">recommended</span> -</h3> -Disallow unreachable code -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUnsafeNegation"> - <a href="/lint/rules/noUnsafeNegation">noUnsafeNegation</a> - <span class="recommended">recommended</span> -</h3> -Disallow using unsafe negation. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUnusedVariables"> - <a href="/lint/rules/noUnusedVariables">noUnusedVariables</a> -</h3> -Disallow unused variables. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUselessFragments"> - <a href="/lint/rules/noUselessFragments">noUselessFragments</a> -</h3> -Disallow unnecessary fragments -</section> -<section class="rule"> -<h3 data-toc-exclude id="noVoidElementsWithChildren"> - <a href="/lint/rules/noVoidElementsWithChildren">noVoidElementsWithChildren</a> - <span class="recommended">recommended</span> -</h3> -This rules prevents void elements (AKA self-closing elements) from having children. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useSingleCaseStatement"> - <a href="/lint/rules/useSingleCaseStatement">useSingleCaseStatement</a> - <span class="recommended">recommended</span> -</h3> -Enforces case clauses have a single statement, emits a quick fix wrapping -the statements in a block -</section> -<section class="rule"> -<h3 data-toc-exclude id="useValidTypeof"> - <a href="/lint/rules/useValidTypeof">useValidTypeof</a> - <span class="recommended">recommended</span> -</h3> -This rule verifies the result of <code>typeof $expr</code> unary expressions is being -compared to valid values, either string literals containing valid type -names or other <code>typeof</code> expressions -</section> -<section class="rule"> -<h3 data-toc-exclude id="useWhile"> - <a href="/lint/rules/useWhile">useWhile</a> - <span class="recommended">recommended</span> -</h3> -Enforce the use of <code>while</code> loops instead of <code>for</code> loops when the -initializer and update expressions are not needed -</section> - -</div> - -## Security - -Rules that detect potential security flaws. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noDangerouslySetInnerHtml"> - <a href="/lint/rules/noDangerouslySetInnerHtml">noDangerouslySetInnerHtml</a> - <span class="recommended">recommended</span> -</h3> -Prevent the usage of dangerous JSX props -</section> -<section class="rule"> -<h3 data-toc-exclude id="noDangerouslySetInnerHtmlWithChildren"> - <a href="/lint/rules/noDangerouslySetInnerHtmlWithChildren">noDangerouslySetInnerHtmlWithChildren</a> - <span class="recommended">recommended</span> -</h3> -Report when a DOM element or a component uses both <code>children</code> and <code>dangerouslySetInnerHTML</code> prop. -</section> - -</div> - -## Style - -Rules enforcing a consistent way of writing your code. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noImplicitBoolean"> - <a href="/lint/rules/noImplicitBoolean">noImplicitBoolean</a> - <span class="recommended">recommended</span> -</h3> -Disallow implicit <code>true</code> values on JSX boolean attributes -</section> -<section class="rule"> -<h3 data-toc-exclude id="noNegationElse"> - <a href="/lint/rules/noNegationElse">noNegationElse</a> - <span class="recommended">recommended</span> -</h3> -Disallow negation in the condition of an <code>if</code> statement if it has an <code>else</code> clause -</section> -<section class="rule"> -<h3 data-toc-exclude id="noShoutyConstants"> - <a href="/lint/rules/noShoutyConstants">noShoutyConstants</a> - <span class="recommended">recommended</span> -</h3> -Disallow the use of constants which its value is the upper-case version of its name. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noUnusedTemplateLiteral"> - <a href="/lint/rules/noUnusedTemplateLiteral">noUnusedTemplateLiteral</a> - <span class="recommended">recommended</span> -</h3> -Disallow template literals if interpolation and special-character handling are not needed -</section> -<section class="rule"> -<h3 data-toc-exclude id="useBlockStatements"> - <a href="/lint/rules/useBlockStatements">useBlockStatements</a> - <span class="recommended">recommended</span> -</h3> -Requires following curly brace conventions. -JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useFragmentSyntax"> - <a href="/lint/rules/useFragmentSyntax">useFragmentSyntax</a> -</h3> -This rule enforces the use of <code><>...</></code> over <code><Fragment>...</Fragment></code>. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useOptionalChain"> - <a href="/lint/rules/useOptionalChain">useOptionalChain</a> - <span class="recommended">recommended</span> -</h3> -Enforce using concise optional chain instead of chained logical expressions. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useSelfClosingElements"> - <a href="/lint/rules/useSelfClosingElements">useSelfClosingElements</a> - <span class="recommended">recommended</span> -</h3> -Prevent extra closing tags for components without children -</section> -<section class="rule"> -<h3 data-toc-exclude id="useShorthandArrayType"> - <a href="/lint/rules/useShorthandArrayType">useShorthandArrayType</a> - <span class="recommended">recommended</span> -</h3> -When expressing array types, this rule promotes the usage of <code>T[]</code> shorthand instead of <code>Array<T></code>. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useSingleVarDeclarator"> - <a href="/lint/rules/useSingleVarDeclarator">useSingleVarDeclarator</a> - <span class="recommended">recommended</span> -</h3> -Disallow multiple variable declarations in the same variable statement -</section> -<section class="rule"> -<h3 data-toc-exclude id="useTemplate"> - <a href="/lint/rules/useTemplate">useTemplate</a> - <span class="recommended">recommended</span> -</h3> -Template literals are preferred over string concatenation. -</section> - -</div> - -## Nursery - -New rules that are still under development. - -Nursery rules require explicit opt-in via configuration because they may still have bugs or performance problems. -Nursery rules get promoted to other groups once they become stable or may be removed. - -Rules that belong to this group <strong>are not subject to semantic version</strong>. -<div class="category-rules"> -<section class="rule"> -<h3 data-toc-exclude id="noBannedTypes"> - <a href="/lint/rules/noBannedTypes">noBannedTypes</a> -</h3> -Disallow certain types. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noConstAssign"> - <a href="/lint/rules/noConstAssign">noConstAssign</a> -</h3> -Prevents from having <code>const</code> variables being re-assigned. -</section> -<section class="rule"> -<h3 data-toc-exclude id="noExplicitAny"> - <a href="/lint/rules/noExplicitAny">noExplicitAny</a> -</h3> -Disallow the <code>any</code> type usage -</section> -<section class="rule"> -<h3 data-toc-exclude id="noInvalidConstructorSuper"> - <a href="/lint/rules/noInvalidConstructorSuper">noInvalidConstructorSuper</a> -</h3> -Prevents the incorrect use of <code>super()</code> inside classes. -It also checks whether a call <code>super()</code> is missing from classes that extends other constructors. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useCamelCase"> - <a href="/lint/rules/useCamelCase">useCamelCase</a> -</h3> -Enforce camel case naming convention. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useExhaustiveDependencies"> - <a href="/lint/rules/useExhaustiveDependencies">useExhaustiveDependencies</a> -</h3> -Enforce all dependencies are correctly specified. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useFlatMap"> - <a href="/lint/rules/useFlatMap">useFlatMap</a> -</h3> -Promotes the use of <code>.flatMap()</code> when <code>map().flat()</code> are used together. -</section> -<section class="rule"> -<h3 data-toc-exclude id="useValidForDirection"> - <a href="/lint/rules/useValidForDirection">useValidForDirection</a> -</h3> -Enforce "for" loop update clause moving the counter in the right direction. -</section> - -</div> diff --git a/website/docs/src/lint/rules/useExhaustiveDependencies.md b/website/docs/src/lint/rules/useExhaustiveDependencies.md deleted file mode 100644 index 5739d0bcf30..00000000000 --- a/website/docs/src/lint/rules/useExhaustiveDependencies.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: Lint Rule useExhaustiveDependencies ---- - -# useExhaustiveDependencies (since v10.0.0) - -Enforce all dependencies are correctly specified. - -## Examples - -### Invalid - -```jsx -let a = 1; -useEffect(() => { - console.log(a); -}) -``` - -{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ - -<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook do not specify all of its dependencies.</span> - - <strong>1 │ </strong>let a = 1; -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { - <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> - <strong>3 │ </strong> console.log(a); - <strong>4 │ </strong>}) - -<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency is not specified in the hook dependency list.</span> - - <strong>1 │ </strong>let a = 1; - <strong>2 │ </strong>useEffect(() => { -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong> console.log(a); - <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> - <strong>4 │ </strong>}) - <strong>5 │ </strong> - -</code></pre>{% endraw %} - -```jsx -let b = 1; -useEffect(() => { -}, [b]) -``` - -{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ - -<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook specifies more dependencies than necessary.</span> - - <strong>1 │ </strong>let b = 1; -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { - <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> - <strong>3 │ </strong>}, [b]) - <strong>4 │ </strong> - -<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency can be removed from the list.</span> - - <strong>1 │ </strong>let b = 1; - <strong>2 │ </strong>useEffect(() => { -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong>}, [b]) - <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> - <strong>4 │ </strong> - -</code></pre>{% endraw %} - -```jsx -const [name, setName] = useState(); -useEffect(() => { - console.log(name); - setName(""); -}, [name, setName]) -``` - -{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ - -<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook specifies more dependencies than necessary.</span> - - <strong>1 │ </strong>const [name, setName] = useState(); -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { - <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> - <strong>3 │ </strong> console.log(name); - <strong>4 │ </strong> setName(""); - -<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency can be removed from the list.</span> - - <strong>3 │ </strong> console.log(name); - <strong>4 │ </strong> setName(""); -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>5 │ </strong>}, [name, setName]) - <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> - <strong>6 │ </strong> - -</code></pre>{% endraw %} - -```jsx -let a = 1; -const b = a + 1; -useEffect(() => { - console.log(b); -}) -``` - -{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:3:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ - -<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook do not specify all of its dependencies.</span> - - <strong>1 │ </strong>let a = 1; - <strong>2 │ </strong>const b = a + 1; -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong>useEffect(() => { - <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> - <strong>4 │ </strong> console.log(b); - <strong>5 │ </strong>}) - -<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency is not specified in the hook dependency list.</span> - - <strong>2 │ </strong>const b = a + 1; - <strong>3 │ </strong>useEffect(() => { -<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>4 │ </strong> console.log(b); - <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> - <strong>5 │ </strong>}) - <strong>6 │ </strong> - -</code></pre>{% endraw %} - -## Valid - -```jsx -let a = 1; -useEffect(() => { - console.log(a); -}, [a]); -``` - -```jsx -const a = 1; -useEffect(() => { - console.log(a); -}); -``` - -```jsx -const [name, setName] = useState(); -useEffect(() => { - console.log(name); - setName(""); -}, [name]) -``` - From 4654ffd847d53a6f9ceacd160ed03d50364c9639 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 15:12:56 -0300 Subject: [PATCH 5/7] push bindings from obj and array bindings --- crates/rome_js_semantic/src/events.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index b24c4dbac4a..9af3629d468 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -374,6 +374,8 @@ impl SemanticEventExtractor { JS_OBJECT_BINDING_PATTERN_SHORTHAND_PROPERTY | JS_OBJECT_BINDING_PATTERN_PROPERTY | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { + self.push_binding_into_scope(None, &name_token); + let possible_declarator = parent.ancestors().find(|x| { !matches!( x.kind(), From d04e70916371e420e12362502f221fe17e808c66 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 15:15:31 -0300 Subject: [PATCH 6/7] fmt and clippy issues --- crates/rome_js_semantic/src/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rome_js_semantic/src/events.rs b/crates/rome_js_semantic/src/events.rs index 9af3629d468..eeba4f29cb1 100644 --- a/crates/rome_js_semantic/src/events.rs +++ b/crates/rome_js_semantic/src/events.rs @@ -375,7 +375,7 @@ impl SemanticEventExtractor { | JS_OBJECT_BINDING_PATTERN_PROPERTY | JS_ARRAY_BINDING_PATTERN_ELEMENT_LIST => { self.push_binding_into_scope(None, &name_token); - + let possible_declarator = parent.ancestors().find(|x| { !matches!( x.kind(), From b5e7690db208ed19f4fdb532dc1614e0e779ea30 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite <xunilrj@hotmail.com> Date: Wed, 9 Nov 2022 16:51:04 -0300 Subject: [PATCH 7/7] updating lintdoc --- website/docs/src/lint/rules/index.md | 490 ++++++++++++++++++ .../lint/rules/useExhaustiveDependencies.md | 148 ++++++ 2 files changed, 638 insertions(+) create mode 100644 website/docs/src/lint/rules/index.md create mode 100644 website/docs/src/lint/rules/useExhaustiveDependencies.md diff --git a/website/docs/src/lint/rules/index.md b/website/docs/src/lint/rules/index.md new file mode 100644 index 00000000000..89b262267bc --- /dev/null +++ b/website/docs/src/lint/rules/index.md @@ -0,0 +1,490 @@ +--- +title: Lint Rules +main-class: rules +--- + +# Rules + + +## Accessibility + +Rules focused on preventing accessibility problems. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noAutofocus"> + <a href="/lint/rules/noAutofocus">noAutofocus</a> + <span class="recommended">recommended</span> +</h3> +Avoid the <code>autoFocus</code> attribute +</section> +<section class="rule"> +<h3 data-toc-exclude id="noPositiveTabindex"> + <a href="/lint/rules/noPositiveTabindex">noPositiveTabindex</a> + <span class="recommended">recommended</span> +</h3> +Prevent the usage of positive integers on <code>tabIndex</code> property +</section> +<section class="rule"> +<h3 data-toc-exclude id="useAltText"> + <a href="/lint/rules/useAltText">useAltText</a> + <span class="recommended">recommended</span> +</h3> +It asserts that alternative text to images or areas, help to rely on to screen readers to understand the purpose and the context of the image. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useAnchorContent"> + <a href="/lint/rules/useAnchorContent">useAnchorContent</a> + <span class="recommended">recommended</span> +</h3> +Enforce that anchor elements have content and that the content is accessible to screen readers. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useBlankTarget"> + <a href="/lint/rules/useBlankTarget">useBlankTarget</a> + <span class="recommended">recommended</span> +</h3> +Disallow <code>target="_blank"</code> attribute without <code>rel="noreferrer"</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="useButtonType"> + <a href="/lint/rules/useButtonType">useButtonType</a> + <span class="recommended">recommended</span> +</h3> +Enforces the usage of the attribute <code>type</code> for the element <code>button</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="useKeyWithClickEvents"> + <a href="/lint/rules/useKeyWithClickEvents">useKeyWithClickEvents</a> + <span class="recommended">recommended</span> +</h3> +Enforce to have the <code>onClick</code> mouse event with the <code>onKeyUp</code>, the <code>onKeyDown</code>, or the <code>noKeyPress</code> keyboard event. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useKeyWithMouseEvents"> + <a href="/lint/rules/useKeyWithMouseEvents">useKeyWithMouseEvents</a> + <span class="recommended">recommended</span> +</h3> +Enforce that <code>onMouseOver</code>/<code>onMouseOut</code> are accompanied by <code>onFocus</code>/<code>onBlur</code> for keyboard-only users. +It is important to take into account users with physical disabilities who cannot use a mouse, +who use assistive technology or screenreader. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useValidAnchor"> + <a href="/lint/rules/useValidAnchor">useValidAnchor</a> + <span class="recommended">recommended</span> +</h3> +Enforce that all anchors are valid, and they are navigable elements. +</section> + +</div> + +## Complexity + +Rules that focus on inspecting complex code that could be simplified. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noExtraBooleanCast"> + <a href="/lint/rules/noExtraBooleanCast">noExtraBooleanCast</a> + <span class="recommended">recommended</span> +</h3> +Disallow unnecessary boolean casts +</section> +<section class="rule"> +<h3 data-toc-exclude id="useSimplifiedLogicExpression"> + <a href="/lint/rules/useSimplifiedLogicExpression">useSimplifiedLogicExpression</a> + <span class="recommended">recommended</span> +</h3> +Discard redundant terms from logical expressions. +</section> + +</div> + +## Correctness + +Rules that detect incorrect or useless code. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noArguments"> + <a href="/lint/rules/noArguments">noArguments</a> + <span class="recommended">recommended</span> +</h3> +Disallow the use of <code>arguments</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="noArrayIndexKey"> + <a href="/lint/rules/noArrayIndexKey">noArrayIndexKey</a> + <span class="recommended">recommended</span> +</h3> +Discourage the usage of Array index in keys. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noAsyncPromiseExecutor"> + <a href="/lint/rules/noAsyncPromiseExecutor">noAsyncPromiseExecutor</a> + <span class="recommended">recommended</span> +</h3> +Disallows using an async function as a Promise executor. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noCatchAssign"> + <a href="/lint/rules/noCatchAssign">noCatchAssign</a> + <span class="recommended">recommended</span> +</h3> +Disallow reassigning exceptions in catch clauses +</section> +<section class="rule"> +<h3 data-toc-exclude id="noChildrenProp"> + <a href="/lint/rules/noChildrenProp">noChildrenProp</a> + <span class="recommended">recommended</span> +</h3> +Prevent passing of <strong>children</strong> as props. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noCommentText"> + <a href="/lint/rules/noCommentText">noCommentText</a> + <span class="recommended">recommended</span> +</h3> +Prevent comments from being inserted as text nodes +</section> +<section class="rule"> +<h3 data-toc-exclude id="noCompareNegZero"> + <a href="/lint/rules/noCompareNegZero">noCompareNegZero</a> + <span class="recommended">recommended</span> +</h3> +Disallow comparing against <code>-0</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="noDebugger"> + <a href="/lint/rules/noDebugger">noDebugger</a> + <span class="recommended">recommended</span> +</h3> +Disallow the use of <code>debugger</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="noDelete"> + <a href="/lint/rules/noDelete">noDelete</a> + <span class="recommended">recommended</span> +</h3> +Disallow the use of the <code>delete</code> operator +</section> +<section class="rule"> +<h3 data-toc-exclude id="noDoubleEquals"> + <a href="/lint/rules/noDoubleEquals">noDoubleEquals</a> + <span class="recommended">recommended</span> +</h3> +Require the use of <code>===</code> and <code>!==</code> +</section> +<section class="rule"> +<h3 data-toc-exclude id="noDupeArgs"> + <a href="/lint/rules/noDupeArgs">noDupeArgs</a> + <span class="recommended">recommended</span> +</h3> +Disallow duplicate function arguments name. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noEmptyPattern"> + <a href="/lint/rules/noEmptyPattern">noEmptyPattern</a> + <span class="recommended">recommended</span> +</h3> +Disallows empty destructuring patterns. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noFunctionAssign"> + <a href="/lint/rules/noFunctionAssign">noFunctionAssign</a> + <span class="recommended">recommended</span> +</h3> +Disallow reassigning function declarations. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noImportAssign"> + <a href="/lint/rules/noImportAssign">noImportAssign</a> + <span class="recommended">recommended</span> +</h3> +Disallow assigning to imported bindings +</section> +<section class="rule"> +<h3 data-toc-exclude id="noLabelVar"> + <a href="/lint/rules/noLabelVar">noLabelVar</a> + <span class="recommended">recommended</span> +</h3> +Disallow labels that share a name with a variable +</section> +<section class="rule"> +<h3 data-toc-exclude id="noMultipleSpacesInRegularExpressionLiterals"> + <a href="/lint/rules/noMultipleSpacesInRegularExpressionLiterals">noMultipleSpacesInRegularExpressionLiterals</a> + <span class="recommended">recommended</span> +</h3> +Disallow unclear usage of multiple space characters in regular expression literals +</section> +<section class="rule"> +<h3 data-toc-exclude id="noNewSymbol"> + <a href="/lint/rules/noNewSymbol">noNewSymbol</a> + <span class="recommended">recommended</span> +</h3> +Disallow <code>new</code> operators with the <code>Symbol</code> object +</section> +<section class="rule"> +<h3 data-toc-exclude id="noRenderReturnValue"> + <a href="/lint/rules/noRenderReturnValue">noRenderReturnValue</a> + <span class="recommended">recommended</span> +</h3> +Prevent the usage of the return value of <code>React.render</code>. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noRestrictedGlobals"> + <a href="/lint/rules/noRestrictedGlobals">noRestrictedGlobals</a> +</h3> +This rule allows you to specify global variable names that you don’t want to use in your application. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noShadowRestrictedNames"> + <a href="/lint/rules/noShadowRestrictedNames">noShadowRestrictedNames</a> + <span class="recommended">recommended</span> +</h3> +Disallow identifiers from shadowing restricted names. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noSparseArray"> + <a href="/lint/rules/noSparseArray">noSparseArray</a> + <span class="recommended">recommended</span> +</h3> +Disallow sparse arrays +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUndeclaredVariables"> + <a href="/lint/rules/noUndeclaredVariables">noUndeclaredVariables</a> +</h3> +Prevents the usage of variables that haven't been declared inside the document +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUnnecessaryContinue"> + <a href="/lint/rules/noUnnecessaryContinue">noUnnecessaryContinue</a> + <span class="recommended">recommended</span> +</h3> +Avoid using unnecessary <code>continue</code>. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUnreachable"> + <a href="/lint/rules/noUnreachable">noUnreachable</a> + <span class="recommended">recommended</span> +</h3> +Disallow unreachable code +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUnsafeNegation"> + <a href="/lint/rules/noUnsafeNegation">noUnsafeNegation</a> + <span class="recommended">recommended</span> +</h3> +Disallow using unsafe negation. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUnusedVariables"> + <a href="/lint/rules/noUnusedVariables">noUnusedVariables</a> +</h3> +Disallow unused variables. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUselessFragments"> + <a href="/lint/rules/noUselessFragments">noUselessFragments</a> +</h3> +Disallow unnecessary fragments +</section> +<section class="rule"> +<h3 data-toc-exclude id="noVoidElementsWithChildren"> + <a href="/lint/rules/noVoidElementsWithChildren">noVoidElementsWithChildren</a> + <span class="recommended">recommended</span> +</h3> +This rules prevents void elements (AKA self-closing elements) from having children. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useSingleCaseStatement"> + <a href="/lint/rules/useSingleCaseStatement">useSingleCaseStatement</a> + <span class="recommended">recommended</span> +</h3> +Enforces case clauses have a single statement, emits a quick fix wrapping +the statements in a block +</section> +<section class="rule"> +<h3 data-toc-exclude id="useValidTypeof"> + <a href="/lint/rules/useValidTypeof">useValidTypeof</a> + <span class="recommended">recommended</span> +</h3> +This rule verifies the result of <code>typeof $expr</code> unary expressions is being +compared to valid values, either string literals containing valid type +names or other <code>typeof</code> expressions +</section> +<section class="rule"> +<h3 data-toc-exclude id="useWhile"> + <a href="/lint/rules/useWhile">useWhile</a> + <span class="recommended">recommended</span> +</h3> +Enforce the use of <code>while</code> loops instead of <code>for</code> loops when the +initializer and update expressions are not needed +</section> + +</div> + +## Security + +Rules that detect potential security flaws. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noDangerouslySetInnerHtml"> + <a href="/lint/rules/noDangerouslySetInnerHtml">noDangerouslySetInnerHtml</a> + <span class="recommended">recommended</span> +</h3> +Prevent the usage of dangerous JSX props +</section> +<section class="rule"> +<h3 data-toc-exclude id="noDangerouslySetInnerHtmlWithChildren"> + <a href="/lint/rules/noDangerouslySetInnerHtmlWithChildren">noDangerouslySetInnerHtmlWithChildren</a> + <span class="recommended">recommended</span> +</h3> +Report when a DOM element or a component uses both <code>children</code> and <code>dangerouslySetInnerHTML</code> prop. +</section> + +</div> + +## Style + +Rules enforcing a consistent way of writing your code. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noImplicitBoolean"> + <a href="/lint/rules/noImplicitBoolean">noImplicitBoolean</a> + <span class="recommended">recommended</span> +</h3> +Disallow implicit <code>true</code> values on JSX boolean attributes +</section> +<section class="rule"> +<h3 data-toc-exclude id="noNegationElse"> + <a href="/lint/rules/noNegationElse">noNegationElse</a> + <span class="recommended">recommended</span> +</h3> +Disallow negation in the condition of an <code>if</code> statement if it has an <code>else</code> clause +</section> +<section class="rule"> +<h3 data-toc-exclude id="noShoutyConstants"> + <a href="/lint/rules/noShoutyConstants">noShoutyConstants</a> + <span class="recommended">recommended</span> +</h3> +Disallow the use of constants which its value is the upper-case version of its name. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noUnusedTemplateLiteral"> + <a href="/lint/rules/noUnusedTemplateLiteral">noUnusedTemplateLiteral</a> + <span class="recommended">recommended</span> +</h3> +Disallow template literals if interpolation and special-character handling are not needed +</section> +<section class="rule"> +<h3 data-toc-exclude id="useBlockStatements"> + <a href="/lint/rules/useBlockStatements">useBlockStatements</a> + <span class="recommended">recommended</span> +</h3> +Requires following curly brace conventions. +JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useFragmentSyntax"> + <a href="/lint/rules/useFragmentSyntax">useFragmentSyntax</a> +</h3> +This rule enforces the use of <code><>...</></code> over <code><Fragment>...</Fragment></code>. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useOptionalChain"> + <a href="/lint/rules/useOptionalChain">useOptionalChain</a> + <span class="recommended">recommended</span> +</h3> +Enforce using concise optional chain instead of chained logical expressions. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useSelfClosingElements"> + <a href="/lint/rules/useSelfClosingElements">useSelfClosingElements</a> + <span class="recommended">recommended</span> +</h3> +Prevent extra closing tags for components without children +</section> +<section class="rule"> +<h3 data-toc-exclude id="useShorthandArrayType"> + <a href="/lint/rules/useShorthandArrayType">useShorthandArrayType</a> + <span class="recommended">recommended</span> +</h3> +When expressing array types, this rule promotes the usage of <code>T[]</code> shorthand instead of <code>Array<T></code>. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useSingleVarDeclarator"> + <a href="/lint/rules/useSingleVarDeclarator">useSingleVarDeclarator</a> + <span class="recommended">recommended</span> +</h3> +Disallow multiple variable declarations in the same variable statement +</section> +<section class="rule"> +<h3 data-toc-exclude id="useTemplate"> + <a href="/lint/rules/useTemplate">useTemplate</a> + <span class="recommended">recommended</span> +</h3> +Template literals are preferred over string concatenation. +</section> + +</div> + +## Nursery + +New rules that are still under development. + +Nursery rules require explicit opt-in via configuration because they may still have bugs or performance problems. +Nursery rules get promoted to other groups once they become stable or may be removed. + +Rules that belong to this group <strong>are not subject to semantic version</strong>. +<div class="category-rules"> +<section class="rule"> +<h3 data-toc-exclude id="noBannedTypes"> + <a href="/lint/rules/noBannedTypes">noBannedTypes</a> +</h3> +Disallow certain types. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noConstAssign"> + <a href="/lint/rules/noConstAssign">noConstAssign</a> +</h3> +Prevents from having <code>const</code> variables being re-assigned. +</section> +<section class="rule"> +<h3 data-toc-exclude id="noExplicitAny"> + <a href="/lint/rules/noExplicitAny">noExplicitAny</a> +</h3> +Disallow the <code>any</code> type usage +</section> +<section class="rule"> +<h3 data-toc-exclude id="noInvalidConstructorSuper"> + <a href="/lint/rules/noInvalidConstructorSuper">noInvalidConstructorSuper</a> +</h3> +Prevents the incorrect use of <code>super()</code> inside classes. +It also checks whether a call <code>super()</code> is missing from classes that extends other constructors. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useCamelCase"> + <a href="/lint/rules/useCamelCase">useCamelCase</a> +</h3> +Enforce camel case naming convention. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useExhaustiveDependencies"> + <a href="/lint/rules/useExhaustiveDependencies">useExhaustiveDependencies</a> +</h3> +Enforce all dependencies are correctly specified. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useFlatMap"> + <a href="/lint/rules/useFlatMap">useFlatMap</a> +</h3> +Promotes the use of <code>.flatMap()</code> when <code>map().flat()</code> are used together. +</section> +<section class="rule"> +<h3 data-toc-exclude id="useValidForDirection"> + <a href="/lint/rules/useValidForDirection">useValidForDirection</a> +</h3> +Enforce "for" loop update clause moving the counter in the right direction. +</section> + +</div> diff --git a/website/docs/src/lint/rules/useExhaustiveDependencies.md b/website/docs/src/lint/rules/useExhaustiveDependencies.md new file mode 100644 index 00000000000..5739d0bcf30 --- /dev/null +++ b/website/docs/src/lint/rules/useExhaustiveDependencies.md @@ -0,0 +1,148 @@ +--- +title: Lint Rule useExhaustiveDependencies +--- + +# useExhaustiveDependencies (since v10.0.0) + +Enforce all dependencies are correctly specified. + +## Examples + +### Invalid + +```jsx +let a = 1; +useEffect(() => { + console.log(a); +}) +``` + +{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ + +<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook do not specify all of its dependencies.</span> + + <strong>1 │ </strong>let a = 1; +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { + <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> + <strong>3 │ </strong> console.log(a); + <strong>4 │ </strong>}) + +<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency is not specified in the hook dependency list.</span> + + <strong>1 │ </strong>let a = 1; + <strong>2 │ </strong>useEffect(() => { +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong> console.log(a); + <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> + <strong>4 │ </strong>}) + <strong>5 │ </strong> + +</code></pre>{% endraw %} + +```jsx +let b = 1; +useEffect(() => { +}, [b]) +``` + +{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ + +<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook specifies more dependencies than necessary.</span> + + <strong>1 │ </strong>let b = 1; +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { + <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> + <strong>3 │ </strong>}, [b]) + <strong>4 │ </strong> + +<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency can be removed from the list.</span> + + <strong>1 │ </strong>let b = 1; + <strong>2 │ </strong>useEffect(() => { +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong>}, [b]) + <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> + <strong>4 │ </strong> + +</code></pre>{% endraw %} + +```jsx +const [name, setName] = useState(); +useEffect(() => { + console.log(name); + setName(""); +}, [name, setName]) +``` + +{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:2:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ + +<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook specifies more dependencies than necessary.</span> + + <strong>1 │ </strong>const [name, setName] = useState(); +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>2 │ </strong>useEffect(() => { + <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> + <strong>3 │ </strong> console.log(name); + <strong>4 │ </strong> setName(""); + +<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency can be removed from the list.</span> + + <strong>3 │ </strong> console.log(name); + <strong>4 │ </strong> setName(""); +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>5 │ </strong>}, [name, setName]) + <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> + <strong>6 │ </strong> + +</code></pre>{% endraw %} + +```jsx +let a = 1; +const b = a + 1; +useEffect(() => { + console.log(b); +}) +``` + +{% raw %}<pre class="language-text"><code class="language-text">nursery/useExhaustiveDependencies.js:3:1 <a href="https://docs.rome.tools/lint/rules/useExhaustiveDependencies">lint/nursery/useExhaustiveDependencies</a> ━━━━━━━━━━━━━━━━━━━━ + +<strong><span style="color: Orange;"> </span></strong><strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This hook do not specify all of its dependencies.</span> + + <strong>1 │ </strong>let a = 1; + <strong>2 │ </strong>const b = a + 1; +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>3 │ </strong>useEffect(() => { + <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong> + <strong>4 │ </strong> console.log(b); + <strong>5 │ </strong>}) + +<strong><span style="color: rgb(38, 148, 255);"> </span></strong><strong><span style="color: rgb(38, 148, 255);">ℹ</span></strong> <span style="color: rgb(38, 148, 255);">This dependency is not specified in the hook dependency list.</span> + + <strong>2 │ </strong>const b = a + 1; + <strong>3 │ </strong>useEffect(() => { +<strong><span style="color: Tomato;"> </span></strong><strong><span style="color: Tomato;">></span></strong> <strong>4 │ </strong> console.log(b); + <strong> │ </strong> <strong><span style="color: Tomato;">^</span></strong> + <strong>5 │ </strong>}) + <strong>6 │ </strong> + +</code></pre>{% endraw %} + +## Valid + +```jsx +let a = 1; +useEffect(() => { + console.log(a); +}, [a]); +``` + +```jsx +const a = 1; +useEffect(() => { + console.log(a); +}); +``` + +```jsx +const [name, setName] = useState(); +useEffect(() => { + console.log(name); + setName(""); +}, [name]) +``` +