From 08a46dec7ec98ff8e1a1cdb3af684b312e82627f Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 14 Sep 2022 09:03:13 +0100 Subject: [PATCH] feat(rome_js_analyze): useCamelCase accepts function when they are used in new or exported (#3210) --- .../nursery/use_camel_case.rs | 47 ++++++++++++++----- .../tests/specs/nursery/useCamelCase.js | 9 ++++ .../tests/specs/nursery/useCamelCase.js.snap | 29 ++++++++++++ 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_camel_case.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_camel_case.rs index 844feb9a444..e04ce413e69 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_camel_case.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_camel_case.rs @@ -8,6 +8,7 @@ use rome_analyze::{ }; use rome_console::markup; use rome_diagnostics::Applicability; +use rome_js_semantic::{AllReferencesExtensions, IsExportedCanBeQueried, SemanticModel}; use rome_js_syntax::{ JsFormalParameter, JsFunctionDeclaration, JsFunctionExportDefaultDeclaration, JsGetterClassMember, JsIdentifierBinding, JsLiteralMemberName, JsMethodClassMember, @@ -60,18 +61,39 @@ fn check_is_camel(name: &str) -> Option { } // It is OK to be non camel case when: -// 1. it's a const variable (eg: const THIS_IS_OK) -fn is_non_camel_ok(binding: &JsIdentifierBinding) -> Option { +// 1. it's a const variable (eg: const THIS_IS_OK); +// 2. it's a function used in a new expression (eg: new PascalCase()); +// 3. it's a exported function. +fn is_non_camel_ok(binding: &JsIdentifierBinding, model: &SemanticModel) -> Option { use JsSyntaxKind::*; - let declarator = binding.parent::()?; - let is_ok = match declarator.syntax().parent().map(|parent| parent.kind()) { - Some(JS_VARIABLE_DECLARATOR_LIST) => declarator - .parent::()? - .parent::()? - .is_const(), - _ => false, - }; - Some(is_ok) + match binding.syntax().parent()?.kind() { + JS_VARIABLE_DECLARATOR => { + let declarator = binding.parent::()?; + let is_ok = match declarator.syntax().parent().map(|parent| parent.kind()) { + Some(JS_VARIABLE_DECLARATOR_LIST) => declarator + .parent::()? + .parent::()? + .is_const(), + _ => false, + }; + Some(is_ok) + } + JS_FUNCTION_DECLARATION => { + if binding.is_exported(model) { + return Some(true); + } + + for reference in binding.all_reads(model) { + let greatparent = reference.node().grand_parent()?; + if let JS_NEW_EXPRESSION = greatparent.kind() { + return Some(true); + } + } + + Some(false) + } + _ => Some(false), + } } impl Rule for UseCamelCase { @@ -83,10 +105,11 @@ impl Rule for UseCamelCase { fn run(ctx: &RuleContext) -> Option { let name = ctx.query(); + let model = ctx.model(); match name { JsAnyCamelCaseName::JsIdentifierBinding(binding) => { - let is_non_camel_ok = is_non_camel_ok(binding); + let is_non_camel_ok = is_non_camel_ok(binding, model); match is_non_camel_ok { Some(false) | None => { let is_variable = binding.parent::().is_some(); diff --git a/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js b/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js index e25996c0fe5..e818decbde5 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js +++ b/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js @@ -35,3 +35,12 @@ let [ UPPER_CASE ] = env; const THIS_IS_OK = 1; const { THIS_IS_OK } = env; const [ THIS_IS_OK ] = env; + +function PascalCaseOkBecauseNew() { } +console.log(new PascalCaseOkBecauseNew()); + +function PascalCaseOkBecauseExport() { } +export default PascalCaseOkBecauseExport; + +function PascalCaseNOk() { } +console.log(PascalCaseNOk()); diff --git a/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js.snap index b8507c11b56..5be10545027 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/useCamelCase.js.snap @@ -42,6 +42,15 @@ const THIS_IS_OK = 1; const { THIS_IS_OK } = env; const [ THIS_IS_OK ] = env; +function PascalCaseOkBecauseNew() { } +console.log(new PascalCaseOkBecauseNew()); + +function PascalCaseOkBecauseExport() { } +export default PascalCaseOkBecauseExport; + +function PascalCaseNOk() { } +console.log(PascalCaseNOk()); + ``` # Diagnostics @@ -199,4 +208,24 @@ Safe fix: Rename this symbol to camel case ``` +``` +warning[nursery/useCamelCase]: Prefer functions names in camel case. + ┌─ useCamelCase.js:45:10 + │ +45 │ function PascalCaseNOk() { } + │ ------------- + +Safe fix: Rename this symbol to camel case + | @@ -42,5 +42,5 @@ +41 41 | function PascalCaseOkBecauseExport() { } +42 42 | export default PascalCaseOkBecauseExport; +43 43 | +44 | - function PascalCaseNOk() { } +45 | - console.log(PascalCaseNOk()); + 44 | + function pascalCaseNOk() { } + 45 | + console.log(pascalCaseNOk()); + + +``` +