-
-
Notifications
You must be signed in to change notification settings - Fork 488
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(transformer/class-properties):
PrivatePropsStack
type
- Loading branch information
1 parent
cafb613
commit 3547117
Showing
4 changed files
with
108 additions
and
60 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
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
95 changes: 95 additions & 0 deletions
95
crates/oxc_transformer/src/es2022/class_properties/private_props.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,95 @@ | ||
use oxc_ast::ast::PrivateIdentifier; | ||
use oxc_data_structures::stack::SparseStack; | ||
use oxc_span::Atom; | ||
use oxc_traverse::BoundIdentifier; | ||
|
||
use super::FxIndexMap; | ||
|
||
/// Stack of private props defined by classes. | ||
/// | ||
/// Pushed to when entering a class (`None` if class has no private props, `Some` if it does). | ||
/// Entries contain a mapping from private prop name to binding for temp var for that property, | ||
/// and details of the class that defines the private prop. | ||
/// | ||
/// This is used as lookup when transforming e.g. `this.#x`. | ||
#[derive(Default)] | ||
pub(super) struct PrivatePropsStack<'a> { | ||
stack: SparseStack<PrivateProps<'a>>, | ||
} | ||
|
||
impl<'a> PrivatePropsStack<'a> { | ||
// Forward methods to underlying `SparseStack` | ||
|
||
#[inline] | ||
pub fn push(&mut self, props: Option<PrivateProps<'a>>) { | ||
self.stack.push(props); | ||
} | ||
|
||
#[inline] | ||
pub fn pop(&mut self) -> Option<PrivateProps<'a>> { | ||
self.stack.pop() | ||
} | ||
|
||
#[inline] | ||
pub fn last(&self) -> Option<&PrivateProps<'a>> { | ||
self.stack.last() | ||
} | ||
|
||
#[inline] | ||
#[expect(dead_code)] | ||
pub fn last_mut(&mut self) -> Option<&mut PrivateProps<'a>> { | ||
self.stack.last_mut() | ||
} | ||
|
||
/// Lookup details of private property referred to by `ident`. | ||
pub fn find<'b>( | ||
&'b self, | ||
ident: &PrivateIdentifier<'a>, | ||
) -> Option<ResolvedPrivateProp<'a, 'b>> { | ||
// Check for binding in closest class first, then enclosing classes | ||
// TODO: Check there are tests for bindings in enclosing classes. | ||
for private_props in self.stack.as_slice().iter().rev() { | ||
if let Some(prop) = private_props.props.get(&ident.name) { | ||
return Some(ResolvedPrivateProp { | ||
prop_binding: &prop.binding, | ||
class_binding: private_props.class_binding.as_ref(), | ||
is_static: prop.is_static, | ||
is_declaration: private_props.is_declaration, | ||
}); | ||
} | ||
} | ||
// TODO: This should be unreachable. Only returning `None` because implementation is incomplete. | ||
None | ||
} | ||
} | ||
|
||
/// Details of private properties for a class. | ||
pub(super) struct PrivateProps<'a> { | ||
/// Private properties for class. Indexed by property name. | ||
// TODO(improve-on-babel): Order that temp vars are created in is not important. Use `FxHashMap` instead. | ||
pub props: FxIndexMap<Atom<'a>, PrivateProp<'a>>, | ||
/// Binding for class, if class has name | ||
pub class_binding: Option<BoundIdentifier<'a>>, | ||
/// `true` for class declaration, `false` for class expression | ||
pub is_declaration: bool, | ||
} | ||
|
||
/// Details of a private property. | ||
pub(super) struct PrivateProp<'a> { | ||
pub binding: BoundIdentifier<'a>, | ||
pub is_static: bool, | ||
} | ||
|
||
/// Details of a private property resolved for a private field. | ||
/// | ||
/// This is the return value of [`PrivatePropsStack::find`]. | ||
pub(super) struct ResolvedPrivateProp<'a, 'b> { | ||
/// Binding for temp var representing the property | ||
pub prop_binding: &'b BoundIdentifier<'a>, | ||
/// Binding for class (if it has one) | ||
pub class_binding: Option<&'b BoundIdentifier<'a>>, | ||
/// `true` if is a static property | ||
pub is_static: bool, | ||
/// `true` if class which defines this property is a class declaration | ||
pub is_declaration: bool, | ||
} |