swc_ecma_ast/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![deny(unreachable_patterns)]
3#![deny(missing_copy_implementations)]
4#![deny(trivial_casts)]
5#![deny(trivial_numeric_casts)]
6#![deny(unreachable_pub)]
7#![deny(clippy::all)]
8#![allow(clippy::enum_variant_names)]
9#![allow(clippy::clone_on_copy)]
10#![recursion_limit = "1024"]
11
12pub use num_bigint::BigInt as BigIntValue;
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15use swc_common::{ast_node, pass::Either, util::take::Take, EqIgnoreSpan, Span};
16
17pub use self::{
18    class::{
19        AutoAccessor, Class, ClassMember, ClassMethod, ClassProp, Constructor, Decorator, Key,
20        MethodKind, PrivateMethod, PrivateProp, StaticBlock,
21    },
22    decl::{ClassDecl, Decl, FnDecl, UsingDecl, VarDecl, VarDeclKind, VarDeclarator},
23    expr::*,
24    function::{Function, Param, ParamOrTsParamProp},
25    ident::{
26        unsafe_id, unsafe_id_from_ident, BindingIdent, EsReserved, Id, Ident, IdentName,
27        PrivateName, UnsafeId,
28    },
29    jsx::{
30        JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXClosingElement, JSXClosingFragment,
31        JSXElement, JSXElementChild, JSXElementName, JSXEmptyExpr, JSXExpr, JSXExprContainer,
32        JSXFragment, JSXMemberExpr, JSXNamespacedName, JSXObject, JSXOpeningElement,
33        JSXOpeningFragment, JSXSpreadChild, JSXText,
34    },
35    list::ListFormat,
36    lit::{BigInt, Bool, Lit, Null, Number, Regex, Str},
37    module::{Module, ModuleItem, Program, Script},
38    module_decl::{
39        DefaultDecl, ExportAll, ExportDecl, ExportDefaultDecl, ExportDefaultExpr,
40        ExportDefaultSpecifier, ExportNamedSpecifier, ExportNamespaceSpecifier, ExportSpecifier,
41        ImportDecl, ImportDefaultSpecifier, ImportNamedSpecifier, ImportPhase, ImportSpecifier,
42        ImportStarAsSpecifier, ModuleDecl, ModuleExportName, NamedExport,
43    },
44    operators::{AssignOp, BinaryOp, UnaryOp, UpdateOp},
45    pat::{
46        ArrayPat, AssignPat, AssignPatProp, KeyValuePatProp, ObjectPat, ObjectPatProp, Pat, RestPat,
47    },
48    prop::{
49        AssignProp, ComputedPropName, GetterProp, KeyValueProp, MethodProp, Prop, PropName,
50        SetterProp,
51    },
52    source_map::{SourceMapperExt, SpanExt},
53    stmt::{
54        BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, DoWhileStmt, EmptyStmt,
55        ExprStmt, ForHead, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt,
56        SwitchCase, SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, WhileStmt, WithStmt,
57    },
58    typescript::{
59        Accessibility, TruePlusMinus, TsArrayType, TsAsExpr, TsCallSignatureDecl,
60        TsConditionalType, TsConstAssertion, TsConstructSignatureDecl, TsConstructorType,
61        TsEntityName, TsEnumDecl, TsEnumMember, TsEnumMemberId, TsExportAssignment,
62        TsExprWithTypeArgs, TsExternalModuleRef, TsFnOrConstructorType, TsFnParam, TsFnType,
63        TsGetterSignature, TsImportCallOptions, TsImportEqualsDecl, TsImportType, TsIndexSignature,
64        TsIndexedAccessType, TsInferType, TsInstantiation, TsInterfaceBody, TsInterfaceDecl,
65        TsIntersectionType, TsKeywordType, TsKeywordTypeKind, TsLit, TsLitType, TsMappedType,
66        TsMethodSignature, TsModuleBlock, TsModuleDecl, TsModuleName, TsModuleRef, TsNamespaceBody,
67        TsNamespaceDecl, TsNamespaceExportDecl, TsNonNullExpr, TsOptionalType, TsParamProp,
68        TsParamPropParam, TsParenthesizedType, TsPropertySignature, TsQualifiedName, TsRestType,
69        TsSatisfiesExpr, TsSetterSignature, TsThisType, TsThisTypeOrIdent, TsTplLitType,
70        TsTupleElement, TsTupleType, TsType, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion,
71        TsTypeElement, TsTypeLit, TsTypeOperator, TsTypeOperatorOp, TsTypeParam, TsTypeParamDecl,
72        TsTypeParamInstantiation, TsTypePredicate, TsTypeQuery, TsTypeQueryExpr, TsTypeRef,
73        TsUnionOrIntersectionType, TsUnionType,
74    },
75};
76
77#[macro_use]
78mod macros;
79mod class;
80mod decl;
81mod expr;
82mod function;
83mod ident;
84mod jsx;
85mod list;
86mod lit;
87mod module;
88mod module_decl;
89mod operators;
90mod pat;
91mod prop;
92mod source_map;
93mod stmt;
94mod typescript;
95
96/// A map from the [Program] to the [Program].
97///
98/// This trait is used to implement transformations. The implementor may decide
99/// to implement [Fold] or [VisitMut] if the transform is fine to start from an
100/// arbitrary node.
101///
102/// Tuple of [Pass] implementations also implements [Pass], but it's limited to
103/// 12 items for fast compile time. If you have more passes, nest it like `(a,
104/// (b, c), (d, e))`
105pub trait Pass {
106    fn process(&mut self, program: &mut Program);
107}
108
109/// Optional pass implementation.
110impl<P> Pass for Option<P>
111where
112    P: Pass,
113{
114    #[inline(always)]
115    fn process(&mut self, program: &mut Program) {
116        if let Some(pass) = self {
117            pass.process(program);
118        }
119    }
120}
121
122impl<P: ?Sized> Pass for Box<P>
123where
124    P: Pass,
125{
126    #[inline(always)]
127    fn process(&mut self, program: &mut Program) {
128        (**self).process(program);
129    }
130}
131
132impl<P: ?Sized> Pass for &'_ mut P
133where
134    P: Pass,
135{
136    #[inline(always)]
137    fn process(&mut self, program: &mut Program) {
138        (**self).process(program);
139    }
140}
141
142impl<L, R> Pass for Either<L, R>
143where
144    L: Pass,
145    R: Pass,
146{
147    #[inline]
148    fn process(&mut self, program: &mut Program) {
149        match self {
150            Either::Left(l) => l.process(program),
151            Either::Right(r) => r.process(program),
152        }
153    }
154}
155
156impl<P> Pass for swc_visit::Optional<P>
157where
158    P: Pass,
159{
160    #[inline]
161    fn process(&mut self, program: &mut Program) {
162        if self.enabled {
163            self.visitor.process(program);
164        }
165    }
166}
167
168impl<P> Pass for swc_visit::Repeat<P>
169where
170    P: Pass + swc_visit::Repeated,
171{
172    #[inline]
173    fn process(&mut self, program: &mut Program) {
174        loop {
175            self.pass.reset();
176            self.pass.process(program);
177
178            if !self.pass.changed() {
179                break;
180            }
181        }
182    }
183}
184
185impl Program {
186    #[inline(always)]
187    pub fn mutate<P>(&mut self, mut pass: P)
188    where
189        P: Pass,
190    {
191        pass.process(self);
192    }
193
194    #[inline(always)]
195    pub fn apply<P>(mut self, mut pass: P) -> Self
196    where
197        P: Pass,
198    {
199        pass.process(&mut self);
200        self
201    }
202}
203
204macro_rules! impl_pass_for_tuple {
205    (
206        [$idx:tt, $name:ident], $([$idx_rest:tt, $name_rest:ident]),*
207    ) => {
208        impl<$name, $($name_rest),*> Pass for ($name, $($name_rest),*)
209        where
210            $name: Pass,
211            $($name_rest: Pass),*
212        {
213            #[inline]
214            fn process(&mut self, program: &mut Program) {
215                self.$idx.process(program);
216
217                $(
218                    self.$idx_rest.process(program);
219                )*
220
221            }
222        }
223    };
224}
225
226impl_pass_for_tuple!([0, A], [1, B]);
227impl_pass_for_tuple!([0, A], [1, B], [2, C]);
228impl_pass_for_tuple!([0, A], [1, B], [2, C], [3, D]);
229impl_pass_for_tuple!([0, A], [1, B], [2, C], [3, D], [4, E]);
230impl_pass_for_tuple!([0, A], [1, B], [2, C], [3, D], [4, E], [5, F]);
231impl_pass_for_tuple!([0, A], [1, B], [2, C], [3, D], [4, E], [5, F], [6, G]);
232impl_pass_for_tuple!(
233    [0, A],
234    [1, B],
235    [2, C],
236    [3, D],
237    [4, E],
238    [5, F],
239    [6, G],
240    [7, H]
241);
242impl_pass_for_tuple!(
243    [0, A],
244    [1, B],
245    [2, C],
246    [3, D],
247    [4, E],
248    [5, F],
249    [6, G],
250    [7, H],
251    [8, I]
252);
253impl_pass_for_tuple!(
254    [0, A],
255    [1, B],
256    [2, C],
257    [3, D],
258    [4, E],
259    [5, F],
260    [6, G],
261    [7, H],
262    [8, I],
263    [9, J]
264);
265impl_pass_for_tuple!(
266    [0, A],
267    [1, B],
268    [2, C],
269    [3, D],
270    [4, E],
271    [5, F],
272    [6, G],
273    [7, H],
274    [8, I],
275    [9, J],
276    [10, K]
277);
278impl_pass_for_tuple!(
279    [0, A],
280    [1, B],
281    [2, C],
282    [3, D],
283    [4, E],
284    [5, F],
285    [6, G],
286    [7, H],
287    [8, I],
288    [9, J],
289    [10, K],
290    [11, L]
291);
292impl_pass_for_tuple!(
293    [0, A],
294    [1, B],
295    [2, C],
296    [3, D],
297    [4, E],
298    [5, F],
299    [6, G],
300    [7, H],
301    [8, I],
302    [9, J],
303    [10, K],
304    [11, L],
305    [12, M]
306);
307
308#[inline(always)]
309pub fn noop_pass() -> impl Pass {
310    fn noop(_: &mut Program) {}
311
312    fn_pass(noop)
313}
314
315#[inline(always)]
316pub fn fn_pass(f: impl FnMut(&mut Program)) -> impl Pass {
317    FnPass { f }
318}
319
320struct FnPass<F> {
321    f: F,
322}
323
324impl<F> Pass for FnPass<F>
325where
326    F: FnMut(&mut Program),
327{
328    fn process(&mut self, program: &mut Program) {
329        (self.f)(program);
330    }
331}
332
333/// Represents a invalid node.
334#[ast_node("Invalid")]
335#[derive(Eq, Default, Hash, Copy, EqIgnoreSpan)]
336#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
337#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
338pub struct Invalid {
339    pub span: Span,
340}
341
342impl Take for Invalid {
343    fn dummy() -> Self {
344        Invalid::default()
345    }
346}
347
348/// Note: This type implements `Serailize` and `Deserialize` if `serde` is
349/// enabled, instead of requiring `serde-impl` feature.
350#[derive(Debug, Default, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
351#[cfg_attr(feature = "serde", derive(Serialize))]
352#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
353pub enum EsVersion {
354    Es3,
355    #[default]
356    Es5,
357    Es2015,
358    Es2016,
359    Es2017,
360    Es2018,
361    Es2019,
362    Es2020,
363    Es2021,
364    Es2022,
365    Es2023,
366    Es2024,
367    EsNext,
368}
369
370#[cfg(feature = "serde")]
371impl<'de> Deserialize<'de> for EsVersion {
372    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
373    where
374        D: serde::Deserializer<'de>,
375    {
376        use serde::de::Error;
377
378        let s = String::deserialize(deserializer)?;
379        match s.to_lowercase().as_str() {
380            "es3" => Ok(EsVersion::Es3),
381            "es5" => Ok(EsVersion::Es5),
382            "es2015" | "es6" => Ok(EsVersion::Es2015),
383            "es2016" => Ok(EsVersion::Es2016),
384            "es2017" => Ok(EsVersion::Es2017),
385            "es2018" => Ok(EsVersion::Es2018),
386            "es2019" => Ok(EsVersion::Es2019),
387            "es2020" => Ok(EsVersion::Es2020),
388            "es2021" => Ok(EsVersion::Es2021),
389            "es2022" => Ok(EsVersion::Es2022),
390            "es2023" => Ok(EsVersion::Es2023),
391            "es2024" => Ok(EsVersion::Es2024),
392            "esnext" => Ok(EsVersion::EsNext),
393            _ => Err(D::Error::custom(format!("Unknown ES version: {s}"))),
394        }
395    }
396}
397
398impl EsVersion {
399    pub const fn latest() -> Self {
400        EsVersion::EsNext
401    }
402}
403
404/// Warning: The particular implementation of serialization and deserialization
405/// of the ast nodes may change in the future, and so these types would be
406/// removed. It's safe to say they will be serializable in some form or another,
407/// but not necessarily with these specific types underlying the implementation.
408/// As such, *use these types at your own risk*.
409#[cfg(feature = "rkyv-impl")]
410#[doc(hidden)]
411pub use self::{
412    class::{
413        ArchivedAutoAccessor, ArchivedClass, ArchivedClassMember, ArchivedClassMethod,
414        ArchivedClassProp, ArchivedConstructor, ArchivedDecorator, ArchivedKey, ArchivedMethodKind,
415        ArchivedPrivateMethod, ArchivedPrivateProp, ArchivedStaticBlock,
416    },
417    decl::{
418        ArchivedClassDecl, ArchivedDecl, ArchivedFnDecl, ArchivedUsingDecl, ArchivedVarDecl,
419        ArchivedVarDeclKind, ArchivedVarDeclarator,
420    },
421    expr::{
422        ArchivedArrayLit, ArchivedArrowExpr, ArchivedAssignExpr, ArchivedAssignTarget,
423        ArchivedAwaitExpr, ArchivedBinExpr, ArchivedBlockStmtOrExpr, ArchivedCallExpr,
424        ArchivedCallee, ArchivedClassExpr, ArchivedCondExpr, ArchivedExpr, ArchivedExprOrSpread,
425        ArchivedFnExpr, ArchivedImport, ArchivedMemberExpr, ArchivedMemberProp,
426        ArchivedMetaPropExpr, ArchivedMetaPropKind, ArchivedNewExpr, ArchivedObjectLit,
427        ArchivedOptCall, ArchivedOptChainBase, ArchivedOptChainExpr, ArchivedParenExpr,
428        ArchivedPropOrSpread, ArchivedSeqExpr, ArchivedSpreadElement, ArchivedSuper,
429        ArchivedSuperProp, ArchivedSuperPropExpr, ArchivedTaggedTpl, ArchivedThisExpr, ArchivedTpl,
430        ArchivedTplElement, ArchivedUnaryExpr, ArchivedUpdateExpr, ArchivedYieldExpr,
431    },
432    function::{ArchivedFunction, ArchivedParam, ArchivedParamOrTsParamProp},
433    ident::{ArchivedBindingIdent, ArchivedIdent, ArchivedIdentName, ArchivedPrivateName},
434    jsx::{
435        ArchivedJSXAttr, ArchivedJSXAttrName, ArchivedJSXAttrOrSpread, ArchivedJSXAttrValue,
436        ArchivedJSXClosingElement, ArchivedJSXClosingFragment, ArchivedJSXElement,
437        ArchivedJSXElementChild, ArchivedJSXElementName, ArchivedJSXEmptyExpr, ArchivedJSXExpr,
438        ArchivedJSXExprContainer, ArchivedJSXFragment, ArchivedJSXMemberExpr,
439        ArchivedJSXNamespacedName, ArchivedJSXObject, ArchivedJSXOpeningElement,
440        ArchivedJSXOpeningFragment, ArchivedJSXSpreadChild, ArchivedJSXText,
441    },
442    lit::{
443        ArchivedBigInt, ArchivedBool, ArchivedLit, ArchivedNull, ArchivedNumber, ArchivedRegex,
444        ArchivedStr,
445    },
446    module::{ArchivedModule, ArchivedModuleItem, ArchivedProgram, ArchivedScript},
447    module_decl::{
448        ArchivedDefaultDecl, ArchivedExportAll, ArchivedExportDecl, ArchivedExportDefaultDecl,
449        ArchivedExportDefaultExpr, ArchivedExportDefaultSpecifier, ArchivedExportNamedSpecifier,
450        ArchivedExportNamespaceSpecifier, ArchivedExportSpecifier, ArchivedImportDecl,
451        ArchivedImportDefaultSpecifier, ArchivedImportNamedSpecifier, ArchivedImportSpecifier,
452        ArchivedImportStarAsSpecifier, ArchivedModuleDecl, ArchivedModuleExportName,
453        ArchivedNamedExport,
454    },
455    operators::{ArchivedAssignOp, ArchivedBinaryOp, ArchivedUnaryOp, ArchivedUpdateOp},
456    pat::{
457        ArchivedArrayPat, ArchivedAssignPat, ArchivedAssignPatProp, ArchivedKeyValuePatProp,
458        ArchivedObjectPat, ArchivedObjectPatProp, ArchivedPat, ArchivedRestPat,
459    },
460    prop::{
461        ArchivedAssignProp, ArchivedComputedPropName, ArchivedGetterProp, ArchivedKeyValueProp,
462        ArchivedMethodProp, ArchivedProp, ArchivedPropName, ArchivedSetterProp,
463    },
464    stmt::{
465        ArchivedBlockStmt, ArchivedBreakStmt, ArchivedCatchClause, ArchivedContinueStmt,
466        ArchivedDebuggerStmt, ArchivedDoWhileStmt, ArchivedEmptyStmt, ArchivedExprStmt,
467        ArchivedForHead, ArchivedForInStmt, ArchivedForOfStmt, ArchivedForStmt, ArchivedIfStmt,
468        ArchivedLabeledStmt, ArchivedReturnStmt, ArchivedStmt, ArchivedSwitchCase,
469        ArchivedSwitchStmt, ArchivedThrowStmt, ArchivedTryStmt, ArchivedVarDeclOrExpr,
470        ArchivedWhileStmt, ArchivedWithStmt,
471    },
472    typescript::{
473        ArchivedAccessibility, ArchivedTruePlusMinus, ArchivedTsArrayType, ArchivedTsAsExpr,
474        ArchivedTsCallSignatureDecl, ArchivedTsConditionalType, ArchivedTsConstAssertion,
475        ArchivedTsConstructSignatureDecl, ArchivedTsConstructorType, ArchivedTsEntityName,
476        ArchivedTsEnumDecl, ArchivedTsEnumMember, ArchivedTsEnumMemberId,
477        ArchivedTsExportAssignment, ArchivedTsExprWithTypeArgs, ArchivedTsExternalModuleRef,
478        ArchivedTsFnOrConstructorType, ArchivedTsFnParam, ArchivedTsFnType,
479        ArchivedTsGetterSignature, ArchivedTsImportEqualsDecl, ArchivedTsImportType,
480        ArchivedTsIndexSignature, ArchivedTsIndexedAccessType, ArchivedTsInferType,
481        ArchivedTsInstantiation, ArchivedTsInterfaceBody, ArchivedTsInterfaceDecl,
482        ArchivedTsIntersectionType, ArchivedTsKeywordType, ArchivedTsKeywordTypeKind,
483        ArchivedTsLit, ArchivedTsLitType, ArchivedTsMappedType, ArchivedTsMethodSignature,
484        ArchivedTsModuleBlock, ArchivedTsModuleDecl, ArchivedTsModuleName, ArchivedTsModuleRef,
485        ArchivedTsNamespaceBody, ArchivedTsNamespaceDecl, ArchivedTsNamespaceExportDecl,
486        ArchivedTsNonNullExpr, ArchivedTsOptionalType, ArchivedTsParamProp,
487        ArchivedTsParamPropParam, ArchivedTsParenthesizedType, ArchivedTsPropertySignature,
488        ArchivedTsQualifiedName, ArchivedTsRestType, ArchivedTsSatisfiesExpr,
489        ArchivedTsSetterSignature, ArchivedTsThisType, ArchivedTsThisTypeOrIdent,
490        ArchivedTsTplLitType, ArchivedTsTupleElement, ArchivedTsTupleType, ArchivedTsType,
491        ArchivedTsTypeAliasDecl, ArchivedTsTypeAnn, ArchivedTsTypeAssertion, ArchivedTsTypeElement,
492        ArchivedTsTypeLit, ArchivedTsTypeOperator, ArchivedTsTypeOperatorOp, ArchivedTsTypeParam,
493        ArchivedTsTypeParamDecl, ArchivedTsTypeParamInstantiation, ArchivedTsTypePredicate,
494        ArchivedTsTypeQuery, ArchivedTsTypeQueryExpr, ArchivedTsTypeRef,
495        ArchivedTsUnionOrIntersectionType, ArchivedTsUnionType,
496    },
497};