This repository has been archived by the owner on Aug 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 659
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rome_js_analyzer): rule
useValidLang
- Loading branch information
Showing
18 changed files
with
584 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use rome_aria_metadata::{IsoCountries, IsoLanguages, ISO_COUNTRIES, ISO_LANGUAGES}; | ||
use std::str::FromStr; | ||
|
||
/// Returns a list of valid ISO countries | ||
pub fn is_valid_country(country: &str) -> bool { | ||
IsoCountries::from_str(country).is_ok() | ||
} | ||
|
||
/// Returns a list of valid ISO languages | ||
pub fn is_valid_language(language: &str) -> bool { | ||
IsoLanguages::from_str(language).is_ok() | ||
} | ||
|
||
/// An array of all available countries | ||
pub fn countries() -> &'static [&'static str] { | ||
&ISO_COUNTRIES | ||
} | ||
|
||
/// An array of all available languages | ||
pub fn languages() -> &'static [&'static str] { | ||
&ISO_LANGUAGES | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,32 @@ | ||
include!(concat!(env!("OUT_DIR"), "/enums.rs")); | ||
include!(concat!(env!("OUT_DIR"), "/roles_and_properties.rs")); | ||
|
||
pub const ISO_COUNTRIES: [&str; 233] = [ | ||
"AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", | ||
"BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BA", "BW", "BR", "IO", "VG", "BN", | ||
"BG", "BF", "MM", "BI", "KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", | ||
"KM", "CK", "CR", "HR", "CU", "CY", "CZ", "CD", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", | ||
"ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "PF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", | ||
"GL", "GD", "GU", "GT", "GN", "GW", "GY", "HT", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", | ||
"IQ", "IE", "IM", "IL", "IT", "CI", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KW", "KG", "LA", | ||
"LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT", | ||
"MH", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "NA", "NR", "NP", | ||
"NL", "AN", "NC", "NZ", "NI", "NE", "NG", "NU", "KP", "MP", "NO", "OM", "PK", "PW", "PA", "PG", | ||
"PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "CG", "RO", "RU", "RW", "BL", "SH", "KN", "LC", | ||
"MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG", "SK", "SI", "SB", "SO", | ||
"ZA", "KR", "ES", "LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", | ||
"TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US", "UY", "VI", | ||
"UZ", "VU", "VE", "VN", "WF", "EH", "YE", "ZM", "ZW", | ||
]; | ||
|
||
pub const ISO_LANGUAGES: [&str; 150] = [ | ||
"ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", | ||
"bi", "br", "bg", "my", "be", "km", "ca", "zh", "zh-Hans", "zh-Hant", "co", "hr", "cs", "da", | ||
"nl", "en", "eo", "et", "fo", "fa", "fj", "fi", "fr", "fy", "gl", "gd", "gv", "ka", "de", "el", | ||
"kl", "gn", "gu", "ht", "ha", "he", "iw", "hi", "hu", "is", "io", "id", "in", "ia", "ie", "iu", | ||
"ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", "lv", | ||
"li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "oc", | ||
"or", "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sm", "sg", "sa", "sr", "sh", "st", | ||
"tn", "sn", "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", | ||
"tt", "te", "th", "bo", "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", | ||
"wa", "cy", "wo", "xh", "yi", "ji", "yo", "zu", | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
crates/rome_js_analyze/src/aria_analyzers/nursery/use_valid_lang.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
use crate::aria_services::Aria; | ||
use rome_analyze::context::RuleContext; | ||
use rome_analyze::{declare_rule, Rule, RuleDiagnostic}; | ||
use rome_console::markup; | ||
use rome_js_syntax::jsx_ext::AnyJsxElement; | ||
use rome_rowan::{AstNode, TextRange}; | ||
declare_rule! { | ||
/// Ensure that the attribute passed to the `lang` attribute is a correct ISO language and/or country. | ||
/// | ||
/// ## Examples | ||
/// | ||
/// ### Invalid | ||
/// | ||
/// ```jsx,expect_diagnostic | ||
/// <html lang="lorem" /> | ||
/// ``` | ||
/// | ||
/// ```jsx,expect_diagnostic | ||
/// <html lang="en-babab" /> | ||
/// ``` | ||
/// | ||
/// ### Valid | ||
/// | ||
/// ```jsx | ||
/// <Html lang="en-babab" /> | ||
/// ``` | ||
pub(crate) UseValidLang { | ||
version: "12.0.0", | ||
name: "useValidLang", | ||
recommended: true, | ||
} | ||
} | ||
|
||
enum ErrorKind { | ||
InvalidLanguage, | ||
InvalidCountry, | ||
InvalidValue, | ||
} | ||
|
||
pub(crate) struct UseValidLangState { | ||
error_kind: ErrorKind, | ||
attribute_range: TextRange, | ||
} | ||
|
||
impl Rule for UseValidLang { | ||
type Query = Aria<AnyJsxElement>; | ||
type State = UseValidLangState; | ||
type Signals = Option<Self::State>; | ||
type Options = (); | ||
|
||
fn run(ctx: &RuleContext<Self>) -> Self::Signals { | ||
let node = ctx.query(); | ||
let element_text = node.name().ok()?.as_jsx_name()?.value_token().ok()?; | ||
if element_text.text_trimmed() == "html" { | ||
let attribute = node.find_attribute_by_name("lang")?; | ||
let attribute_value = attribute.initializer()?.value().ok()?; | ||
let attribute_text = attribute_value.inner_text_value().ok()??; | ||
let mut split_value = attribute_text.text().split('-'); | ||
match (split_value.next(), split_value.next()) { | ||
(Some(language), Some(country)) => { | ||
if !ctx.is_valid_language(language) { | ||
return Some(UseValidLangState { | ||
attribute_range: attribute_value.range(), | ||
error_kind: ErrorKind::InvalidLanguage, | ||
}); | ||
} else if !ctx.is_valid_country(country) { | ||
return Some(UseValidLangState { | ||
attribute_range: attribute_value.range(), | ||
error_kind: ErrorKind::InvalidCountry, | ||
}); | ||
} | ||
} | ||
|
||
(Some(language), None) => { | ||
if !ctx.is_valid_language(language) { | ||
return Some(UseValidLangState { | ||
attribute_range: attribute_value.range(), | ||
error_kind: ErrorKind::InvalidLanguage, | ||
}); | ||
} | ||
} | ||
_ => { | ||
if split_value.next().is_some() { | ||
return Some(UseValidLangState { | ||
attribute_range: attribute_value.range(), | ||
error_kind: ErrorKind::InvalidValue, | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
|
||
None | ||
} | ||
|
||
fn diagnostic(ctx: &RuleContext<Self>, state: &Self::State) -> Option<RuleDiagnostic> { | ||
let mut diagnostic = RuleDiagnostic::new( | ||
rule_category!(), | ||
state.attribute_range, | ||
markup! { | ||
"Provide a valid value for the "<Emphasis>"lang"</Emphasis>" attribute." | ||
}, | ||
); | ||
diagnostic = match state.error_kind { | ||
ErrorKind::InvalidLanguage => { | ||
let languages = ctx.iso_language_list(); | ||
let languages = if languages.len() > 15 { | ||
&languages[..15] | ||
} else { | ||
languages | ||
}; | ||
|
||
diagnostic.footer_list("Some of valid languages:", languages) | ||
} | ||
ErrorKind::InvalidCountry => { | ||
let countries = ctx.iso_country_list(); | ||
let countries = if countries.len() > 15 { | ||
&countries[..15] | ||
} else { | ||
countries | ||
}; | ||
|
||
diagnostic.footer_list("Some of valid countries:", countries) | ||
} | ||
ErrorKind::InvalidValue => diagnostic, | ||
};y | ||
Some(diagnostic) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// invalid | ||
let a = <html lang="lorem" />; | ||
let a = <html lang="en-babab" />; | ||
|
||
// valid | ||
let a = <Html lang="en-babab" />; | ||
let a = <html lang="en-US"></html>; | ||
let a = <html lang="en"></html>; | ||
let a = <html lang={lang}></html>; |
Oops, something went wrong.