11#![ expect( missing_docs) ] // FIXME
2- use oxc_span:: Atom ;
2+ use oxc_span:: { Atom , GetSpan } ;
33
44use super :: { AstKind , ast:: * } ;
55
@@ -81,6 +81,28 @@ impl<'a> AstKind<'a> {
8181 }
8282 }
8383
84+ /// Returns whether this expression is a member expression, such as `obj.prop`, `obj["prop"]`, or `obj.#prop`.
85+ pub fn is_member_expression_kind ( & self ) -> bool {
86+ self . as_member_expression_kind ( ) . is_some ( )
87+ }
88+
89+ /// If this is some kind of member expression, returns it as a
90+ /// [`MemberExpressionKind`]. Otherwise, returns `None`.
91+ pub fn as_member_expression_kind ( & self ) -> Option < MemberExpressionKind < ' a > > {
92+ match self {
93+ Self :: ComputedMemberExpression ( member_expr) => {
94+ Some ( MemberExpressionKind :: Computed ( member_expr) )
95+ }
96+ Self :: StaticMemberExpression ( member_expr) => {
97+ Some ( MemberExpressionKind :: Static ( member_expr) )
98+ }
99+ Self :: PrivateFieldExpression ( member_expr) => {
100+ Some ( MemberExpressionKind :: PrivateField ( member_expr) )
101+ }
102+ _ => None ,
103+ }
104+ }
105+
84106 pub fn from_expression ( e : & ' a Expression < ' a > ) -> Self {
85107 match e {
86108 Expression :: BooleanLiteral ( e) => Self :: BooleanLiteral ( e) ,
@@ -101,16 +123,16 @@ impl<'a> AstKind<'a> {
101123 Expression :: CallExpression ( e) => Self :: CallExpression ( e) ,
102124 Expression :: ChainExpression ( e) => Self :: ChainExpression ( e) ,
103125 Expression :: ClassExpression ( e) => Self :: Class ( e) ,
126+ Expression :: ComputedMemberExpression ( e) => Self :: ComputedMemberExpression ( e) ,
104127 Expression :: ConditionalExpression ( e) => Self :: ConditionalExpression ( e) ,
105128 Expression :: FunctionExpression ( e) => Self :: Function ( e) ,
106129 Expression :: ImportExpression ( e) => Self :: ImportExpression ( e) ,
107130 Expression :: LogicalExpression ( e) => Self :: LogicalExpression ( e) ,
108- match_member_expression ! ( Expression ) => {
109- Self :: MemberExpression ( e. to_member_expression ( ) )
110- }
111131 Expression :: NewExpression ( e) => Self :: NewExpression ( e) ,
112132 Expression :: ObjectExpression ( e) => Self :: ObjectExpression ( e) ,
113133 Expression :: ParenthesizedExpression ( e) => Self :: ParenthesizedExpression ( e) ,
134+ Expression :: PrivateFieldExpression ( e) => Self :: PrivateFieldExpression ( e) ,
135+ Expression :: StaticMemberExpression ( e) => Self :: StaticMemberExpression ( e) ,
114136 Expression :: SequenceExpression ( e) => Self :: SequenceExpression ( e) ,
115137 Expression :: TaggedTemplateExpression ( e) => Self :: TaggedTemplateExpression ( e) ,
116138 Expression :: ThisExpression ( e) => Self :: ThisExpression ( e) ,
@@ -220,7 +242,6 @@ impl AstKind<'_> {
220242 Self :: ComputedMemberExpression ( _) => "ComputedMemberExpression" . into ( ) ,
221243 Self :: ConditionalExpression ( _) => "ConditionalExpression" . into ( ) ,
222244 Self :: LogicalExpression ( _) => "LogicalExpression" . into ( ) ,
223- Self :: MemberExpression ( _) => "MemberExpression" . into ( ) ,
224245 Self :: NewExpression ( n) => {
225246 let callee = match & n. callee {
226247 Expression :: Identifier ( id) => Some ( id. name . as_str ( ) ) ,
@@ -233,6 +254,8 @@ impl AstKind<'_> {
233254 }
234255 Self :: ObjectExpression ( _) => "ObjectExpression" . into ( ) ,
235256 Self :: ParenthesizedExpression ( _) => "ParenthesizedExpression" . into ( ) ,
257+ Self :: PrivateFieldExpression ( _) => "PrivateFieldExpression" . into ( ) ,
258+ Self :: StaticMemberExpression ( _) => "StaticMemberExpression" . into ( ) ,
236259 Self :: SequenceExpression ( _) => "SequenceExpression" . into ( ) ,
237260 Self :: TaggedTemplateExpression ( _) => "TaggedTemplateExpression" . into ( ) ,
238261 Self :: ThisExpression ( _) => "ThisExpression" . into ( ) ,
@@ -388,3 +411,64 @@ impl AstKind<'_> {
388411 }
389412 }
390413}
414+
415+ /// This is a subset of [`AstKind`] that represents member expressions.
416+ ///
417+ /// Having a separate enum for this allows us to implement helpful methods that are specific to member expressions,
418+ /// such as getting the property name or the object of the member expression.
419+ pub enum MemberExpressionKind < ' a > {
420+ /// A static member expression, such as `obj.prop`.
421+ Static ( & ' a StaticMemberExpression < ' a > ) ,
422+ /// A computed member expression, such as `obj["prop"]`.
423+ Computed ( & ' a ComputedMemberExpression < ' a > ) ,
424+ /// A private field expression, such as `obj.#field`.
425+ PrivateField ( & ' a PrivateFieldExpression < ' a > ) ,
426+ }
427+
428+ impl < ' a > MemberExpressionKind < ' a > {
429+ /// Returns the property name of the member expression, otherwise `None`.
430+ ///
431+ /// Example: returns the `prop` in `obj.prop` or `obj["prop"]`.
432+ pub fn static_property_name ( & self ) -> Option < Atom < ' a > > {
433+ match self {
434+ Self :: Computed ( member_expr) => member_expr. static_property_name ( ) ,
435+ Self :: Static ( member_expr) => Some ( member_expr. property . name ) ,
436+ Self :: PrivateField ( _) => None ,
437+ }
438+ }
439+
440+ /// Returns the object of the member expression, otherwise `None`.
441+ ///
442+ /// Example: returns the `obj` in `obj.prop` or `obj["prop"]`.
443+ pub fn object ( & self ) -> & Expression < ' a > {
444+ match self {
445+ Self :: Computed ( member_expr) => & member_expr. object ,
446+ Self :: Static ( member_expr) => & member_expr. object ,
447+ Self :: PrivateField ( member_expr) => & member_expr. object ,
448+ }
449+ }
450+
451+ /// Returns whether the member expression is optional, i.e. if it uses the
452+ /// optional chaining operator (`?.`).
453+ ///
454+ /// Example:
455+ /// - Returns `true` for `obj?.prop` or `obj?.["prop"]`.
456+ /// - Returns `false` for `obj.prop` or `obj["prop"]`.
457+ pub fn optional ( & self ) -> bool {
458+ match self {
459+ Self :: Computed ( member_expr) => member_expr. optional ,
460+ Self :: Static ( member_expr) => member_expr. optional ,
461+ Self :: PrivateField ( member_expr) => member_expr. optional ,
462+ }
463+ }
464+ }
465+
466+ impl GetSpan for MemberExpressionKind < ' _ > {
467+ fn span ( & self ) -> Span {
468+ match self {
469+ Self :: Computed ( member_expr) => member_expr. span ,
470+ Self :: Static ( member_expr) => member_expr. span ,
471+ Self :: PrivateField ( member_expr) => member_expr. span ,
472+ }
473+ }
474+ }
0 commit comments