|
1 |
| -use crate::{semantic_services::Semantic, utils::batch::JsBatchMutation, JsRuleAction}; |
2 |
| -use rome_analyze::{ |
3 |
| - context::RuleContext, declare_rule, ActionCategory, Rule, RuleCategory, RuleDiagnostic, |
4 |
| -}; |
| 1 | +use crate::semantic_services::Semantic; |
| 2 | +use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleCategory, RuleDiagnostic}; |
5 | 3 | use rome_console::markup;
|
6 |
| -use rome_diagnostics::Applicability; |
7 | 4 | use rome_js_semantic::{AllReferencesExtensions, SemanticScopeExtensions};
|
8 | 5 | use rome_js_syntax::{
|
9 |
| - JsCatchDeclaration, JsConstructorParameterList, JsConstructorParameters, JsFormalParameter, |
10 |
| - JsFunctionDeclaration, JsIdentifierBinding, JsParameterList, JsParameters, JsSyntaxKind, |
| 6 | + JsClassExpression, JsConstructorParameterList, JsConstructorParameters, JsFunctionDeclaration, |
| 7 | + JsFunctionExpression, JsIdentifierBinding, JsParameterList, JsParameters, JsSyntaxKind, |
11 | 8 | JsVariableDeclarator,
|
12 | 9 | };
|
13 |
| -use rome_rowan::{AstNode, BatchMutationExt}; |
| 10 | +use rome_rowan::AstNode; |
14 | 11 |
|
15 | 12 | declare_rule! {
|
16 | 13 | /// Disallow unused variables.
|
@@ -65,6 +62,20 @@ declare_rule! {
|
65 | 62 | /// };
|
66 | 63 | /// foo();
|
67 | 64 | /// ```
|
| 65 | + /// |
| 66 | + /// ```js |
| 67 | + /// function foo(_unused) { |
| 68 | + /// }; |
| 69 | + /// foo(); |
| 70 | + /// ``` |
| 71 | + /// |
| 72 | + /// ```jsx |
| 73 | + /// import React from 'react'; |
| 74 | + /// function foo() { |
| 75 | + /// return <div />; |
| 76 | + /// }; |
| 77 | + /// foo(); |
| 78 | + /// ``` |
68 | 79 | pub(crate) NoUnusedVariables {
|
69 | 80 | version: "0.9.0",
|
70 | 81 | name: "noUnusedVariables",
|
@@ -117,12 +128,28 @@ impl Rule for NoUnusedVariables {
|
117 | 128 |
|
118 | 129 | fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
|
119 | 130 | let binding = ctx.query();
|
120 |
| - let model = ctx.model(); |
| 131 | + let name = binding.name_token().ok()?; |
| 132 | + let name = name.token_text_trimmed(); |
| 133 | + let name = name.text(); |
| 134 | + |
| 135 | + // Old code import React but do not used directly |
| 136 | + // only indirectly after transpiling JSX. |
| 137 | + if name.starts_with('_') || name == "React" { |
| 138 | + return None; |
| 139 | + } |
| 140 | + |
| 141 | + // Ignore expressions |
| 142 | + if binding.parent::<JsFunctionExpression>().is_some() |
| 143 | + || binding.parent::<JsClassExpression>().is_some() |
| 144 | + { |
| 145 | + return None; |
| 146 | + } |
121 | 147 |
|
122 | 148 | if is_typescript_unused_ok(binding).is_some() {
|
123 | 149 | return None;
|
124 | 150 | }
|
125 | 151 |
|
| 152 | + let model = ctx.model(); |
126 | 153 | if model.is_exported(binding) {
|
127 | 154 | return None;
|
128 | 155 | }
|
@@ -198,43 +225,4 @@ impl Rule for NoUnusedVariables {
|
198 | 225 |
|
199 | 226 | Some(diag)
|
200 | 227 | }
|
201 |
| - |
202 |
| - fn action(ctx: &RuleContext<Self>, _: &Self::State) -> Option<JsRuleAction> { |
203 |
| - let root = ctx.root(); |
204 |
| - let binding = ctx.query(); |
205 |
| - |
206 |
| - let mut batch = root.begin(); |
207 |
| - |
208 |
| - // Try to remove node |
209 |
| - let removed = if let Some(declaration) = binding.parent::<JsFunctionDeclaration>() { |
210 |
| - batch.remove_node(declaration); |
211 |
| - true |
212 |
| - } else if let Some(variable_declarator) = binding.parent::<JsVariableDeclarator>() { |
213 |
| - batch.remove_js_variable_declarator(&variable_declarator) |
214 |
| - } else if let Some(formal_parameter) = binding.parent::<JsFormalParameter>() { |
215 |
| - batch.remove_js_formal_parameter(&formal_parameter) |
216 |
| - } else if let Some(catch_declaration) = binding.parent::<JsCatchDeclaration>() { |
217 |
| - batch.remove_node(catch_declaration); |
218 |
| - true |
219 |
| - } else { |
220 |
| - false |
221 |
| - }; |
222 |
| - |
223 |
| - if removed { |
224 |
| - let symbol_type = match binding.syntax().parent().unwrap().kind() { |
225 |
| - JsSyntaxKind::JS_FORMAL_PARAMETER => "parameter", |
226 |
| - JsSyntaxKind::JS_FUNCTION_DECLARATION => "function", |
227 |
| - _ => "variable", |
228 |
| - }; |
229 |
| - |
230 |
| - Some(JsRuleAction { |
231 |
| - category: ActionCategory::QuickFix, |
232 |
| - applicability: Applicability::MaybeIncorrect, |
233 |
| - message: markup! { "Remove this " {symbol_type} "." }.to_owned(), |
234 |
| - mutation: batch, |
235 |
| - }) |
236 |
| - } else { |
237 |
| - None |
238 |
| - } |
239 |
| - } |
240 | 228 | }
|
0 commit comments