diff --git a/crates/rome_js_analyze/src/analyzers/nursery/use_literal_keys.rs b/crates/rome_js_analyze/src/analyzers/nursery/use_literal_keys.rs index 0aa18d0efc6..999d9945981 100644 --- a/crates/rome_js_analyze/src/analyzers/nursery/use_literal_keys.rs +++ b/crates/rome_js_analyze/src/analyzers/nursery/use_literal_keys.rs @@ -9,7 +9,7 @@ use rome_js_syntax::{ AnyJsComputedMember, AnyJsExpression, AnyJsLiteralExpression, AnyJsName, JsComputedMemberName, JsLiteralMemberName, JsSyntaxKind, T, }; -use rome_js_unicode_table::{is_id_continue, is_id_start}; +use rome_js_unicode_table::is_js_ident; use rome_rowan::{declare_node_union, AstNode, BatchMutationExt, TextRange}; declare_rule! { @@ -153,15 +153,3 @@ impl Rule for UseLiteralKeys { declare_node_union! { pub(crate) AnyJsMember = AnyJsComputedMember | JsLiteralMemberName | JsComputedMemberName } - -// This function check if the key is valid JavaScript identifier. -// Currently, it doesn't check escaped unicode chars. -fn is_js_ident(key: &str) -> bool { - key.chars().enumerate().all(|(index, c)| { - if index == 0 { - is_id_start(c) - } else { - is_id_continue(c) - } - }) -} diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_naming_convention.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_naming_convention.rs index 4c97fcf14bf..48aba09f8dc 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_naming_convention.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/use_naming_convention.rs @@ -22,6 +22,7 @@ use rome_js_syntax::{ JsLiteralMemberName, JsPrivateClassMemberName, JsSyntaxKind, JsSyntaxToken, JsVariableDeclarator, JsVariableKind, TsEnumMember, TsIdentifierBinding, TsTypeParameterName, }; +use rome_js_unicode_table::is_js_ident; use rome_json_syntax::JsonLanguage; use rome_rowan::{ declare_node_union, AstNode, AstNodeList, BatchMutationExt, SyntaxNode, SyntaxResult, @@ -289,7 +290,14 @@ impl Rule for UseNamingConvention { return None; } let name_token = node.name_token().ok()?; - let name = name_token.text_trimmed(); + let mut name = name_token.text_trimmed(); + if name_token.kind() == JsSyntaxKind::JS_STRING_LITERAL { + name = &name[1..name.len() - 1]; + } + if !is_js_ident(name) { + // ignore non-identifier strings + return None; + } let trimmed_name = trim_underscore_dollar(name); let actual_case = Case::identify(trimmed_name, options.strict_case); if trimmed_name.is_empty() @@ -315,7 +323,10 @@ impl Rule for UseNamingConvention { suggested_name, } = state; let name_token = ctx.query().name_token().ok()?; - let name = name_token.text_trimmed(); + let mut name = name_token.text_trimmed(); + if name_token.kind() == JsSyntaxKind::JS_STRING_LITERAL { + name = &name[1..name.len() - 1]; + } let trimmed_name = trim_underscore_dollar(name); let allowed_cases = element.allowed_cases(ctx.options()); let allowed_case_names = allowed_cases @@ -622,10 +633,6 @@ impl Named { Named::from_binding_declaration(&binding.declaration()?) } AnyName::JsLiteralMemberName(member_name) => { - // ignore quoted names - if member_name.value().ok()?.kind() == JsSyntaxKind::JS_STRING_LITERAL { - return None; - } if let Some(member) = member_name.parent::() { Named::from_class_member(&member) } else if let Some(member) = member_name.parent::() { diff --git a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js index 79dcdc5f64d..2760e2caa31 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js +++ b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js @@ -1,6 +1,8 @@ export default class { X + "Y" = 0 + #X Initialized = 0 diff --git a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js.snap index 30dde674744..4ce9f3ca20c 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/invalidClassProperty.js.snap @@ -7,6 +7,8 @@ expression: invalidClassProperty.js export default class { X + "Y" = 0 + #X Initialized = 0 @@ -45,7 +47,7 @@ invalidClassProperty.js:2:5 lint/nursery/useNamingConvention ━━━━━━ > 2 │ X │ ^ 3 │ - 4 │ #X + 4 │ "Y" = 0 i The name could be renamed to `x`. @@ -59,12 +61,12 @@ invalidClassProperty.js:4:5 lint/nursery/useNamingConvention ━━━━━━ 2 │ X 3 │ - > 4 │ #X - │ ^^ + > 4 │ "Y" = 0 + │ ^^^ 5 │ - 6 │ Initialized = 0 + 6 │ #X - i The name could be renamed to `x`. + i The name could be renamed to `y`. ``` @@ -74,14 +76,14 @@ invalidClassProperty.js:6:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 4 │ #X + 4 │ "Y" = 0 5 │ - > 6 │ Initialized = 0 - │ ^^^^^^^^^^^ + > 6 │ #X + │ ^^ 7 │ - 8 │ #Initialized = 0 + 8 │ Initialized = 0 - i The name could be renamed to `initialized`. + i The name could be renamed to `x`. ``` @@ -91,12 +93,12 @@ invalidClassProperty.js:8:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 6 │ Initialized = 0 + 6 │ #X 7 │ - > 8 │ #Initialized = 0 - │ ^^^^^^^^^^^^ + > 8 │ Initialized = 0 + │ ^^^^^^^^^^^ 9 │ - 10 │ PROPERTY + 10 │ #Initialized = 0 i The name could be renamed to `initialized`. @@ -108,14 +110,14 @@ invalidClassProperty.js:10:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 8 │ #Initialized = 0 + 8 │ Initialized = 0 9 │ - > 10 │ PROPERTY - │ ^^^^^^^^ + > 10 │ #Initialized = 0 + │ ^^^^^^^^^^^^ 11 │ - 12 │ #PROPERTY + 12 │ PROPERTY - i The name could be renamed to `property`. + i The name could be renamed to `initialized`. ``` @@ -125,12 +127,12 @@ invalidClassProperty.js:12:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 10 │ PROPERTY + 10 │ #Initialized = 0 11 │ - > 12 │ #PROPERTY - │ ^^^^^^^^^ + > 12 │ PROPERTY + │ ^^^^^^^^ 13 │ - 14 │ SpecialProperty + 14 │ #PROPERTY i The name could be renamed to `property`. @@ -142,14 +144,14 @@ invalidClassProperty.js:14:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 12 │ #PROPERTY + 12 │ PROPERTY 13 │ - > 14 │ SpecialProperty - │ ^^^^^^^^^^^^^^^ + > 14 │ #PROPERTY + │ ^^^^^^^^^ 15 │ - 16 │ #SpecialProperty + 16 │ SpecialProperty - i The name could be renamed to `specialProperty`. + i The name could be renamed to `property`. ``` @@ -159,12 +161,12 @@ invalidClassProperty.js:16:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 14 │ SpecialProperty + 14 │ #PROPERTY 15 │ - > 16 │ #SpecialProperty - │ ^^^^^^^^^^^^^^^^ + > 16 │ SpecialProperty + │ ^^^^^^^^^^^^^^^ 17 │ - 18 │ special_property + 18 │ #SpecialProperty i The name could be renamed to `specialProperty`. @@ -176,12 +178,12 @@ invalidClassProperty.js:18:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 16 │ #SpecialProperty + 16 │ SpecialProperty 17 │ - > 18 │ special_property + > 18 │ #SpecialProperty │ ^^^^^^^^^^^^^^^^ 19 │ - 20 │ #special_property + 20 │ special_property i The name could be renamed to `specialProperty`. @@ -193,12 +195,12 @@ invalidClassProperty.js:20:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 18 │ special_property + 18 │ #SpecialProperty 19 │ - > 20 │ #special_property - │ ^^^^^^^^^^^^^^^^^ + > 20 │ special_property + │ ^^^^^^^^^^^^^^^^ 21 │ - 22 │ Unknown_Style + 22 │ #special_property i The name could be renamed to `specialProperty`. @@ -210,14 +212,14 @@ invalidClassProperty.js:22:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 20 │ #special_property + 20 │ special_property 21 │ - > 22 │ Unknown_Style - │ ^^^^^^^^^^^^^ + > 22 │ #special_property + │ ^^^^^^^^^^^^^^^^^ 23 │ - 24 │ #Unknown_Style + 24 │ Unknown_Style - i The name could be renamed to `unknownStyle`. + i The name could be renamed to `specialProperty`. ``` @@ -227,12 +229,12 @@ invalidClassProperty.js:24:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 22 │ Unknown_Style + 22 │ #special_property 23 │ - > 24 │ #Unknown_Style - │ ^^^^^^^^^^^^^^ + > 24 │ Unknown_Style + │ ^^^^^^^^^^^^^ 25 │ - 26 │ Unknown_Init_Style = 0 + 26 │ #Unknown_Style i The name could be renamed to `unknownStyle`. @@ -244,14 +246,14 @@ invalidClassProperty.js:26:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 24 │ #Unknown_Style + 24 │ Unknown_Style 25 │ - > 26 │ Unknown_Init_Style = 0 - │ ^^^^^^^^^^^^^^^^^^ + > 26 │ #Unknown_Style + │ ^^^^^^^^^^^^^^ 27 │ - 28 │ #Unknown_Init_Style = 0 + 28 │ Unknown_Init_Style = 0 - i The name could be renamed to `unknownInitStyle`. + i The name could be renamed to `unknownStyle`. ``` @@ -261,11 +263,28 @@ invalidClassProperty.js:28:5 lint/nursery/useNamingConvention ━━━━━━ ! This class property name should be in camelCase. - 26 │ Unknown_Init_Style = 0 + 26 │ #Unknown_Style 27 │ - > 28 │ #Unknown_Init_Style = 0 + > 28 │ Unknown_Init_Style = 0 + │ ^^^^^^^^^^^^^^^^^^ + 29 │ + 30 │ #Unknown_Init_Style = 0 + + i The name could be renamed to `unknownInitStyle`. + + +``` + +``` +invalidClassProperty.js:30:5 lint/nursery/useNamingConvention ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! This class property name should be in camelCase. + + 28 │ Unknown_Init_Style = 0 + 29 │ + > 30 │ #Unknown_Init_Style = 0 │ ^^^^^^^^^^^^^^^^^^^ - 29 │ } + 31 │ } i The name could be renamed to `unknownInitStyle`. diff --git a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js index 09a81094bd7..2f4dab40d66 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js +++ b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js @@ -1,6 +1,8 @@ export default class { p + "q" = 0 + #p initialized = 0 diff --git a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js.snap index 175654b29d4..b42f2c1ff29 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/useNamingConvention/validClassProperty.js.snap @@ -7,6 +7,8 @@ expression: validClassProperty.js export default class { p + "q" = 0 + #p initialized = 0 diff --git a/crates/rome_js_unicode_table/src/lib.rs b/crates/rome_js_unicode_table/src/lib.rs index 15757e6db92..a2d66bddca3 100644 --- a/crates/rome_js_unicode_table/src/lib.rs +++ b/crates/rome_js_unicode_table/src/lib.rs @@ -18,6 +18,30 @@ pub fn is_id_continue(c: char) -> bool { c == '$' || c == '\u{200d}' || c == '\u{200c}' || ID_Continue(c) } +/// Check if `s` is a valid _JavaScript_ identifier. +/// Currently, it doesn't check escaped unicode chars. +/// +/// ``` +/// use rome_js_unicode_table::is_js_ident; +/// +/// assert!(is_js_ident("id0")); +/// assert!(is_js_ident("$id$")); +/// assert!(is_js_ident("_id_")); +/// +/// assert!(!is_js_ident("@")); +/// assert!(!is_js_ident("custom-id")); +/// assert!(!is_js_ident("0")); +/// ``` +pub fn is_js_ident(s: &str) -> bool { + s.chars().enumerate().all(|(index, c)| { + if index == 0 { + is_id_start(c) + } else { + is_id_continue(c) + } + }) +} + /// Looks up a byte in the lookup table. #[inline] pub fn lookup_byte(byte: u8) -> Dispatch {