refactor(ast): split syntax_directed_operations into separate files

This commit is contained in:
Boshen 2023-10-19 14:58:31 +08:00
parent 1aa95fa6d6
commit 94792e9153
No known key found for this signature in database
GPG key ID: 234DA6A7079C6801
9 changed files with 146 additions and 136 deletions

View file

@ -1,3 +1,5 @@
#![allow(clippy::wildcard_imports)]
//! # Oxc AST
//!
//! This is almost similar to [estree](https://github.com/estree/estree) except a few places:

View file

@ -1,6 +1,5 @@
use oxc_span::{GetSpan, Span};
#[allow(clippy::wildcard_imports)]
use crate::ast::*;
impl<'a> GetSpan for Statement<'a> {

View file

@ -1,8 +1,3 @@
//! [ECMA262 Syntax-Directed Operations](https://tc39.es/ecma262/#sec-syntax-directed-operations)
use oxc_span::Span;
#[allow(clippy::wildcard_imports)]
use crate::ast::*;
/// [`BoundName`](https://tc39.es/ecma262/#sec-static-semantics-boundnames)
@ -162,131 +157,3 @@ impl<'a> BoundNames for ExportNamedDeclaration<'a> {
}
}
}
/// [`IsSimpleParameterList`](https://tc39.es/ecma262/#sec-static-semantics-issimpleparameterlist)
pub trait IsSimpleParameterList {
fn is_simple_parameter_list(&self) -> bool;
}
impl<'a> IsSimpleParameterList for FormalParameters<'a> {
fn is_simple_parameter_list(&self) -> bool {
self.items.iter().all(|pat| pat.pattern.kind.is_binding_identifier()) && self.rest.is_none()
}
}
/// [`PropName`](https://tc39.es/ecma262/#sec-static-semantics-propname)
pub trait PropName {
fn prop_name(&self) -> Option<(&str, Span)>;
}
impl<'a> PropName for ObjectPropertyKind<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
ObjectPropertyKind::ObjectProperty(prop) => prop.prop_name(),
ObjectPropertyKind::SpreadProperty(_) => None,
}
}
}
impl<'a> PropName for ObjectProperty<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.kind != PropertyKind::Init || self.method || self.shorthand || self.computed {
return None;
}
self.key.prop_name()
}
}
impl<'a> PropName for PropertyKey<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
PropertyKey::Identifier(ident) => Some((&ident.name, ident.span)),
PropertyKey::PrivateIdentifier(_) => None,
PropertyKey::Expression(expr) => match &expr {
Expression::Identifier(ident) => Some((&ident.name, ident.span)),
Expression::StringLiteral(lit) => Some((&lit.value, lit.span)),
_ => None,
},
}
}
}
impl<'a> PropName for ClassElement<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
ClassElement::MethodDefinition(def) => def.prop_name(),
ClassElement::TSAbstractMethodDefinition(def) => def.method_definition.prop_name(),
ClassElement::PropertyDefinition(def) => def.prop_name(),
ClassElement::TSAbstractPropertyDefinition(def) => def.property_definition.prop_name(),
_ => None,
}
}
}
impl<'a> PropName for MethodDefinition<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.computed {
return None;
}
self.key.prop_name()
}
}
impl<'a> PropName for PropertyDefinition<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.computed {
return None;
}
self.key.prop_name()
}
}
/// [`PrivateBoundIdentifiers`](https://tc39.es/ecma262/#sec-static-semantics-privateboundidentifiers)
pub trait PrivateBoundIdentifiers {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier>;
}
impl<'a> PrivateBoundIdentifiers for ClassElement<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
match self {
ClassElement::StaticBlock(_) | ClassElement::TSIndexSignature(_) => None,
ClassElement::MethodDefinition(def) => def.private_bound_identifiers(),
ClassElement::PropertyDefinition(def) => def.private_bound_identifiers(),
ClassElement::AccessorProperty(def) => def.private_bound_identifiers(),
ClassElement::TSAbstractMethodDefinition(def) => {
def.method_definition.private_bound_identifiers()
}
ClassElement::TSAbstractPropertyDefinition(def) => {
def.property_definition.private_bound_identifiers()
}
}
}
}
impl<'a> PrivateBoundIdentifiers for MethodDefinition<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
self.value.body.as_ref()?;
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}
impl<'a> PrivateBoundIdentifiers for PropertyDefinition<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}
impl<'a> PrivateBoundIdentifiers for AccessorProperty<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}

View file

@ -0,0 +1,12 @@
use crate::ast::*;
/// [`IsSimpleParameterList`](https://tc39.es/ecma262/#sec-static-semantics-issimpleparameterlist)
pub trait IsSimpleParameterList {
fn is_simple_parameter_list(&self) -> bool;
}
impl<'a> IsSimpleParameterList for FormalParameters<'a> {
fn is_simple_parameter_list(&self) -> bool {
self.items.iter().all(|pat| pat.pattern.kind.is_binding_identifier()) && self.rest.is_none()
}
}

View file

@ -0,0 +1,11 @@
//! [ECMA262 Syntax-Directed Operations](https://tc39.es/ecma262/#sec-syntax-directed-operations)
mod bound_names;
mod is_simple_parameter_list;
mod private_bound_identifiers;
mod prop_name;
pub use self::{
bound_names::BoundNames, is_simple_parameter_list::IsSimpleParameterList,
private_bound_identifiers::PrivateBoundIdentifiers, prop_name::PropName,
};

View file

@ -0,0 +1,51 @@
use crate::ast::*;
/// [`PrivateBoundIdentifiers`](https://tc39.es/ecma262/#sec-static-semantics-privateboundidentifiers)
pub trait PrivateBoundIdentifiers {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier>;
}
impl<'a> PrivateBoundIdentifiers for ClassElement<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
match self {
ClassElement::StaticBlock(_) | ClassElement::TSIndexSignature(_) => None,
ClassElement::MethodDefinition(def) => def.private_bound_identifiers(),
ClassElement::PropertyDefinition(def) => def.private_bound_identifiers(),
ClassElement::AccessorProperty(def) => def.private_bound_identifiers(),
ClassElement::TSAbstractMethodDefinition(def) => {
def.method_definition.private_bound_identifiers()
}
ClassElement::TSAbstractPropertyDefinition(def) => {
def.property_definition.private_bound_identifiers()
}
}
}
}
impl<'a> PrivateBoundIdentifiers for MethodDefinition<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
self.value.body.as_ref()?;
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}
impl<'a> PrivateBoundIdentifiers for PropertyDefinition<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}
impl<'a> PrivateBoundIdentifiers for AccessorProperty<'a> {
fn private_bound_identifiers(&self) -> Option<PrivateIdentifier> {
if let PropertyKey::PrivateIdentifier(ident) = &self.key {
return Some((*ident).clone());
}
None
}
}

View file

@ -0,0 +1,70 @@
use oxc_span::Span;
use crate::ast::*;
/// [`PropName`](https://tc39.es/ecma262/#sec-static-semantics-propname)
pub trait PropName {
fn prop_name(&self) -> Option<(&str, Span)>;
}
impl<'a> PropName for ObjectPropertyKind<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
ObjectPropertyKind::ObjectProperty(prop) => prop.prop_name(),
ObjectPropertyKind::SpreadProperty(_) => None,
}
}
}
impl<'a> PropName for ObjectProperty<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.kind != PropertyKind::Init || self.method || self.shorthand || self.computed {
return None;
}
self.key.prop_name()
}
}
impl<'a> PropName for PropertyKey<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
PropertyKey::Identifier(ident) => Some((&ident.name, ident.span)),
PropertyKey::PrivateIdentifier(_) => None,
PropertyKey::Expression(expr) => match &expr {
Expression::Identifier(ident) => Some((&ident.name, ident.span)),
Expression::StringLiteral(lit) => Some((&lit.value, lit.span)),
_ => None,
},
}
}
}
impl<'a> PropName for ClassElement<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
match self {
ClassElement::MethodDefinition(def) => def.prop_name(),
ClassElement::TSAbstractMethodDefinition(def) => def.method_definition.prop_name(),
ClassElement::PropertyDefinition(def) => def.prop_name(),
ClassElement::TSAbstractPropertyDefinition(def) => def.property_definition.prop_name(),
_ => None,
}
}
}
impl<'a> PropName for MethodDefinition<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.computed {
return None;
}
self.key.prop_name()
}
}
impl<'a> PropName for PropertyDefinition<'a> {
fn prop_name(&self) -> Option<(&str, Span)> {
if self.computed {
return None;
}
self.key.prop_name()
}
}

View file

@ -8,7 +8,6 @@ use oxc_allocator::Vec;
use oxc_span::Span;
use oxc_syntax::scope::ScopeFlags;
#[allow(clippy::wildcard_imports)]
use crate::{ast::*, ast_kind::AstKind};
/// Syntax tree traversal

View file

@ -3,7 +3,6 @@
use oxc_allocator::Vec;
use oxc_span::Span;
#[allow(clippy::wildcard_imports)]
use crate::ast::*;
/// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in place.