mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 19:51:11 +08:00
deps/vm: vendor regress 0.11.1 补 Script/Script_Extensions 的 Unknown(Zzzz) 取值——上游表缺未分配码点集取值,规范合法模式 \p{Script=Unknown} 编译期 SyntaxError;fork 纯增量(0 行改动上游行,仅补区间表与解析臂),回归钉四则(未分配匹配/已分配不匹配/sc·scx·Zzzz 别名/既有取值不扰动)
This commit is contained in:
Vendored
+113
@@ -0,0 +1,113 @@
|
||||
use crate::cursor::Direction;
|
||||
use crate::indexing::{ElementType, InputIndexer};
|
||||
use crate::types::BracketContents;
|
||||
use crate::unicodetables::nonascii_folds_to_ascii_word_char;
|
||||
use crate::{cursor, unicode};
|
||||
|
||||
pub trait CharProperties {
|
||||
type Element: ElementType;
|
||||
|
||||
/// Case-fold an element.
|
||||
fn fold(c: Self::Element, unicode: bool) -> Self::Element;
|
||||
|
||||
/// \return whether this is a word char.
|
||||
/// ES9 21.2.2.6.2.
|
||||
fn is_word_char(c: Self::Element) -> bool {
|
||||
let c = c.as_u32();
|
||||
'a' as u32 <= c && c <= 'z' as u32
|
||||
|| 'A' as u32 <= c && c <= 'Z' as u32
|
||||
|| '0' as u32 <= c && c <= '9' as u32
|
||||
|| c == '_' as u32
|
||||
}
|
||||
|
||||
/// \return whether this is a word char in Unicode case-insensitive mode.
|
||||
/// This includes ASCII word chars and any character that folds to an ASCII word char.
|
||||
fn is_word_char_unicode_icase(c: Self::Element) -> bool {
|
||||
Self::is_word_char(c) || nonascii_folds_to_ascii_word_char(c.as_u32())
|
||||
}
|
||||
|
||||
/// ES9 11.3
|
||||
fn is_line_terminator(c: Self::Element) -> bool {
|
||||
matches!(c.as_u32(), 0x000A | 0x000D | 0x2028 | 0x2029)
|
||||
}
|
||||
|
||||
/// \return whether the bracket \p bc matches the given character \p c,
|
||||
/// respecting case. Respects 'invert'.
|
||||
#[inline(always)]
|
||||
fn bracket(bc: &BracketContents, cp: Self::Element) -> bool {
|
||||
let cp = cp.into();
|
||||
if bc.cps.contains(cp) {
|
||||
return !bc.invert;
|
||||
}
|
||||
bc.invert
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UTF8CharProperties {}
|
||||
|
||||
impl CharProperties for UTF8CharProperties {
|
||||
type Element = char;
|
||||
|
||||
fn fold(c: Self::Element, unicode: bool) -> Self::Element {
|
||||
char::from_u32(unicode::fold_code_point(c.into(), unicode)).unwrap_or(c)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ASCIICharProperties {}
|
||||
impl CharProperties for ASCIICharProperties {
|
||||
type Element = u8;
|
||||
|
||||
fn fold(c: Self::Element, unicode: bool) -> Self::Element {
|
||||
if unicode {
|
||||
c.to_ascii_lowercase()
|
||||
} else {
|
||||
c.to_ascii_uppercase()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "utf16")]
|
||||
pub struct Utf16CharProperties {}
|
||||
|
||||
#[cfg(feature = "utf16")]
|
||||
impl CharProperties for Utf16CharProperties {
|
||||
type Element = u32;
|
||||
|
||||
fn fold(c: Self::Element, unicode: bool) -> Self::Element {
|
||||
unicode::fold_code_point(c, unicode)
|
||||
}
|
||||
}
|
||||
|
||||
/// Check whether the \p orig_range within \p cursor matches position \p pos.
|
||||
pub fn backref<Input: InputIndexer, Dir: Direction>(
|
||||
input: &Input,
|
||||
dir: Dir,
|
||||
orig_range: core::ops::Range<Input::Position>,
|
||||
pos: &mut Input::Position,
|
||||
) -> bool {
|
||||
input.subrange_eq(dir, pos, orig_range)
|
||||
}
|
||||
|
||||
pub fn backref_icase<Input: InputIndexer, Dir: Direction>(
|
||||
input: &Input,
|
||||
dir: Dir,
|
||||
orig_range: core::ops::Range<Input::Position>,
|
||||
pos: &mut Input::Position,
|
||||
) -> bool {
|
||||
let ref_input = input.subinput(orig_range);
|
||||
let mut ref_pos = if Dir::FORWARD {
|
||||
ref_input.left_end()
|
||||
} else {
|
||||
ref_input.right_end()
|
||||
};
|
||||
while let Some(c1) = cursor::next(&ref_input, dir, &mut ref_pos) {
|
||||
let mut matched = false;
|
||||
if let Some(c2) = cursor::next(input, dir, pos) {
|
||||
matched = input.fold_equals(c1, c2)
|
||||
}
|
||||
if !matched {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
Reference in New Issue
Block a user