mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 20:28:58 +00:00
refactor(parser): move JSXIdentifier conversion code into parser (#5345)
Outside of the parser, a `JSXIdentifier` in a `JSXElementName::Identifier` will never be a identifier reference. So move the code for deciding if a `JSXElementName` is `JSXElementName::Identifier` or `JSXElementName::IdentifierReference`, and the code for converting from one to the other, into the parser - which is only place it should be used.
This commit is contained in:
parent
292f217da8
commit
d236554512
3 changed files with 19 additions and 32 deletions
|
|
@ -351,12 +351,6 @@ impl<'a> fmt::Display for IdentifierReference<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<JSXIdentifier<'a>> for IdentifierReference<'a> {
|
||||
fn from(value: JSXIdentifier<'a>) -> Self {
|
||||
IdentifierReference { span: value.span, name: value.name, reference_id: Cell::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for BindingIdentifier<'a> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
|
|
|
|||
|
|
@ -19,28 +19,6 @@ impl<'a> fmt::Display for JSXIdentifier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> JSXIdentifier<'a> {
|
||||
/// Determines whether the given current identifier is a reference.
|
||||
///
|
||||
/// References begin with a capital letter, `_` or `$`.
|
||||
/// <https://babeljs.io/repl#?code_lz=DwMQ9mAED0B8DcAoYAzCMHIPpqnJwAJLhkkA&presets=react>
|
||||
// `name.chars().next().unwrap()` cannot panic because name is never an empty string.
|
||||
#[allow(clippy::missing_panics_doc)]
|
||||
pub fn is_reference(&self) -> bool {
|
||||
// The identifier has already been checked to be valid, so when first char is ASCII, it can only
|
||||
// be `a-z`, `A-Z`, `_` or `$`. But compiler doesn't know that, so we can help it create faster
|
||||
// code by taking that invariant into account.
|
||||
// `b < b'a'` matches `A-Z`, `_` and `$`.
|
||||
// Use a fast path for common case of ASCII characters, to avoid the more expensive
|
||||
// `char::is_uppercase` in most cases.
|
||||
let name = self.name.as_str();
|
||||
match name.as_bytes()[0] {
|
||||
b if b.is_ascii() => b < b'a',
|
||||
_ => name.chars().next().unwrap().is_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for JSXNamespacedName<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}:{}", self.namespace.name, self.property.name)
|
||||
|
|
|
|||
|
|
@ -154,8 +154,23 @@ impl<'a> ParserImpl<'a> {
|
|||
.map(JSXElementName::MemberExpression);
|
||||
}
|
||||
|
||||
let element_name = if identifier.is_reference() {
|
||||
JSXElementName::IdentifierReference(self.ast.alloc(identifier.into()))
|
||||
// References begin with a capital letter, `_` or `$` e.g. `<Foo>`, `<_foo>`, `<$foo>`.
|
||||
// https://babeljs.io/repl#?code_lz=DwMQ9mAED0B8DcAoYAzCMHIPpqnJwAJLhkkA&presets=react
|
||||
// The identifier has already been checked to be valid, so when first char is ASCII, it can only
|
||||
// be `a-z`, `A-Z`, `_` or `$`. But compiler doesn't know that, so we can help it create faster
|
||||
// code by taking that invariant into account.
|
||||
// `b < b'a'` matches `A-Z`, `_` and `$`.
|
||||
// Use a fast path for common case of ASCII characters, to avoid the more expensive
|
||||
// `char::is_uppercase` in most cases.
|
||||
let name = identifier.name.as_str();
|
||||
let is_reference = match name.as_bytes()[0] {
|
||||
b if b.is_ascii() => b < b'a',
|
||||
_ => name.chars().next().unwrap().is_uppercase(),
|
||||
};
|
||||
|
||||
let element_name = if is_reference {
|
||||
let identifier = self.ast.identifier_reference(identifier.span, identifier.name);
|
||||
JSXElementName::IdentifierReference(self.ast.alloc(identifier))
|
||||
} else {
|
||||
JSXElementName::Identifier(self.ast.alloc(identifier))
|
||||
};
|
||||
|
|
@ -171,8 +186,8 @@ impl<'a> ParserImpl<'a> {
|
|||
object: JSXIdentifier<'a>,
|
||||
) -> Result<Box<'a, JSXMemberExpression<'a>>> {
|
||||
let mut span = span;
|
||||
let mut object =
|
||||
JSXMemberExpressionObject::IdentifierReference(self.ast.alloc(object.into()));
|
||||
let object = self.ast.identifier_reference(object.span, object.name);
|
||||
let mut object = JSXMemberExpressionObject::IdentifierReference(self.ast.alloc(object));
|
||||
let mut property = None;
|
||||
|
||||
while self.eat(Kind::Dot) && !self.at(Kind::Eof) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue