| 1 | /// Returns whether a character has the Unicode `ID_Start` properly. |
| 2 | /// |
| 3 | /// This is only ever-so-slightly different from `XID_Start` in a few edge |
| 4 | /// cases, so we handle those edge cases manually and delegate everything else |
| 5 | /// to `unicode-ident`. |
| 6 | fn is_id_start(c: char) -> bool { |
| 7 | match c { |
| 8 | ' \u{037A}' | ' \u{0E33}' | ' \u{0EB3}' | ' \u{309B}' | ' \u{309C}' | ' \u{FC5E}' |
| 9 | | ' \u{FC5F}' | ' \u{FC60}' | ' \u{FC61}' | ' \u{FC62}' | ' \u{FC63}' | ' \u{FDFA}' |
| 10 | | ' \u{FDFB}' | ' \u{FE70}' | ' \u{FE72}' | ' \u{FE74}' | ' \u{FE76}' | ' \u{FE78}' |
| 11 | | ' \u{FE7A}' | ' \u{FE7C}' | ' \u{FE7E}' | ' \u{FF9E}' | ' \u{FF9F}' => true, |
| 12 | _ => unicode_ident::is_xid_start(ch:c), |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | /// Returns whether a character has the Unicode `ID_Continue` properly. |
| 17 | /// |
| 18 | /// This is only ever-so-slightly different from `XID_Continue` in a few edge |
| 19 | /// cases, so we handle those edge cases manually and delegate everything else |
| 20 | /// to `unicode-ident`. |
| 21 | fn is_id_continue(c: char) -> bool { |
| 22 | match c { |
| 23 | ' \u{037A}' | ' \u{309B}' | ' \u{309C}' | ' \u{FC5E}' | ' \u{FC5F}' | ' \u{FC60}' |
| 24 | | ' \u{FC61}' | ' \u{FC62}' | ' \u{FC63}' | ' \u{FDFA}' | ' \u{FDFB}' | ' \u{FE70}' |
| 25 | | ' \u{FE72}' | ' \u{FE74}' | ' \u{FE76}' | ' \u{FE78}' | ' \u{FE7A}' | ' \u{FE7C}' |
| 26 | | ' \u{FE7E}' => true, |
| 27 | _ => unicode_ident::is_xid_continue(ch:c), |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | /// Returns whether a string is a valid JavaScript identifier. |
| 32 | /// Defined at https://tc39.es/ecma262/#prod-IdentifierName. |
| 33 | pub fn is_valid_ident(name: &str) -> bool { |
| 34 | !name.is_empty() |
| 35 | && name.chars().enumerate().all(|(i: usize, char: char)| { |
| 36 | if i == 0 { |
| 37 | is_id_start(char) || char == '$' || char == '_' |
| 38 | } else { |
| 39 | is_id_continue(char) || char == '$' || char == ' \u{200C}' || char == ' \u{200D}' |
| 40 | } |
| 41 | }) |
| 42 | } |
| 43 | |