|
use oxc::{
|
|
ast::ast::AssignmentOperator,
|
|
span::{Atom, Span},
|
|
};
|
|
use smallvec::{SmallVec, smallvec};
|
|
|
|
use crate::changes::{JsChange, change};
|
|
|
|
macro_rules! rewrite {
|
|
($span:expr, $($ty:tt)*) => {
|
|
$crate::rewrite::Rewrite::new($span, $crate::rewrite::RewriteType::$($ty)*)
|
|
};
|
|
}
|
|
pub(crate) use rewrite;
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub(crate) enum RewriteType<'alloc: 'data, 'data> {
|
|
|
|
WrapFn {
|
|
wrap: bool,
|
|
},
|
|
|
|
SetRealmFn,
|
|
|
|
WrapThisFn,
|
|
|
|
ImportFn,
|
|
|
|
MetaFn,
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
ScramErr {
|
|
ident: Atom<'data>,
|
|
},
|
|
|
|
Scramitize,
|
|
|
|
|
|
Eval {
|
|
inner: Span,
|
|
},
|
|
|
|
Assignment {
|
|
name: Atom<'data>,
|
|
rhs: Span,
|
|
op: AssignmentOperator,
|
|
},
|
|
|
|
ShorthandObj {
|
|
name: Atom<'data>,
|
|
},
|
|
SourceTag,
|
|
|
|
|
|
Replace {
|
|
text: &'alloc str,
|
|
},
|
|
Delete,
|
|
}
|
|
|
|
pub(crate) struct Rewrite<'alloc, 'data> {
|
|
span: Span,
|
|
ty: RewriteType<'alloc, 'data>,
|
|
}
|
|
|
|
impl<'alloc: 'data, 'data> Rewrite<'alloc, 'data> {
|
|
pub fn new(span: Span, ty: RewriteType<'alloc, 'data>) -> Self {
|
|
Self { span, ty }
|
|
}
|
|
|
|
pub fn into_inner(self) -> SmallVec<[JsChange<'alloc, 'data>; 2]> {
|
|
self.ty.into_inner(self.span)
|
|
}
|
|
}
|
|
|
|
impl<'alloc: 'data, 'data> RewriteType<'alloc, 'data> {
|
|
fn into_inner(self, span: Span) -> SmallVec<[JsChange<'alloc, 'data>; 2]> {
|
|
macro_rules! span {
|
|
(start) => {
|
|
Span::new(span.start, span.start)
|
|
};
|
|
(end) => {
|
|
Span::new(span.end, span.end)
|
|
};
|
|
($span1:ident $span2:ident start) => {
|
|
Span::new($span1.start, $span2.start)
|
|
};
|
|
($span1:ident $span2:ident end) => {
|
|
Span::new($span1.end, $span2.end)
|
|
};
|
|
}
|
|
|
|
match self {
|
|
Self::WrapFn { wrap } => smallvec![
|
|
change!(span!(start), WrapFnLeft { wrap }),
|
|
change!(span!(end), WrapFnRight { wrap }),
|
|
],
|
|
Self::SetRealmFn => smallvec![change!(span, SetRealmFn)],
|
|
Self::WrapThisFn => smallvec![
|
|
change!(span!(start), WrapThisFn),
|
|
change!(
|
|
span!(end),
|
|
ClosingParen {
|
|
semi: false,
|
|
replace: false
|
|
}
|
|
),
|
|
],
|
|
Self::ImportFn => smallvec![change!(span, ImportFn)],
|
|
Self::MetaFn => smallvec![change!(span, MetaFn)],
|
|
Self::ScramErr { ident } => smallvec![change!(span!(end), ScramErrFn { ident })],
|
|
Self::Scramitize => smallvec![
|
|
change!(span!(start), ScramitizeFn),
|
|
change!(
|
|
span!(end),
|
|
ClosingParen {
|
|
semi: false,
|
|
replace: false
|
|
}
|
|
)
|
|
],
|
|
Self::Eval { inner } => smallvec![
|
|
change!(span!(span inner start), EvalRewriteFn),
|
|
change!(
|
|
span!(inner span end),
|
|
ClosingParen {
|
|
semi: false,
|
|
replace: true
|
|
}
|
|
)
|
|
],
|
|
Self::Assignment { name, rhs, op } => smallvec![
|
|
change!(span!(span rhs start), AssignmentLeft { name, op }),
|
|
change!(
|
|
span!(rhs span end),
|
|
ClosingParen {
|
|
semi: false,
|
|
replace: true
|
|
}
|
|
)
|
|
],
|
|
Self::ShorthandObj { name } => {
|
|
smallvec![change!(span!(end), ShorthandObj { ident: name })]
|
|
}
|
|
Self::SourceTag => smallvec![change!(span, SourceTag)],
|
|
Self::Replace { text } => smallvec![change!(span, Replace { text })],
|
|
Self::Delete => smallvec![change!(span, Delete)],
|
|
}
|
|
}
|
|
}
|
|
|