swc_ecma_lexer/common/parser/
output_type.rs

1use swc_common::Span;
2use swc_ecma_ast::{
3    Class, ClassDecl, ClassExpr, Decl, DefaultDecl, ExportDefaultDecl, Expr, FnDecl, FnExpr,
4    Function, Ident,
5};
6
7use crate::error::SyntaxError;
8
9pub trait OutputType: Sized {
10    const IS_IDENT_REQUIRED: bool;
11
12    /// From babel..
13    ///
14    /// When parsing function expression, the binding identifier is parsed
15    /// according to the rules inside the function.
16    /// e.g. (function* yield() {}) is invalid because "yield" is disallowed in
17    /// generators.
18    /// This isn't the case with function declarations: function* yield() {} is
19    /// valid because yield is parsed as if it was outside the generator.
20    /// Therefore, this.state.inGenerator is set before or after parsing the
21    /// function id according to the "isStatement" parameter.
22    fn is_fn_expr() -> bool {
23        false
24    }
25
26    fn finish_fn(span: Span, ident: Option<Ident>, f: Box<Function>) -> Result<Self, SyntaxError>;
27
28    fn finish_class(
29        span: Span,
30        ident: Option<Ident>,
31        class: Box<Class>,
32    ) -> Result<Self, SyntaxError>;
33}
34
35impl OutputType for Box<Expr> {
36    const IS_IDENT_REQUIRED: bool = false;
37
38    fn is_fn_expr() -> bool {
39        true
40    }
41
42    fn finish_fn(
43        _span: Span,
44        ident: Option<Ident>,
45        function: Box<Function>,
46    ) -> Result<Self, SyntaxError> {
47        Ok(FnExpr { ident, function }.into())
48    }
49
50    fn finish_class(
51        _span: Span,
52        ident: Option<Ident>,
53        class: Box<Class>,
54    ) -> Result<Self, SyntaxError> {
55        Ok(ClassExpr { ident, class }.into())
56    }
57}
58
59impl OutputType for ExportDefaultDecl {
60    const IS_IDENT_REQUIRED: bool = false;
61
62    fn finish_fn(
63        span: Span,
64        ident: Option<Ident>,
65        function: Box<Function>,
66    ) -> Result<Self, SyntaxError> {
67        Ok(ExportDefaultDecl {
68            span,
69            decl: DefaultDecl::Fn(FnExpr { ident, function }),
70        })
71    }
72
73    fn finish_class(
74        span: Span,
75        ident: Option<Ident>,
76        class: Box<Class>,
77    ) -> Result<Self, SyntaxError> {
78        Ok(ExportDefaultDecl {
79            span,
80            decl: DefaultDecl::Class(ClassExpr { ident, class }),
81        })
82    }
83}
84
85impl OutputType for Decl {
86    const IS_IDENT_REQUIRED: bool = true;
87
88    fn finish_fn(
89        _span: Span,
90        ident: Option<Ident>,
91        function: Box<Function>,
92    ) -> Result<Self, SyntaxError> {
93        let ident = ident.ok_or(SyntaxError::ExpectedIdent)?;
94
95        Ok(FnDecl {
96            declare: false,
97            ident,
98            function,
99        }
100        .into())
101    }
102
103    fn finish_class(_: Span, ident: Option<Ident>, class: Box<Class>) -> Result<Self, SyntaxError> {
104        let ident = ident.ok_or(SyntaxError::ExpectedIdent)?;
105
106        Ok(ClassDecl {
107            declare: false,
108            ident,
109            class,
110        }
111        .into())
112    }
113}