scramjet / rewriter /js /src /rewrite.rs
soiz1's picture
Upload 150 files
bee6636 verified
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> {
/// `(cfg.wrapfn(ident,strictchecker))` | `cfg.wrapfn(ident,strictchecker)`
WrapFn {
wrap: bool,
},
/// `cfg.setrealmfn({}).ident`
SetRealmFn,
/// `cfg.wrapthis(this)`
WrapThisFn,
/// `(cfg.importfn("cfg.base"))`
ImportFn,
/// `cfg.metafn("cfg.base")`
MetaFn,
// dead code only if debug is disabled
#[allow(dead_code)]
/// `$scramerr(name)`
ScramErr {
ident: Atom<'data>,
},
/// `$scramitize(span)`
Scramitize,
/// `eval(cfg.rewritefn(inner))`
Eval {
inner: Span,
},
/// `((t)=>$scramjet$tryset(name,"op",t)||(name op t))(rhs)`
Assignment {
name: Atom<'data>,
rhs: Span,
op: AssignmentOperator,
},
/// `ident,` -> `ident: cfg.wrapfn(ident),`
ShorthandObj {
name: Atom<'data>,
},
SourceTag,
// don't use for anything static, only use for stuff like rewriteurl
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)],
}
}
}