swc_ecma_parser/parser/
util.rs
use super::*;
impl<I: Tokens> Parser<I> {
pub(super) fn with_ctx(&mut self, ctx: Context) -> WithCtx<I> {
let orig_ctx = self.ctx();
self.set_ctx(ctx);
WithCtx {
orig_ctx,
inner: self,
}
}
pub(super) fn with_state(&mut self, state: State) -> WithState<I> {
let orig_state = std::mem::replace(&mut self.state, state);
WithState {
orig_state,
inner: self,
}
}
pub(super) fn set_ctx(&mut self, ctx: Context) {
self.input.set_ctx(ctx);
}
pub(super) fn strict_mode(&mut self) -> WithCtx<I> {
let ctx = self.ctx() | Context::Strict;
self.with_ctx(ctx)
}
pub(super) fn in_type(&mut self) -> WithCtx<I> {
let ctx = self.ctx() | Context::InType;
self.with_ctx(ctx)
}
pub(super) fn include_in_expr(&mut self, include_in_expr: bool) -> WithCtx<I> {
let mut ctx = self.ctx();
ctx.set(Context::IncludeInExpr, include_in_expr);
self.with_ctx(ctx)
}
#[inline(always)]
pub(super) fn parse_with<F, Ret>(&mut self, f: F) -> PResult<Ret>
where
F: FnOnce(&mut Self) -> PResult<Ret>,
{
f(self)
}
pub(super) fn syntax(&self) -> Syntax {
self.input.syntax()
}
}
pub trait ParseObject<Obj> {
type Prop;
fn make_object(
&mut self,
span: Span,
props: Vec<Self::Prop>,
trailing_comma: Option<Span>,
) -> PResult<Obj>;
fn parse_object_prop(&mut self) -> PResult<Self::Prop>;
}
pub struct WithState<'w, I: 'w + Tokens> {
inner: &'w mut Parser<I>,
orig_state: State,
}
impl<I: Tokens> Deref for WithState<'_, I> {
type Target = Parser<I>;
fn deref(&self) -> &Parser<I> {
self.inner
}
}
impl<I: Tokens> DerefMut for WithState<'_, I> {
fn deref_mut(&mut self) -> &mut Parser<I> {
self.inner
}
}
impl<I: Tokens> Drop for WithState<'_, I> {
fn drop(&mut self) {
std::mem::swap(&mut self.inner.state, &mut self.orig_state);
}
}
pub struct WithCtx<'w, I: 'w + Tokens> {
inner: &'w mut Parser<I>,
orig_ctx: Context,
}
impl<I: Tokens> Deref for WithCtx<'_, I> {
type Target = Parser<I>;
fn deref(&self) -> &Parser<I> {
self.inner
}
}
impl<I: Tokens> DerefMut for WithCtx<'_, I> {
fn deref_mut(&mut self) -> &mut Parser<I> {
self.inner
}
}
impl<I: Tokens> Drop for WithCtx<'_, I> {
fn drop(&mut self) {
self.inner.set_ctx(self.orig_ctx);
}
}
pub(super) trait ExprExt {
fn as_expr(&self) -> &Expr;
fn is_valid_simple_assignment_target(&self, strict: bool) -> bool {
match self.as_expr() {
Expr::Ident(ident) => {
if strict && ident.is_reserved_in_strict_bind() {
return false;
}
true
}
Expr::This(..)
| Expr::Lit(..)
| Expr::Array(..)
| Expr::Object(..)
| Expr::Fn(..)
| Expr::Class(..)
| Expr::Tpl(..)
| Expr::TaggedTpl(..) => false,
Expr::Paren(ParenExpr { expr, .. }) => expr.is_valid_simple_assignment_target(strict),
Expr::Member(MemberExpr { obj, .. }) => match obj.as_ref() {
Expr::Member(..) => obj.is_valid_simple_assignment_target(strict),
Expr::OptChain(..) => false,
_ => true,
},
Expr::SuperProp(..) => true,
Expr::New(..) | Expr::Call(..) => false,
Expr::MetaProp(..) => false,
Expr::Update(..) => false,
Expr::Unary(..) | Expr::Await(..) => false,
Expr::Bin(..) => false,
Expr::Cond(..) => false,
Expr::Yield(..) | Expr::Arrow(..) | Expr::Assign(..) => false,
Expr::Seq(..) => false,
Expr::OptChain(..) => false,
Expr::PrivateName(..) => false,
Expr::JSXMember(..)
| Expr::JSXNamespacedName(..)
| Expr::JSXEmpty(..)
| Expr::JSXElement(..)
| Expr::JSXFragment(..) => false,
Expr::TsNonNull(TsNonNullExpr { ref expr, .. })
| Expr::TsTypeAssertion(TsTypeAssertion { ref expr, .. })
| Expr::TsAs(TsAsExpr { ref expr, .. })
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { ref expr, .. }) => {
expr.is_valid_simple_assignment_target(strict)
}
Expr::TsConstAssertion(..) => false,
Expr::Invalid(..) => false,
}
}
}
impl ExprExt for Box<Expr> {
fn as_expr(&self) -> &Expr {
self
}
}
impl ExprExt for Expr {
fn as_expr(&self) -> &Expr {
self
}
}