diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/react_extensive_dependencies.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/react_extensive_dependencies.rs index b6195e5ddfc6..75b5c5f70b97 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/react_extensive_dependencies.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/react_extensive_dependencies.rs @@ -1,22 +1,13 @@ -use crate::{ - semantic_services::Semantic, - utils::{rename::RenameSymbolExtensions, ToCamelCase}, - JsRuleAction, -}; -use rome_analyze::{ - context::RuleContext, declare_rule, ActionCategory, Rule, RuleCategory, RuleDiagnostic, -}; +use crate::semantic_services::Semantic; +use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic}; use rome_console::markup; -use rome_diagnostics::Applicability; -use rome_js_semantic::{AllReferencesExtensions, IsExportedCanBeQueried, SemanticModel, Capture}; +use rome_js_semantic::{Capture, SemanticModel}; use rome_js_syntax::{ - JsFormalParameter, JsFunctionDeclaration, JsFunctionExportDefaultDeclaration, - JsGetterClassMember, JsIdentifierBinding, JsLiteralMemberName, JsMethodClassMember, - JsPrivateClassMemberName, JsPropertyClassMember, JsSetterClassMember, JsSyntaxKind, - JsVariableDeclaration, JsVariableDeclarator, JsVariableDeclaratorList, JsxReferenceIdentifier, JsCallExpression, JsAnyCallArgument, JsArrowFunctionExpression, JsArrayExpression, JsAnyExpression, JsLanguage, SyntaxNodeText, TextRange, + JsAnyCallArgument, JsAnyExpression, JsArrayExpression, JsArrowFunctionExpression, + JsCallExpression, JsSyntaxKind, TextRange, }; -use rome_rowan::{declare_node_union, AstNode, BatchMutationExt, SyntaxTokenText, SyntaxNode}; -use std::{borrow::Cow, iter::once, collections::{BTreeSet, HashSet, HashMap}}; +use rome_rowan::AstNode; +use std::collections::HashMap; declare_rule! { /// Enforce all dependencies are correctly specified. @@ -28,11 +19,6 @@ declare_rule! { } } -pub enum Todo { - AddDependency { capture: Vec> }, - RemoveDependency { dep: JsAnyExpression } -} - impl Rule for ReactExtensiveDependencies { type Query = Semantic; type State = (TextRange, Vec); @@ -42,35 +28,34 @@ impl Rule for ReactExtensiveDependencies { let mut signals = vec![]; let node = ctx.query(); - if let Some(useEffect) = ReactUseEffectCallExpression::new(node) { - let range = match useEffect.callee_trimmed_range() { + if let Some(use_effect) = ReactUseEffectCallExpression::new(node) { + let range = match use_effect.callee_trimmed_range() { Some(range) => range, None => return signals, }; let model = ctx.model(); - let function = useEffect.effect().unwrap(); - let captures: Vec<_> = function.all_captures(model) - .map(|x| { - ( - x.node().text_trimmed().to_string(), - x - ) - }) + let function = use_effect.effect().unwrap(); + let captures: Vec<_> = function + .all_captures(model) + .map(|x| (x.node().text_trimmed().to_string(), x)) .collect(); - let deps: Vec = useEffect.deps().map(|deps| { - deps.items() - .into_iter() - .map(|x| x.syntax().text_trimmed().to_string()) - .collect() - }).unwrap_or_default(); + let deps: Vec = use_effect + .deps() + .map(|deps| { + deps.items() + .into_iter() + .map(|x| x.syntax().text_trimmed().to_string()) + .collect() + }) + .unwrap_or_default(); dbg!(&captures.iter().map(|x| &x.0).collect::>()); dbg!(&deps); let mut add_deps: HashMap> = HashMap::new(); - + // Search for captures not in the dependency for (text, capture) in captures.iter() { if !deps.contains(text) { @@ -81,20 +66,18 @@ impl Rule for ReactExtensiveDependencies { // Search for dependencies not captured - for (text, captures) in add_deps { - signals.push((range.clone(), captures)); + for (_, captures) in add_deps { + signals.push((range, captures)); } } - + signals } - fn diagnostic(ctx: &RuleContext, dep: &Self::State) -> Option { - let node = ctx.query(); - + fn diagnostic(_: &RuleContext, dep: &Self::State) -> Option { let diag = RuleDiagnostic::new( rule_category!(), - dep.0.clone(), + dep.0, markup! { "This useEffect has missing dependencies" }, @@ -104,7 +87,10 @@ impl Rule for ReactExtensiveDependencies { for capture in dep.1.iter() { let node = capture.node(); - diag = diag.secondary(node.text_trimmed_range(), "This capture is not in the dependency list"); + diag = diag.secondary( + node.text_trimmed_range(), + "This capture is not in the dependency list", + ); } Some(diag) @@ -118,7 +104,7 @@ struct ReactUseEffectCallExpression<'a> { } pub enum ReactUseEffectEffect<'a> { - JsArrowFunctionExpression(&'a JsArrowFunctionExpression) + JsArrowFunctionExpression(&'a JsArrowFunctionExpression), } impl<'a> ReactUseEffectEffect<'a> { @@ -128,24 +114,23 @@ impl<'a> ReactUseEffectEffect<'a> { JsArrowFunctionExpression(node) => { let closure = model.closure(*node); closure.all_captures() - }, - } + } + } } } pub enum ReactUseEffectDeps<'a> { - JsArrayExpression(&'a JsArrayExpression) + JsArrayExpression(&'a JsArrayExpression), } impl<'a> ReactUseEffectDeps<'a> { pub fn items(&self) -> Vec { match self { - ReactUseEffectDeps::JsArrayExpression(node) => { - node.elements() - .into_iter() - .filter_map(|x| x.ok()?.as_js_any_expression().cloned()) - .collect() - }, + ReactUseEffectDeps::JsArrayExpression(node) => node + .elements() + .into_iter() + .filter_map(|x| x.ok()?.as_js_any_expression().cloned()) + .collect(), } } } @@ -154,16 +139,16 @@ impl<'a> ReactUseEffectCallExpression<'a> { pub fn new(call: &'a JsCallExpression) -> Option { let name = call.callee().ok()?.syntax().text_trimmed(); (name == "useEffect").then(|| { - let (effect, deps) = call.arguments() - .map(|args| { - let mut args = args.args().into_iter(); - let effect = args.next() - .and_then(|x| x.ok()); - let deps = args.next() - .and_then(|x| x.ok()); - (effect, deps) - }).unwrap_or((None, None)); - + let (effect, deps) = call + .arguments() + .map(|args| { + let mut args = args.args().into_iter(); + let effect = args.next().and_then(|x| x.ok()); + let deps = args.next().and_then(|x| x.ok()); + (effect, deps) + }) + .unwrap_or((None, None)); + Self { call, effect, deps } }) } @@ -171,7 +156,7 @@ impl<'a> ReactUseEffectCallExpression<'a> { pub fn callee_trimmed_range(&self) -> Option { Some(self.call.callee().ok()?.syntax().text_trimmed_range()) } - + pub fn effect(&self) -> Option { let expr = self.effect.as_ref()?.as_js_any_expression()?; match expr.syntax().kind() { @@ -179,7 +164,7 @@ impl<'a> ReactUseEffectCallExpression<'a> { let expr = expr.as_js_arrow_function_expression()?; Some(ReactUseEffectEffect::JsArrowFunctionExpression(expr)) } - _ => None + _ => None, } } @@ -190,7 +175,7 @@ impl<'a> ReactUseEffectCallExpression<'a> { let expr = expr.as_js_array_expression()?; Some(ReactUseEffectDeps::JsArrayExpression(expr)) } - _ => None + _ => None, } } -} \ No newline at end of file +}